From ab6eb0a65558ec86dae62a59eccb2b163d72715c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 31 Jan 2022 12:19:17 -0700 Subject: [PATCH] Start on completion rendering Co-Authored-By: Antonio Scandurra Co-Authored-By: Max Brunsfeld --- crates/editor/src/editor.rs | 54 +++++++++++++++++++++++++++++++---- crates/editor/src/element.rs | 5 ++++ crates/language/src/buffer.rs | 6 ++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 5a14ab4642..3bfddcc48d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -26,8 +26,8 @@ use gpui::{ use items::BufferItemHandle; use itertools::Itertools as _; use language::{ - AnchorRangeExt as _, BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, - Selection, SelectionGoal, TransactionId, + AnchorRangeExt as _, BracketPair, Buffer, Completion, Diagnostic, DiagnosticSeverity, Language, + Point, Selection, SelectionGoal, TransactionId, }; use multi_buffer::MultiBufferChunks; pub use multi_buffer::{ @@ -390,6 +390,7 @@ pub struct Editor { highlighted_rows: Option>, highlighted_ranges: BTreeMap>)>, nav_history: Option, + completion_state: Option, } pub struct EditorSnapshot { @@ -423,6 +424,11 @@ struct BracketPairState { pair: BracketPair, } +struct CompletionState { + completions: Arc<[Completion]>, + list: UniformListState, +} + #[derive(Debug)] struct ActiveDiagnosticGroup { primary_range: Range, @@ -539,6 +545,7 @@ impl Editor { highlighted_rows: None, highlighted_ranges: Default::default(), nav_history: None, + completion_state: None, }; let selection = Selection { id: post_inc(&mut this.next_selection_id), @@ -1502,9 +1509,46 @@ impl Editor { let position = self .newest_selection::(&self.buffer.read(cx).read(cx)) .head(); - self.buffer - .update(cx, |buffer, cx| buffer.completions(position, cx)) - .detach_and_log_err(cx); + + let completions = self + .buffer + .update(cx, |buffer, cx| buffer.completions(position, cx)); + + cx.spawn_weak(|this, mut cx| async move { + let completions = completions.await?; + if let Some(this) = cx.read(|cx| this.upgrade(cx)) { + this.update(&mut cx, |this, cx| { + this.completion_state = Some(CompletionState { + completions: completions.into(), + list: Default::default(), + }); + cx.notify(); + }); + } + + Ok::<_, anyhow::Error>(()) + }) + .detach_and_log_err(cx); + } + + pub fn render_completions(&self) -> Option { + self.completion_state.as_ref().map(|state| { + let build_settings = self.build_settings.clone(); + let completions = state.completions.clone(); + UniformList::new( + state.list.clone(), + state.completions.len(), + move |range, items, cx| { + let settings = build_settings(cx); + for completion in &completions[range] { + items.push( + Label::new(completion.label().to_string(), settings.style.text.clone()).boxed(), + ); + } + }, + ) + .boxed() + }) } pub fn clear(&mut self, cx: &mut ViewContext) { diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 8ef6656897..5bba59191b 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -836,6 +836,7 @@ impl Element for EditorElement { max_row.saturating_sub(1) as f32, ); + let mut completions = None; self.update_view(cx.app, |view, cx| { let clamped = view.clamp_scroll_left(scroll_max.x()); let autoscrolled; @@ -855,6 +856,8 @@ impl Element for EditorElement { if clamped || autoscrolled { snapshot = view.snapshot(cx); } + + completions = view.render_completions(); }); let blocks = self.layout_blocks( @@ -891,6 +894,7 @@ impl Element for EditorElement { em_width, em_advance, selections, + completions, }), ) } @@ -1000,6 +1004,7 @@ pub struct LayoutState { highlighted_ranges: Vec<(Range, Color)>, selections: HashMap>>, text_offset: Vector2F, + completions: Option, } fn layout_line( diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 9dc7c112be..290cb4f1b6 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -2424,6 +2424,12 @@ impl Default for Diagnostic { } } +impl Completion { + pub fn label(&self) -> &str { + &self.lsp_completion.label + } +} + pub fn contiguous_ranges( values: impl Iterator, max_len: usize,