Deduplicate inlay hints queries with buffer versions
This commit is contained in:
parent
f25a09bfd8
commit
ba3d1e4dba
3 changed files with 43 additions and 10 deletions
|
@ -255,7 +255,6 @@ impl DisplayMap {
|
||||||
if to_remove.is_empty() && to_insert.is_empty() {
|
if to_remove.is_empty() && to_insert.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
let (snapshot, edits) = self.inlay_map.sync(buffer_snapshot, edits);
|
let (snapshot, edits) = self.inlay_map.sync(buffer_snapshot, edits);
|
||||||
|
|
|
@ -54,7 +54,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||||
use hover_popover::{hide_hover, HoverState};
|
use hover_popover::{hide_hover, HoverState};
|
||||||
use inlay_hint_cache::{visible_inlay_hints, InlayHintCache, InlaySplice};
|
use inlay_hint_cache::{visible_inlay_hints, InlayHintCache, InlaySplice, InvalidationStrategy};
|
||||||
pub use items::MAX_TAB_TITLE_LEN;
|
pub use items::MAX_TAB_TITLE_LEN;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
pub use language::{char_kind, CharKind};
|
pub use language::{char_kind, CharKind};
|
||||||
|
@ -1198,6 +1198,7 @@ enum InlayRefreshReason {
|
||||||
SettingsChange(editor_settings::InlayHints),
|
SettingsChange(editor_settings::InlayHints),
|
||||||
NewLinesShown,
|
NewLinesShown,
|
||||||
ExcerptEdited,
|
ExcerptEdited,
|
||||||
|
RefreshRequested,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editor {
|
impl Editor {
|
||||||
|
@ -1311,7 +1312,7 @@ 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(InlayRefreshReason::ExcerptEdited, cx);
|
editor.refresh_inlays(InlayRefreshReason::RefreshRequested, cx);
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -2629,8 +2630,9 @@ impl Editor {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
InlayRefreshReason::NewLinesShown => false,
|
InlayRefreshReason::NewLinesShown => InvalidationStrategy::None,
|
||||||
InlayRefreshReason::ExcerptEdited => true,
|
InlayRefreshReason::ExcerptEdited => InvalidationStrategy::OnConflict,
|
||||||
|
InlayRefreshReason::RefreshRequested => InvalidationStrategy::All,
|
||||||
};
|
};
|
||||||
|
|
||||||
let excerpts_to_query = self
|
let excerpts_to_query = self
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
MultiBufferSnapshot,
|
MultiBufferSnapshot,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use clock::Global;
|
||||||
use gpui::{ModelHandle, Task, ViewContext};
|
use gpui::{ModelHandle, Task, ViewContext};
|
||||||
use language::{Buffer, BufferSnapshot};
|
use language::{Buffer, BufferSnapshot};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -31,6 +32,7 @@ struct CacheSnapshot {
|
||||||
|
|
||||||
struct CachedExcerptHints {
|
struct CachedExcerptHints {
|
||||||
version: usize,
|
version: usize,
|
||||||
|
buffer_version: Global,
|
||||||
hints: Vec<(InlayId, InlayHint)>,
|
hints: Vec<(InlayId, InlayHint)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +43,14 @@ struct ExcerptQuery {
|
||||||
excerpt_range_start: language::Anchor,
|
excerpt_range_start: language::Anchor,
|
||||||
excerpt_range_end: language::Anchor,
|
excerpt_range_end: language::Anchor,
|
||||||
cache_version: usize,
|
cache_version: usize,
|
||||||
invalidate_cache: bool,
|
invalidate: InvalidationStrategy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum InvalidationStrategy {
|
||||||
|
All,
|
||||||
|
OnConflict,
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -116,10 +125,14 @@ impl InlayHintCache {
|
||||||
pub fn spawn_hints_update(
|
pub fn spawn_hints_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut excerpts_to_query: HashMap<ExcerptId, ModelHandle<Buffer>>,
|
mut excerpts_to_query: HashMap<ExcerptId, ModelHandle<Buffer>>,
|
||||||
invalidate_cache: bool,
|
invalidate: InvalidationStrategy,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) {
|
) {
|
||||||
let update_tasks = &mut self.update_tasks;
|
let update_tasks = &mut self.update_tasks;
|
||||||
|
let invalidate_cache = matches!(
|
||||||
|
invalidate,
|
||||||
|
InvalidationStrategy::All | InvalidationStrategy::OnConflict
|
||||||
|
);
|
||||||
if invalidate_cache {
|
if invalidate_cache {
|
||||||
update_tasks
|
update_tasks
|
||||||
.retain(|task_excerpt_id, _| excerpts_to_query.contains_key(task_excerpt_id));
|
.retain(|task_excerpt_id, _| excerpts_to_query.contains_key(task_excerpt_id));
|
||||||
|
@ -179,7 +192,7 @@ impl InlayHintCache {
|
||||||
excerpt_range_start: excerpt_range.start,
|
excerpt_range_start: excerpt_range.start,
|
||||||
excerpt_range_end: excerpt_range.end,
|
excerpt_range_end: excerpt_range.end,
|
||||||
cache_version,
|
cache_version,
|
||||||
invalidate_cache,
|
invalidate,
|
||||||
};
|
};
|
||||||
let cached_excxerpt_hints = editor
|
let cached_excxerpt_hints = editor
|
||||||
.inlay_hint_cache
|
.inlay_hint_cache
|
||||||
|
@ -187,6 +200,20 @@ impl InlayHintCache {
|
||||||
.hints
|
.hints
|
||||||
.get(&excerpt_id)
|
.get(&excerpt_id)
|
||||||
.cloned();
|
.cloned();
|
||||||
|
|
||||||
|
if let Some(cached_excerpt_hints) = &cached_excxerpt_hints {
|
||||||
|
let new_task_buffer_version = buffer_snapshot.version();
|
||||||
|
let cached_buffer_version = &cached_excerpt_hints.buffer_version;
|
||||||
|
if cached_buffer_version.changed_since(new_task_buffer_version) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !new_task_buffer_version.changed_since(&cached_buffer_version)
|
||||||
|
&& !matches!(invalidate, InvalidationStrategy::All)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
editor.inlay_hint_cache.update_tasks.insert(
|
editor.inlay_hint_cache.update_tasks.insert(
|
||||||
excerpt_id,
|
excerpt_id,
|
||||||
new_update_task(
|
new_update_task(
|
||||||
|
@ -252,6 +279,7 @@ fn new_update_task(
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
Arc::new(CachedExcerptHints {
|
Arc::new(CachedExcerptHints {
|
||||||
version: new_update.cache_version,
|
version: new_update.cache_version,
|
||||||
|
buffer_version: buffer_snapshot.version().clone(),
|
||||||
hints: Vec::new(),
|
hints: Vec::new(),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -267,7 +295,8 @@ fn new_update_task(
|
||||||
cached_excerpt_hints.hints.retain(|(hint_id, _)| {
|
cached_excerpt_hints.hints.retain(|(hint_id, _)| {
|
||||||
!new_update.remove_from_cache.contains(hint_id)
|
!new_update.remove_from_cache.contains(hint_id)
|
||||||
});
|
});
|
||||||
|
cached_excerpt_hints.buffer_version =
|
||||||
|
buffer_snapshot.version().clone();
|
||||||
editor.inlay_hint_cache.snapshot.version += 1;
|
editor.inlay_hint_cache.snapshot.version += 1;
|
||||||
|
|
||||||
let mut splice = InlaySplice {
|
let mut splice = InlaySplice {
|
||||||
|
@ -457,7 +486,10 @@ fn new_excerpt_hints_update_result(
|
||||||
|
|
||||||
let mut remove_from_visible = Vec::new();
|
let mut remove_from_visible = Vec::new();
|
||||||
let mut remove_from_cache = HashSet::default();
|
let mut remove_from_cache = HashSet::default();
|
||||||
if query.invalidate_cache {
|
if matches!(
|
||||||
|
query.invalidate,
|
||||||
|
InvalidationStrategy::All | InvalidationStrategy::OnConflict
|
||||||
|
) {
|
||||||
remove_from_visible.extend(
|
remove_from_visible.extend(
|
||||||
visible_hints
|
visible_hints
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue