Store inlays per paths and query on editor open
This commit is contained in:
parent
8acc5cf8f4
commit
ea837a183b
3 changed files with 34 additions and 27 deletions
|
@ -84,6 +84,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use snippet::Snippet;
|
use snippet::Snippet;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -1297,7 +1298,6 @@ impl Editor {
|
||||||
project_subscriptions.push(cx.subscribe(project, |editor, _, event, cx| {
|
project_subscriptions.push(cx.subscribe(project, |editor, _, event, cx| {
|
||||||
if let project::Event::RefreshInlays = event {
|
if let project::Event::RefreshInlays = event {
|
||||||
editor.refresh_inlays(cx);
|
editor.refresh_inlays(cx);
|
||||||
cx.notify()
|
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -1352,6 +1352,7 @@ impl Editor {
|
||||||
hover_state: Default::default(),
|
hover_state: Default::default(),
|
||||||
link_go_to_definition_state: Default::default(),
|
link_go_to_definition_state: Default::default(),
|
||||||
copilot_state: Default::default(),
|
copilot_state: Default::default(),
|
||||||
|
// TODO kb has to live between editors
|
||||||
inlay_cache: InlayCache::default(),
|
inlay_cache: InlayCache::default(),
|
||||||
gutter_hovered: false,
|
gutter_hovered: false,
|
||||||
_subscriptions: vec![
|
_subscriptions: vec![
|
||||||
|
@ -1377,6 +1378,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.report_editor_event("open", None, cx);
|
this.report_editor_event("open", None, cx);
|
||||||
|
this.refresh_inlays(cx);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2594,7 +2596,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InlayRequestKey {
|
struct InlayRequestKey {
|
||||||
buffer_id: u64,
|
buffer_path: PathBuf,
|
||||||
buffer_version: Global,
|
buffer_version: Global,
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
}
|
}
|
||||||
|
@ -2603,22 +2605,21 @@ impl Editor {
|
||||||
let multi_buffer_snapshot = multi_buffer.read(cx).snapshot(cx);
|
let multi_buffer_snapshot = multi_buffer.read(cx).snapshot(cx);
|
||||||
let inlay_fetch_tasks = multi_buffer_snapshot
|
let inlay_fetch_tasks = multi_buffer_snapshot
|
||||||
.excerpts()
|
.excerpts()
|
||||||
.map(|(excerpt_id, buffer_snapshot, excerpt_range)| {
|
.filter_map(|(excerpt_id, buffer_snapshot, excerpt_range)| {
|
||||||
// TODO kb every time I reopen the same buffer, it's different.
|
let buffer_path = buffer_snapshot.resolve_file_path(cx, true)?;
|
||||||
// Find a way to understand it's the same buffer. Use paths?
|
|
||||||
let buffer_id = buffer_snapshot.remote_id();
|
let buffer_id = buffer_snapshot.remote_id();
|
||||||
let buffer_version = buffer_snapshot.version().clone();
|
let buffer_version = buffer_snapshot.version().clone();
|
||||||
let buffer_handle = multi_buffer.read(cx).buffer(buffer_id);
|
let buffer_handle = multi_buffer.read(cx).buffer(buffer_id);
|
||||||
let inlays_up_to_date =
|
let inlays_up_to_date =
|
||||||
self.inlay_cache
|
self.inlay_cache
|
||||||
.inlays_up_to_date(buffer_id, &buffer_version, excerpt_id);
|
.inlays_up_to_date(&buffer_path, &buffer_version, excerpt_id);
|
||||||
let key = InlayRequestKey {
|
let key = InlayRequestKey {
|
||||||
buffer_id,
|
buffer_path,
|
||||||
buffer_version,
|
buffer_version,
|
||||||
excerpt_id,
|
excerpt_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.spawn(|editor, mut cx| async move {
|
let task = cx.spawn(|editor, mut cx| async move {
|
||||||
if inlays_up_to_date {
|
if inlays_up_to_date {
|
||||||
anyhow::Ok((key, None))
|
anyhow::Ok((key, None))
|
||||||
} else {
|
} else {
|
||||||
|
@ -2631,7 +2632,7 @@ impl 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(
|
project.query_inlay_hints_for_buffer(
|
||||||
buffer_handle,
|
buffer_handle,
|
||||||
query_start..query_end,
|
query_start..query_end,
|
||||||
cx,
|
cx,
|
||||||
|
@ -2658,13 +2659,15 @@ impl Editor {
|
||||||
None => Some(Vec::new()),
|
None => Some(Vec::new()),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
Some(task)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
cx.spawn(|editor, mut cx| async move {
|
cx.spawn(|editor, mut cx| async move {
|
||||||
let mut inlay_updates: HashMap<
|
let mut inlay_updates: HashMap<
|
||||||
u64,
|
PathBuf,
|
||||||
(
|
(
|
||||||
Global,
|
Global,
|
||||||
HashMap<ExcerptId, Option<OrderedByAnchorOffset<InlayHint>>>,
|
HashMap<ExcerptId, Option<OrderedByAnchorOffset<InlayHint>>>,
|
||||||
|
@ -2692,7 +2695,7 @@ impl Editor {
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)]);
|
)]);
|
||||||
match inlay_updates.entry(request_key.buffer_id) {
|
match inlay_updates.entry(request_key.buffer_path) {
|
||||||
hash_map::Entry::Occupied(mut o) => {
|
hash_map::Entry::Occupied(mut o) => {
|
||||||
o.get_mut().1.extend(inlays_per_excerpt);
|
o.get_mut().1.extend(inlays_per_excerpt);
|
||||||
}
|
}
|
||||||
|
@ -7243,7 +7246,7 @@ impl Editor {
|
||||||
event: &multi_buffer::Event,
|
event: &multi_buffer::Event,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let update_inlay_hints = match event {
|
let refresh_inlay_hints = match event {
|
||||||
multi_buffer::Event::Edited => {
|
multi_buffer::Event::Edited => {
|
||||||
self.refresh_active_diagnostics(cx);
|
self.refresh_active_diagnostics(cx);
|
||||||
self.refresh_code_actions(cx);
|
self.refresh_code_actions(cx);
|
||||||
|
@ -7304,7 +7307,7 @@ impl Editor {
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if update_inlay_hints {
|
if refresh_inlay_hints {
|
||||||
self.refresh_inlays(cx);
|
self.refresh_inlays(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::cmp;
|
use std::{
|
||||||
|
cmp,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{Anchor, ExcerptId};
|
use crate::{Anchor, ExcerptId};
|
||||||
use clock::{Global, Local};
|
use clock::{Global, Local};
|
||||||
|
@ -9,7 +12,7 @@ use collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct InlayCache {
|
pub struct InlayCache {
|
||||||
inlays_per_buffer: HashMap<u64, BufferInlays>,
|
inlays_per_buffer: HashMap<PathBuf, BufferInlays>,
|
||||||
next_inlay_id: usize,
|
next_inlay_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +63,11 @@ pub struct InlaysUpdate {
|
||||||
impl InlayCache {
|
impl InlayCache {
|
||||||
pub fn inlays_up_to_date(
|
pub fn inlays_up_to_date(
|
||||||
&self,
|
&self,
|
||||||
buffer_id: u64,
|
buffer_path: &Path,
|
||||||
buffer_version: &Global,
|
buffer_version: &Global,
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(buffer_inlays) = self.inlays_per_buffer.get(&buffer_id) else { return false };
|
let Some(buffer_inlays) = self.inlays_per_buffer.get(buffer_path) else { return false };
|
||||||
let buffer_up_to_date = buffer_version == &buffer_inlays.buffer_version
|
let buffer_up_to_date = buffer_version == &buffer_inlays.buffer_version
|
||||||
|| buffer_inlays.buffer_version.changed_since(buffer_version);
|
|| buffer_inlays.buffer_version.changed_since(buffer_version);
|
||||||
buffer_up_to_date && buffer_inlays.inlays_per_excerpts.contains_key(&excerpt_id)
|
buffer_up_to_date && buffer_inlays.inlays_per_excerpts.contains_key(&excerpt_id)
|
||||||
|
@ -73,7 +76,7 @@ impl InlayCache {
|
||||||
pub fn update_inlays(
|
pub fn update_inlays(
|
||||||
&mut self,
|
&mut self,
|
||||||
inlay_updates: HashMap<
|
inlay_updates: HashMap<
|
||||||
u64,
|
PathBuf,
|
||||||
(
|
(
|
||||||
Global,
|
Global,
|
||||||
HashMap<ExcerptId, Option<OrderedByAnchorOffset<InlayHint>>>,
|
HashMap<ExcerptId, Option<OrderedByAnchorOffset<InlayHint>>>,
|
||||||
|
@ -84,17 +87,17 @@ impl InlayCache {
|
||||||
let mut to_remove = Vec::new();
|
let mut to_remove = Vec::new();
|
||||||
let mut to_insert = Vec::new();
|
let mut to_insert = Vec::new();
|
||||||
|
|
||||||
for (buffer_id, (buffer_version, new_buffer_inlays)) in inlay_updates {
|
for (buffer_path, (buffer_version, new_buffer_inlays)) in inlay_updates {
|
||||||
match old_inlays.remove(&buffer_id) {
|
match old_inlays.remove(&buffer_path) {
|
||||||
Some(mut old_buffer_inlays) => {
|
Some(mut old_buffer_inlays) => {
|
||||||
for (excerpt_id, new_excerpt_inlays) in new_buffer_inlays {
|
for (excerpt_id, new_excerpt_inlays) in new_buffer_inlays {
|
||||||
if self.inlays_up_to_date(buffer_id, &buffer_version, excerpt_id) {
|
if self.inlays_up_to_date(&buffer_path, &buffer_version, excerpt_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_inlays_per_buffer = self
|
let self_inlays_per_buffer = self
|
||||||
.inlays_per_buffer
|
.inlays_per_buffer
|
||||||
.get_mut(&buffer_id)
|
.get_mut(&buffer_path)
|
||||||
.expect("element expected: `old_inlays.remove` returned `Some`");
|
.expect("element expected: `old_inlays.remove` returned `Some`");
|
||||||
let mut new_excerpt_inlays = match new_excerpt_inlays {
|
let mut new_excerpt_inlays = match new_excerpt_inlays {
|
||||||
Some(new_inlays) => {
|
Some(new_inlays) => {
|
||||||
|
@ -112,6 +115,7 @@ impl InlayCache {
|
||||||
.get_mut(&excerpt_id)
|
.get_mut(&excerpt_id)
|
||||||
.expect("element expected: `old_excerpt_inlays` is `Some`");
|
.expect("element expected: `old_excerpt_inlays` is `Some`");
|
||||||
let mut hints_to_add = Vec::<(Anchor, (InlayId, InlayHint))>::new();
|
let mut hints_to_add = Vec::<(Anchor, (InlayId, InlayHint))>::new();
|
||||||
|
// TODO kb update inner buffer_id and version with the new data?
|
||||||
self_excerpt_inlays.0.retain(
|
self_excerpt_inlays.0.retain(
|
||||||
|_, (old_anchor, (old_inlay_id, old_inlay))| {
|
|_, (old_anchor, (old_inlay_id, old_inlay))| {
|
||||||
let mut retain = false;
|
let mut retain = false;
|
||||||
|
@ -202,7 +206,7 @@ impl InlayCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.inlays_per_buffer.insert(
|
self.inlays_per_buffer.insert(
|
||||||
buffer_id,
|
buffer_path,
|
||||||
BufferInlays {
|
BufferInlays {
|
||||||
buffer_version,
|
buffer_version,
|
||||||
inlays_per_excerpts,
|
inlays_per_excerpts,
|
||||||
|
|
|
@ -4928,7 +4928,7 @@ impl Project {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inlay_hints_for_buffer<T: ToOffset>(
|
pub fn query_inlay_hints_for_buffer<T: ToOffset>(
|
||||||
&self,
|
&self,
|
||||||
buffer_handle: ModelHandle<Buffer>,
|
buffer_handle: ModelHandle<Buffer>,
|
||||||
range: Range<T>,
|
range: Range<T>,
|
||||||
|
@ -4951,7 +4951,6 @@ impl Project {
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.context("waiting for inlay hint request range edits")?;
|
.context("waiting for inlay hint request range edits")?;
|
||||||
|
|
||||||
match lsp_request_task.await {
|
match lsp_request_task.await {
|
||||||
Ok(hints) => Ok(Some(hints)),
|
Ok(hints) => Ok(Some(hints)),
|
||||||
Err(e) if is_content_modified_error(&e) => Ok(None),
|
Err(e) if is_content_modified_error(&e) => Ok(None),
|
||||||
|
@ -6767,7 +6766,8 @@ impl Project {
|
||||||
let buffer_hints = this
|
let buffer_hints = this
|
||||||
.update(&mut cx, |project, cx| {
|
.update(&mut cx, |project, cx| {
|
||||||
let buffer_end = buffer.read(cx).len();
|
let buffer_end = buffer.read(cx).len();
|
||||||
project.inlay_hints_for_buffer(
|
// TODO kb use cache before querying?
|
||||||
|
project.query_inlay_hints_for_buffer(
|
||||||
buffer,
|
buffer,
|
||||||
envelope
|
envelope
|
||||||
.payload
|
.payload
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue