Start on completion rendering

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo 2022-01-31 12:19:17 -07:00
parent 960696a504
commit ab6eb0a655
3 changed files with 60 additions and 5 deletions

View file

@ -26,8 +26,8 @@ use gpui::{
use items::BufferItemHandle; use items::BufferItemHandle;
use itertools::Itertools as _; use itertools::Itertools as _;
use language::{ use language::{
AnchorRangeExt as _, BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, AnchorRangeExt as _, BracketPair, Buffer, Completion, Diagnostic, DiagnosticSeverity, Language,
Selection, SelectionGoal, TransactionId, Point, Selection, SelectionGoal, TransactionId,
}; };
use multi_buffer::MultiBufferChunks; use multi_buffer::MultiBufferChunks;
pub use multi_buffer::{ pub use multi_buffer::{
@ -390,6 +390,7 @@ pub struct Editor {
highlighted_rows: Option<Range<u32>>, highlighted_rows: Option<Range<u32>>,
highlighted_ranges: BTreeMap<TypeId, (Color, Vec<Range<Anchor>>)>, highlighted_ranges: BTreeMap<TypeId, (Color, Vec<Range<Anchor>>)>,
nav_history: Option<ItemNavHistory>, nav_history: Option<ItemNavHistory>,
completion_state: Option<CompletionState>,
} }
pub struct EditorSnapshot { pub struct EditorSnapshot {
@ -423,6 +424,11 @@ struct BracketPairState {
pair: BracketPair, pair: BracketPair,
} }
struct CompletionState {
completions: Arc<[Completion]>,
list: UniformListState,
}
#[derive(Debug)] #[derive(Debug)]
struct ActiveDiagnosticGroup { struct ActiveDiagnosticGroup {
primary_range: Range<Anchor>, primary_range: Range<Anchor>,
@ -539,6 +545,7 @@ impl Editor {
highlighted_rows: None, highlighted_rows: None,
highlighted_ranges: Default::default(), highlighted_ranges: Default::default(),
nav_history: None, nav_history: None,
completion_state: None,
}; };
let selection = Selection { let selection = Selection {
id: post_inc(&mut this.next_selection_id), id: post_inc(&mut this.next_selection_id),
@ -1502,11 +1509,48 @@ impl Editor {
let position = self let position = self
.newest_selection::<usize>(&self.buffer.read(cx).read(cx)) .newest_selection::<usize>(&self.buffer.read(cx).read(cx))
.head(); .head();
self.buffer
.update(cx, |buffer, cx| buffer.completions(position, 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); .detach_and_log_err(cx);
} }
pub fn render_completions(&self) -> Option<ElementBox> {
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<Self>) { pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
self.start_transaction(cx); self.start_transaction(cx);
self.select_all(&SelectAll, cx); self.select_all(&SelectAll, cx);

View file

@ -836,6 +836,7 @@ impl Element for EditorElement {
max_row.saturating_sub(1) as f32, max_row.saturating_sub(1) as f32,
); );
let mut completions = None;
self.update_view(cx.app, |view, cx| { self.update_view(cx.app, |view, cx| {
let clamped = view.clamp_scroll_left(scroll_max.x()); let clamped = view.clamp_scroll_left(scroll_max.x());
let autoscrolled; let autoscrolled;
@ -855,6 +856,8 @@ impl Element for EditorElement {
if clamped || autoscrolled { if clamped || autoscrolled {
snapshot = view.snapshot(cx); snapshot = view.snapshot(cx);
} }
completions = view.render_completions();
}); });
let blocks = self.layout_blocks( let blocks = self.layout_blocks(
@ -891,6 +894,7 @@ impl Element for EditorElement {
em_width, em_width,
em_advance, em_advance,
selections, selections,
completions,
}), }),
) )
} }
@ -1000,6 +1004,7 @@ pub struct LayoutState {
highlighted_ranges: Vec<(Range<DisplayPoint>, Color)>, highlighted_ranges: Vec<(Range<DisplayPoint>, Color)>,
selections: HashMap<ReplicaId, Vec<text::Selection<DisplayPoint>>>, selections: HashMap<ReplicaId, Vec<text::Selection<DisplayPoint>>>,
text_offset: Vector2F, text_offset: Vector2F,
completions: Option<ElementBox>,
} }
fn layout_line( fn layout_line(

View file

@ -2424,6 +2424,12 @@ impl Default for Diagnostic {
} }
} }
impl Completion {
pub fn label(&self) -> &str {
&self.lsp_completion.label
}
}
pub fn contiguous_ranges( pub fn contiguous_ranges(
values: impl Iterator<Item = u32>, values: impl Iterator<Item = u32>,
max_len: usize, max_len: usize,