Detailed changes
@@ -113,6 +113,7 @@ use unicode_segmentation::UnicodeSegmentation;
use ztracing::instrument;
use std::cell::RefCell;
+use std::collections::hash_map::Entry;
use std::{
any::TypeId,
borrow::Cow,
@@ -175,9 +176,9 @@ pub trait ToDisplayPoint {
fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint;
}
-type TextHighlights = TreeMap<HighlightKey, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>;
+type TextHighlights = Arc<HashMap<HighlightKey, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>>;
type SemanticTokensHighlights =
- TreeMap<BufferId, (Arc<[SemanticTokenHighlight]>, Arc<HighlightStyleInterner>)>;
+ Arc<HashMap<BufferId, (Arc<[SemanticTokenHighlight]>, Arc<HighlightStyleInterner>)>>;
type InlayHighlights = TreeMap<HighlightKey, TreeMap<InlayId, (HighlightStyle, InlayHighlight)>>;
#[derive(Debug)]
@@ -478,7 +479,7 @@ impl DisplayMap {
diagnostics_max_severity,
text_highlights: Default::default(),
inlay_highlights: Default::default(),
- semantic_token_highlights: TreeMap::default(),
+ semantic_token_highlights: Default::default(),
clip_at_line_ends: false,
masked: false,
companion: None,
@@ -1226,22 +1227,25 @@ impl DisplayMap {
cx: &App,
) {
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
- let to_insert = match self.text_highlights.remove(&key) {
- Some(mut previous) if merge => match Arc::get_mut(&mut previous) {
- Some((_, previous_ranges)) => {
+ match Arc::make_mut(&mut self.text_highlights).entry(key) {
+ Entry::Occupied(mut slot) => match Arc::get_mut(slot.get_mut()) {
+ Some((_, previous_ranges)) if merge => {
previous_ranges.extend(ranges);
previous_ranges.sort_by(|a, b| a.start.cmp(&b.start, &multi_buffer_snapshot));
- previous
}
- None => Arc::new((style, {
- ranges.extend(previous.1.iter().cloned());
+ Some((previous_style, previous_ranges)) => {
+ *previous_style = style;
+ *previous_ranges = ranges;
+ }
+ None if merge => {
+ ranges.extend(slot.get().1.iter().cloned());
ranges.sort_by(|a, b| a.start.cmp(&b.start, &multi_buffer_snapshot));
- ranges
- })),
+ slot.insert(Arc::new((style, ranges)));
+ }
+ None => _ = slot.insert(Arc::new((style, ranges))),
},
- _ => Arc::new((style, ranges)),
- };
- self.text_highlights.insert(key, to_insert);
+ Entry::Vacant(slot) => _ = slot.insert(Arc::new((style, ranges))),
+ }
}
#[instrument(skip_all)]
@@ -1288,14 +1292,16 @@ impl DisplayMap {
}
pub fn clear_highlights(&mut self, key: HighlightKey) -> bool {
- let mut cleared = self.text_highlights.remove(&key).is_some();
+ let mut cleared = Arc::make_mut(&mut self.text_highlights)
+ .remove(&key)
+ .is_some();
cleared |= self.inlay_highlights.remove(&key).is_some();
cleared
}
pub fn clear_highlights_with(&mut self, f: &mut dyn FnMut(&HighlightKey) -> bool) -> bool {
let mut cleared = false;
- self.text_highlights.retain(|k, _| {
+ Arc::make_mut(&mut self.text_highlights).retain(|k, _| {
let b = !f(k);
cleared |= b;
b
@@ -1448,7 +1454,7 @@ impl DisplayMap {
}
pub fn invalidate_semantic_highlights(&mut self, buffer_id: BufferId) {
- self.semantic_token_highlights.remove(&buffer_id);
+ Arc::make_mut(&mut self.semantic_token_highlights).remove(&buffer_id);
}
}
@@ -1328,9 +1328,10 @@ mod tests {
use super::*;
use crate::{
MultiBuffer,
- display_map::{HighlightKey, InlayHighlights, TextHighlights},
+ display_map::{HighlightKey, InlayHighlights},
hover_links::InlayHighlight,
};
+ use collections::HashMap;
use gpui::{App, HighlightStyle};
use multi_buffer::Anchor;
use project::{InlayHint, InlayHintLabel, ResolveState};
@@ -1897,7 +1898,7 @@ mod tests {
);
}
- let mut text_highlights = TextHighlights::default();
+ let mut text_highlights = HashMap::default();
let text_highlight_count = rng.random_range(0_usize..10);
let mut text_highlight_ranges = (0..text_highlight_count)
.map(|_| buffer_snapshot.random_byte_range(MultiBufferOffset(0), &mut rng))
@@ -1917,6 +1918,7 @@ mod tests {
.collect(),
)),
);
+ let text_highlights = Arc::new(text_highlights);
let mut inlay_highlights = InlayHighlights::default();
if !inlays.is_empty() {
@@ -122,7 +122,10 @@ impl Editor {
if !self.mode().is_full() || !self.semantic_token_state.enabled() {
self.invalidate_semantic_tokens(None);
self.display_map.update(cx, |display_map, _| {
- display_map.semantic_token_highlights.clear();
+ match Arc::get_mut(&mut display_map.semantic_token_highlights) {
+ Some(highlights) => highlights.clear(),
+ None => display_map.semantic_token_highlights = Arc::new(Default::default()),
+ };
});
self.semantic_token_state.update_task = Task::ready(());
cx.notify();
@@ -171,8 +174,8 @@ impl Editor {
.display_map
.read(cx)
.semantic_token_highlights
- .iter()
- .map(|(buffer_id, _)| *buffer_id)
+ .keys()
+ .copied()
.filter(|buffer_id| !buffers_to_query.contains_key(buffer_id))
.filter(|buffer_id| {
!self
@@ -308,7 +311,7 @@ impl Editor {
token_highlights.sort_by(|a, b| {
a.range.start.cmp(&b.range.start, &multi_buffer_snapshot)
});
- display_map.semantic_token_highlights.insert(
+ Arc::make_mut(&mut display_map.semantic_token_highlights).insert(
buffer_id,
(Arc::from(token_highlights), Arc::new(interner)),
);
@@ -624,7 +624,7 @@ pub struct MultiBufferSnapshot {
diffs: TreeMap<BufferId, DiffStateSnapshot>,
diff_transforms: SumTree<DiffTransform>,
excerpt_ids: SumTree<ExcerptIdMapping>,
- replaced_excerpts: TreeMap<ExcerptId, ExcerptId>,
+ replaced_excerpts: Arc<HashMap<ExcerptId, ExcerptId>>,
non_text_state_update_count: usize,
edit_count: usize,
is_dirty: bool,
@@ -1967,7 +1967,10 @@ impl MultiBuffer {
*has_deleted_file = false;
*has_conflict = false;
*has_inverted_diff = false;
- replaced_excerpts.clear();
+ match Arc::get_mut(replaced_excerpts) {
+ Some(replaced_excerpts) => replaced_excerpts.clear(),
+ None => *replaced_excerpts = Default::default(),
+ }
let edits = Self::sync_diff_transforms(
self.snapshot.get_mut(),
@@ -382,9 +382,7 @@ impl MultiBuffer {
{
last.context.end = last.context.end.max(existing_range.end);
to_remove.push(*existing_id);
- self.snapshot
- .get_mut()
- .replaced_excerpts
+ Arc::make_mut(&mut self.snapshot.get_mut().replaced_excerpts)
.insert(*existing_id, *last_id);
existing_iter.next();
continue;
@@ -462,9 +460,7 @@ impl MultiBuffer {
(Some(_), Some((_, existing_range))) => {
let existing_id = existing_iter.next().unwrap();
let new_id = next_excerpt_id();
- self.snapshot
- .get_mut()
- .replaced_excerpts
+ Arc::make_mut(&mut self.snapshot.get_mut().replaced_excerpts)
.insert(existing_id, new_id);
to_remove.push(existing_id);
let mut range = new_iter.next().unwrap();