@@ -24,20 +24,11 @@ impl Editor {
let accents_count = cx.theme().accents().0.len();
let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx);
- let all_excerpts = self.buffer().read(cx).excerpt_ids();
let anchors_in_multi_buffer = |current_excerpt: ExcerptId,
text_anchors: [text::Anchor; 4]|
-> Option<[Option<_>; 4]> {
multi_buffer_snapshot
- .anchors_in_excerpt(current_excerpt, text_anchors)
- .or_else(|| {
- all_excerpts
- .iter()
- .filter(|&&excerpt_id| excerpt_id != current_excerpt)
- .find_map(|&excerpt_id| {
- multi_buffer_snapshot.anchors_in_excerpt(excerpt_id, text_anchors)
- })
- })?
+ .anchors_in_excerpt(current_excerpt, text_anchors)?
.collect_array()
};
@@ -17403,12 +17403,12 @@ impl Editor {
};
let snapshot = self.buffer.read(cx).snapshot(cx);
- let mut excerpt_ids = selections
+ let excerpt_ids = selections
.iter()
.flat_map(|selection| snapshot.excerpt_ids_for_range(selection.range()))
+ .unique()
+ .sorted()
.collect::<Vec<_>>();
- excerpt_ids.sort();
- excerpt_ids.dedup();
if self.delegate_expand_excerpts {
cx.emit(EditorEvent::ExpandExcerptsRequested {
@@ -8,6 +8,7 @@ use clock::Global;
use collections::{HashMap, HashSet};
use futures::future::join_all;
use gpui::{App, Entity, Task};
+use itertools::Itertools;
use language::{
BufferRow,
language_settings::{InlayHintKind, InlayHintSettings, language_settings},
@@ -772,8 +773,17 @@ impl Editor {
return;
};
- let mut hints_to_remove = Vec::new();
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
+ let Some(buffer_snapshot) = self
+ .buffer
+ .read(cx)
+ .buffer(buffer_id)
+ .map(|buffer| buffer.read(cx).snapshot())
+ else {
+ return;
+ };
+
+ let mut hints_to_remove = Vec::new();
// If we've received hints from the cache, it means `invalidate_cache` had invalidated whatever possible there,
// and most probably there are no more hints with IDs from `visible_inlay_hint_ids` in the cache.
@@ -786,9 +796,8 @@ impl Editor {
hints_to_remove.extend(visible_inlay_hint_ids);
}
- let excerpts = self.buffer.read(cx).excerpt_ids();
let mut inserted_hint_text = HashMap::default();
- let hints_to_insert = new_hints
+ let new_hints = new_hints
.into_iter()
.filter_map(|(chunk_range, hints_result)| {
let chunks_fetched = inlay_hints.hint_chunk_fetching.get_mut(&buffer_id);
@@ -843,22 +852,24 @@ impl Editor {
hints_deduplicated
})
- .filter_map(|(hint_id, lsp_hint)| {
- if inlay_hints.allowed_hint_kinds.contains(&lsp_hint.kind)
+ .filter(|(hint_id, lsp_hint)| {
+ inlay_hints.allowed_hint_kinds.contains(&lsp_hint.kind)
&& inlay_hints
.added_hints
- .insert(hint_id, lsp_hint.kind)
+ .insert(*hint_id, lsp_hint.kind)
.is_none()
- {
- let position = excerpts.iter().find_map(|excerpt_id| {
- multi_buffer_snapshot.anchor_in_excerpt(*excerpt_id, lsp_hint.position)
- })?;
- return Some(Inlay::hint(hint_id, position, &lsp_hint));
- }
- None
})
+ .sorted_by(|(_, a), (_, b)| a.position.cmp(&b.position, &buffer_snapshot))
.collect::<Vec<_>>();
+ let hints_to_insert = multi_buffer_snapshot
+ .text_anchors_to_visible_anchors(
+ new_hints.iter().map(|(_, lsp_hint)| lsp_hint.position),
+ )
+ .into_iter()
+ .zip(&new_hints)
+ .filter_map(|(position, (hint_id, hint))| Some(Inlay::hint(*hint_id, position?, &hint)))
+ .collect();
let invalidate_hints_for_buffers =
std::mem::take(&mut inlay_hints.invalidate_hints_for_buffers);
if !invalidate_hints_for_buffers.is_empty() {
@@ -2254,7 +2254,7 @@ mod tests {
assert_eq!(lhs_content, expected_lhs, "lhs");
}
- #[gpui::test(iterations = 100)]
+ #[gpui::test(iterations = 25)]
async fn test_random_split_editor(mut rng: StdRng, cx: &mut gpui::TestAppContext) {
use rand::prelude::*;