Query inlay hints for excerpt ranges only

This commit is contained in:
Kirill Bulatov 2023-06-12 18:43:57 +03:00
parent 271cd25a1d
commit 6d1068d1e9
3 changed files with 30 additions and 51 deletions

View file

@ -29,7 +29,7 @@ pub struct InlayMap {
#[derive(Clone)] #[derive(Clone)]
pub struct InlaySnapshot { pub struct InlaySnapshot {
// TODO kb merge these two together? // TODO kb merge these two together
pub suggestion_snapshot: SuggestionSnapshot, pub suggestion_snapshot: SuggestionSnapshot,
transforms: SumTree<Transform>, transforms: SumTree<Transform>,
pub version: usize, pub version: usize,

View file

@ -2597,86 +2597,62 @@ impl Editor {
} }
let multi_buffer = self.buffer(); let multi_buffer = self.buffer();
let hint_fetch_tasks = multi_buffer let multi_buffer_snapshot = multi_buffer.read(cx).snapshot(cx);
.read(cx) let hint_fetch_tasks = multi_buffer_snapshot
.all_buffers() .excerpts()
.into_iter() .filter_map(|(excerpt_id, buffer_snapshot, excerpt_range)| {
.map(|buffer_handle| {
let buffer = buffer_handle.read(cx);
// TODO kb every time I reopen the same buffer, it's different. // TODO kb every time I reopen the same buffer, it's different.
// Find a way to understand it's the same buffer. Use paths? // Find a way to understand it's the same buffer. Use paths?
dbg!(buffer_handle.id()); let buffer_id = buffer_snapshot.remote_id();
let buffer_id = dbg!(buffer.remote_id()); let buffer_handle = multi_buffer.read(cx).buffer(buffer_id)?;
let buffer_len = buffer.len();
cx.spawn(|editor, mut cx| async move { let task = cx.spawn(|editor, mut cx| async move {
let task = editor let task = editor
.update(&mut cx, |editor, cx| { .update(&mut cx, |editor, cx| {
editor.project.as_ref().map(|project| { editor.project.as_ref().map(|project| {
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
project.inlay_hints_for_buffer(buffer_handle, 0..buffer_len, cx) project.inlay_hints_for_buffer(
buffer_handle,
excerpt_range.context,
cx,
)
}) })
}) })
}) })
.context("inlay hints fecth task spawn")?; .context("inlay hints fecth task spawn")?;
anyhow::Ok(( anyhow::Ok((
buffer_id, excerpt_id,
match task { match task {
Some(task) => { Some(task) => task.await.context("inlay hints for buffer task")?,
let mut buffer_hints =
task.await.context("inlay hints for buffer task")?;
buffer_hints.sort_unstable_by_key(|hint| hint.position.offset);
buffer_hints
}
None => Vec::new(), None => Vec::new(),
}, },
)) ))
}) });
Some(task)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
cx.spawn(|editor, mut cx| async move { cx.spawn(|editor, mut cx| async move {
let mut hints_to_draw: Vec<(Anchor, InlayHint)> = Vec::new(); let mut hints_to_draw: Vec<(Anchor, InlayHint)> = Vec::new();
let (multi_buffer, multi_buffer_snapshot) = editor.read_with(&cx, |editor, cx| { let multi_buffer_snapshot =
let multi_buffer = editor.buffer().clone(); editor.read_with(&cx, |editor, cx| editor.buffer().read(cx).snapshot(cx))?;
let multi_buffer_snapshot = multi_buffer.read(cx).snapshot(cx);
(multi_buffer, multi_buffer_snapshot)
})?;
for task_result in futures::future::join_all(hint_fetch_tasks).await { for task_result in futures::future::join_all(hint_fetch_tasks).await {
match task_result { match task_result {
Ok((buffer_id, sorted_buffer_hints)) => { Ok((excerpt_id, excerpt_hints)) => {
let Some(buffer_excerpts) = cx.read(|cx| { if !excerpt_hints.is_empty() {
let multi_buffer = multi_buffer.read(cx); hints_to_draw.extend(excerpt_hints.into_iter().map(|hint| {
multi_buffer.buffer(buffer_id).map(|buffer| multi_buffer.excerpts_for_buffer(&buffer, cx)) let anchor = multi_buffer_snapshot
}) else { continue }; .anchor_in_excerpt(excerpt_id, hint.position);
for (excerpt_id, excerpt_range) in buffer_excerpts { (anchor, hint)
let excerpt_hints = sorted_buffer_hints }));
.iter()
.cloned()
.skip_while(|hint| {
hint.position.offset < excerpt_range.context.start.offset
})
.take_while(|hint| {
hint.position.offset <= excerpt_range.context.end.offset
})
.collect::<Vec<_>>();
if !excerpt_hints.is_empty() {
hints_to_draw.extend(excerpt_hints.into_iter().map(|hint| {
let anchor = multi_buffer_snapshot
.anchor_in_excerpt(excerpt_id, hint.position);
(anchor, hint)
}));
}
} }
} }
Err(e) => error!("Failed to update hints for buffer: {e:#}"), Err(e) => error!("Failed to update hints for buffer: {e:#}"),
} }
} }
// TODO kb calculate diffs using the storage instead
if !hints_to_draw.is_empty() { if !hints_to_draw.is_empty() {
editor.update(&mut cx, |editor, cx| { editor.update(&mut cx, |editor, cx| {
editor.display_map.update(cx, |display_map, cx| { editor.display_map.update(cx, |display_map, cx| {

View file

@ -9,11 +9,14 @@ pub struct InlayHintStorage {
} }
impl InlayHintStorage { impl InlayHintStorage {
// TODO kb calculate the diff instead
fn insert(&mut self) -> bool { fn insert(&mut self) -> bool {
todo!("TODO kb") todo!("TODO kb")
} }
} }
// TODO kb need to understand different inlay hint update cases:
// * new hints from the new excerpt (no need to invalidate the cache)
// * new hints after /refresh or a text edit (whole cache should be purged)
// ??? revert/reopened files could get a speedup, if we don't truly delete the hints, but hide them in another var?
// let buffer_version = // let buffer_version =
// cx.read(|cx| buffer.read(cx).version().clone()); // cx.read(|cx| buffer.read(cx).version().clone());