Use standalone inlay background highlights

Kirill Bulatov created

Change summary

crates/editor/src/display_map.rs           | 15 ++++++++-----
crates/editor/src/display_map/inlay_map.rs |  4 --
crates/editor/src/editor.rs                | 25 +++++++++--------------
crates/editor/src/element.rs               | 11 ++++++++-
crates/editor/src/link_go_to_definition.rs |  1 
crates/search/src/buffer_search.rs         | 12 +++++-----
crates/search/src/project_search.rs        |  2 
crates/vim/src/normal/search.rs            |  2 
crates/vim/src/test.rs                     |  2 
9 files changed, 38 insertions(+), 36 deletions(-)

Detailed changes

crates/editor/src/display_map.rs 🔗

@@ -5,11 +5,11 @@ mod tab_map;
 mod wrap_map;
 
 use crate::{
-    link_go_to_definition::InlayRange, Anchor, AnchorRangeExt, InlayId, MultiBuffer,
-    MultiBufferSnapshot, ToOffset, ToPoint,
+    link_go_to_definition::InlayRange, Anchor, AnchorRangeExt, InlayBackgroundHighlight, InlayId,
+    MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
 };
 pub use block_map::{BlockMap, BlockPoint};
-use collections::{HashMap, HashSet};
+use collections::{BTreeMap, HashMap, HashSet};
 use fold_map::FoldMap;
 use gpui::{
     color::Color,
@@ -320,6 +320,7 @@ pub struct DisplaySnapshot {
 pub struct Highlights<'a> {
     pub text_highlights: Option<&'a TextHighlights>,
     pub inlay_highlights: Option<&'a InlayHighlights>,
+    pub inlay_background_highlights: Option<&'a BTreeMap<TypeId, InlayBackgroundHighlight>>,
     pub inlay_highlight_style: Option<HighlightStyle>,
     pub suggestion_highlight_style: Option<HighlightStyle>,
 }
@@ -475,10 +476,11 @@ impl DisplaySnapshot {
         })
     }
 
-    pub fn chunks(
-        &self,
+    pub fn chunks<'a>(
+        &'a self,
         display_rows: Range<u32>,
         language_aware: bool,
+        inlay_background_highlights: Option<&'a BTreeMap<TypeId, InlayBackgroundHighlight>>,
         inlay_highlight_style: Option<HighlightStyle>,
         suggestion_highlight_style: Option<HighlightStyle>,
     ) -> DisplayChunks<'_> {
@@ -488,6 +490,7 @@ impl DisplaySnapshot {
             Highlights {
                 text_highlights: Some(&self.text_highlights),
                 inlay_highlights: Some(&self.inlay_highlights),
+                inlay_background_highlights,
                 inlay_highlight_style,
                 suggestion_highlight_style,
             },
@@ -1699,7 +1702,7 @@ pub mod tests {
     ) -> Vec<(String, Option<Color>, Option<Color>)> {
         let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
         let mut chunks: Vec<(String, Option<Color>, Option<Color>)> = Vec::new();
-        for chunk in snapshot.chunks(rows, true, None, None) {
+        for chunk in snapshot.chunks(rows, true, None, None, None) {
             let syntax_color = chunk
                 .syntax_highlight_id
                 .and_then(|id| id.style(theme)?.color);

crates/editor/src/display_map/inlay_map.rs 🔗

@@ -1649,9 +1649,7 @@ mod tests {
                         false,
                         Highlights {
                             text_highlights: Some(&text_highlights),
-                            inlay_highlights: None,
-                            inlay_highlight_style: None,
-                            suggestion_highlight_style: None,
+                            ..Highlights::default()
                         },
                     )
                     .map(|chunk| chunk.text)

crates/editor/src/editor.rs 🔗

@@ -549,6 +549,7 @@ type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
 type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
 
 type BackgroundHighlight = (fn(&Theme) -> Color, Vec<Range<Anchor>>);
+type InlayBackgroundHighlight = (fn(&Theme) -> Color, Vec<InlayRange>);
 
 pub struct Editor {
     handle: WeakViewHandle<Self>,
@@ -580,6 +581,7 @@ pub struct Editor {
     placeholder_text: Option<Arc<str>>,
     highlighted_rows: Option<Range<u32>>,
     background_highlights: BTreeMap<TypeId, BackgroundHighlight>,
+    inlay_background_highlights: BTreeMap<TypeId, InlayBackgroundHighlight>,
     nav_history: Option<ItemNavHistory>,
     context_menu: Option<ContextMenu>,
     mouse_context_menu: ViewHandle<context_menu::ContextMenu>,
@@ -1523,6 +1525,7 @@ impl Editor {
             placeholder_text: None,
             highlighted_rows: None,
             background_highlights: Default::default(),
+            inlay_background_highlights: Default::default(),
             nav_history: None,
             context_menu: None,
             mouse_context_menu: cx
@@ -7070,9 +7073,6 @@ impl Editor {
             } else {
                 this.update(&mut cx, |this, cx| {
                     let buffer = this.buffer.read(cx).snapshot(cx);
-                    let display_snapshot = this
-                        .display_map
-                        .update(cx, |display_map, cx| display_map.snapshot(cx));
                     let mut buffer_highlights = this
                         .document_highlights_for_position(selection.head(), &buffer)
                         .filter(|highlight| {
@@ -7822,14 +7822,8 @@ impl Editor {
         color_fetcher: fn(&Theme) -> Color,
         cx: &mut ViewContext<Self>,
     ) {
-        // TODO kb
-        // self.background_highlights.insert(
-        //     TypeId::of::<T>(),
-        //     (
-        //         color_fetcher,
-        //         ranges.into_iter().map(DocumentRange::Inlay).collect(),
-        //     ),
-        // );
+        self.inlay_background_highlights
+            .insert(TypeId::of::<T>(), (color_fetcher, ranges));
         cx.notify();
     }
 
@@ -7837,15 +7831,16 @@ impl Editor {
         &mut self,
         cx: &mut ViewContext<Self>,
     ) -> Option<BackgroundHighlight> {
-        let highlights = self.background_highlights.remove(&TypeId::of::<T>());
-        if highlights.is_some() {
+        let text_highlights = self.background_highlights.remove(&TypeId::of::<T>());
+        let inlay_highlights = self.inlay_background_highlights.remove(&TypeId::of::<T>());
+        if text_highlights.is_some() || inlay_highlights.is_some() {
             cx.notify();
         }
-        highlights
+        text_highlights
     }
 
     #[cfg(feature = "test-support")]
-    pub fn all_background_highlights(
+    pub fn all_text_background_highlights(
         &mut self,
         cx: &mut ViewContext<Self>,
     ) -> Vec<(Range<DisplayPoint>, Color)> {

crates/editor/src/element.rs 🔗

@@ -1547,6 +1547,7 @@ impl EditorElement {
         &mut self,
         rows: Range<u32>,
         line_number_layouts: &[Option<Line>],
+        editor: &mut Editor,
         snapshot: &EditorSnapshot,
         cx: &ViewContext<Editor>,
     ) -> Vec<LineWithInvisibles> {
@@ -1595,6 +1596,7 @@ impl EditorElement {
                 .chunks(
                     rows.clone(),
                     true,
+                    Some(&editor.inlay_background_highlights),
                     Some(style.theme.hint),
                     Some(style.theme.suggestion),
                 )
@@ -2355,8 +2357,13 @@ impl Element<Editor> for EditorElement {
         let scrollbar_row_range = scroll_position.y()..(scroll_position.y() + height_in_lines);
 
         let mut max_visible_line_width = 0.0;
-        let line_layouts =
-            self.layout_lines(start_row..end_row, &line_number_layouts, &snapshot, cx);
+        let line_layouts = self.layout_lines(
+            start_row..end_row,
+            &line_number_layouts,
+            editor,
+            &snapshot,
+            cx,
+        );
         for line_with_invisibles in &line_layouts {
             if line_with_invisibles.line.width() > max_visible_line_width {
                 max_visible_line_width = line_with_invisibles.line.width();
@@ -69,7 +69,6 @@ pub enum GoToDefinitionLink {
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct InlayRange {
     pub inlay: InlayId,
-    // TODO kb look up inlays by id instead?
     pub inlay_position: Anchor,
     pub highlight_start: usize,
     pub highlight_end: usize,

crates/search/src/buffer_search.rs 🔗

@@ -992,7 +992,7 @@ mod tests {
             .unwrap();
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[
                     (
                         DisplayPoint::new(2, 17)..DisplayPoint::new(2, 19),
@@ -1013,7 +1013,7 @@ mod tests {
         editor.next_notification(cx).await;
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[(
                     DisplayPoint::new(2, 43)..DisplayPoint::new(2, 45),
                     Color::red(),
@@ -1029,7 +1029,7 @@ mod tests {
             .unwrap();
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[
                     (
                         DisplayPoint::new(0, 24)..DisplayPoint::new(0, 26),
@@ -1070,7 +1070,7 @@ mod tests {
         editor.next_notification(cx).await;
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[
                     (
                         DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43),
@@ -1281,7 +1281,7 @@ mod tests {
             .unwrap();
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[(
                     DisplayPoint::new(2, 43)..DisplayPoint::new(2, 45),
                     Color::red(),
@@ -1308,7 +1308,7 @@ mod tests {
         editor.next_notification(cx).await;
         editor.update(cx, |editor, cx| {
             assert_eq!(
-                editor.all_background_highlights(cx),
+                editor.all_text_background_highlights(cx),
                 &[(
                     DisplayPoint::new(0, 35)..DisplayPoint::new(0, 40),
                     Color::red(),

crates/search/src/project_search.rs 🔗

@@ -1724,7 +1724,7 @@ pub mod tests {
             assert_eq!(
                 search_view
                     .results_editor
-                    .update(cx, |editor, cx| editor.all_background_highlights(cx)),
+                    .update(cx, |editor, cx| editor.all_text_background_highlights(cx)),
                 &[
                     (
                         DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35),

crates/vim/src/normal/search.rs 🔗

@@ -227,7 +227,7 @@ mod test {
         deterministic.run_until_parked();
 
         cx.update_editor(|editor, cx| {
-            let highlights = editor.all_background_highlights(cx);
+            let highlights = editor.all_text_background_highlights(cx);
             assert_eq!(3, highlights.len());
             assert_eq!(
                 DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),

crates/vim/src/test.rs 🔗

@@ -190,7 +190,7 @@ async fn test_selection_on_search(cx: &mut gpui::TestAppContext) {
     search_bar.next_notification(&cx).await;
 
     cx.update_editor(|editor, cx| {
-        let highlights = editor.all_background_highlights(cx);
+        let highlights = editor.all_text_background_highlights(cx);
         assert_eq!(3, highlights.len());
         assert_eq!(
             DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),