Slightly simplify editor highlights code (#9123)

Kirill Bulatov created

Prepare for git diff hunk highlights by grouping all inlay highlight
properties into one struct, and removing the dead background highlight
code.


Release Notes:

- N/A

Change summary

crates/editor/src/display_map.rs           | 23 ++++++++++------
crates/editor/src/display_map/inlay_map.rs | 12 +++-----
crates/editor/src/editor.rs                | 32 +++--------------------
crates/editor/src/hover_popover.rs         |  7 ----
4 files changed, 25 insertions(+), 49 deletions(-)

Detailed changes

crates/editor/src/display_map.rs 🔗

@@ -339,8 +339,13 @@ impl DisplayMap {
 pub(crate) struct Highlights<'a> {
     pub text_highlights: Option<&'a TextHighlights>,
     pub inlay_highlights: Option<&'a InlayHighlights>,
-    pub inlay_highlight_style: Option<HighlightStyle>,
-    pub suggestion_highlight_style: Option<HighlightStyle>,
+    pub styles: HighlightStyles,
+}
+
+#[derive(Default, Debug, Clone, Copy)]
+pub struct HighlightStyles {
+    pub inlay_hint: Option<HighlightStyle>,
+    pub suggestion: Option<HighlightStyle>,
 }
 
 pub struct HighlightedChunk<'a> {
@@ -516,8 +521,7 @@ impl DisplaySnapshot {
         &self,
         display_rows: Range<u32>,
         language_aware: bool,
-        inlay_highlight_style: Option<HighlightStyle>,
-        suggestion_highlight_style: Option<HighlightStyle>,
+        highlight_styles: HighlightStyles,
     ) -> DisplayChunks<'_> {
         self.block_snapshot.chunks(
             display_rows,
@@ -525,8 +529,7 @@ impl DisplaySnapshot {
             Highlights {
                 text_highlights: Some(&self.text_highlights),
                 inlay_highlights: Some(&self.inlay_highlights),
-                inlay_highlight_style,
-                suggestion_highlight_style,
+                styles: highlight_styles,
             },
         )
     }
@@ -540,8 +543,10 @@ impl DisplaySnapshot {
         self.chunks(
             display_rows,
             language_aware,
-            Some(editor_style.inlays_style),
-            Some(editor_style.suggestions_style),
+            HighlightStyles {
+                inlay_hint: Some(editor_style.inlay_hints_style),
+                suggestion: Some(editor_style.suggestions_style),
+            },
         )
         .map(|chunk| {
             let mut highlight_style = chunk
@@ -1846,7 +1851,7 @@ pub mod tests {
     ) -> Vec<(String, Option<Hsla>, Option<Hsla>)> {
         let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
         let mut chunks: Vec<(String, Option<Hsla>, Option<Hsla>)> = Vec::new();
-        for chunk in snapshot.chunks(rows, true, None, None) {
+        for chunk in snapshot.chunks(rows, true, HighlightStyles::default()) {
             let syntax_color = chunk
                 .syntax_highlight_id
                 .and_then(|id| id.style(theme)?.color);

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

@@ -1,4 +1,4 @@
-use crate::InlayId;
+use crate::{HighlightStyles, InlayId};
 use collections::{BTreeMap, BTreeSet};
 use gpui::HighlightStyle;
 use language::{Chunk, Edit, Point, TextSummary};
@@ -215,8 +215,7 @@ pub struct InlayChunks<'a> {
     inlay_chunk: Option<&'a str>,
     output_offset: InlayOffset,
     max_output_offset: InlayOffset,
-    inlay_highlight_style: Option<HighlightStyle>,
-    suggestion_highlight_style: Option<HighlightStyle>,
+    highlight_styles: HighlightStyles,
     highlight_endpoints: Peekable<vec::IntoIter<HighlightEndpoint>>,
     active_highlights: BTreeMap<Option<TypeId>, HighlightStyle>,
     highlights: Highlights<'a>,
@@ -307,8 +306,8 @@ impl<'a> Iterator for InlayChunks<'a> {
                 }
 
                 let mut highlight_style = match inlay.id {
-                    InlayId::Suggestion(_) => self.suggestion_highlight_style,
-                    InlayId::Hint(_) => self.inlay_highlight_style,
+                    InlayId::Suggestion(_) => self.highlight_styles.suggestion,
+                    InlayId::Hint(_) => self.highlight_styles.inlay_hint,
                 };
                 let next_inlay_highlight_endpoint;
                 let offset_in_inlay = self.output_offset - self.transforms.start().0;
@@ -1052,8 +1051,7 @@ impl InlaySnapshot {
             buffer_chunk: None,
             output_offset: range.start,
             max_output_offset: range.end,
-            inlay_highlight_style: highlights.inlay_highlight_style,
-            suggestion_highlight_style: highlights.suggestion_highlight_style,
+            highlight_styles: highlights.styles,
             highlight_endpoints: highlight_endpoints.into_iter().peekable(),
             active_highlights: Default::default(),
             highlights,

crates/editor/src/editor.rs 🔗

@@ -111,7 +111,6 @@ use std::{
     time::{Duration, Instant},
 };
 pub use sum_tree::Bias;
-use sum_tree::TreeMap;
 use text::{BufferId, OffsetUtf16, Rope};
 use theme::{
     observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme,
@@ -323,7 +322,7 @@ pub struct EditorStyle {
     pub scrollbar_width: Pixels,
     pub syntax: Arc<SyntaxTheme>,
     pub status: StatusColors,
-    pub inlays_style: HighlightStyle,
+    pub inlay_hints_style: HighlightStyle,
     pub suggestions_style: HighlightStyle,
 }
 
@@ -339,7 +338,7 @@ impl Default for EditorStyle {
             // We should look into removing the status colors from the editor
             // style and retrieve them directly from the theme.
             status: StatusColors::dark(),
-            inlays_style: HighlightStyle::default(),
+            inlay_hints_style: HighlightStyle::default(),
             suggestions_style: HighlightStyle::default(),
         }
     }
@@ -351,7 +350,6 @@ type CompletionId = usize;
 // type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
 
 type BackgroundHighlight = (fn(&ThemeColors) -> Hsla, Vec<Range<Anchor>>);
-type InlayBackgroundHighlight = (fn(&ThemeColors) -> Hsla, Vec<InlayHighlight>);
 
 /// Zed's primary text input `View`, allowing users to edit a [`MultiBuffer`]
 ///
@@ -390,7 +388,6 @@ pub struct Editor {
     placeholder_text: Option<Arc<str>>,
     highlighted_rows: Option<Range<u32>>,
     background_highlights: BTreeMap<TypeId, BackgroundHighlight>,
-    inlay_background_highlights: TreeMap<Option<TypeId>, InlayBackgroundHighlight>,
     nav_history: Option<ItemNavHistory>,
     context_menu: RwLock<Option<ContextMenu>>,
     mouse_context_menu: Option<MouseContextMenu>,
@@ -1528,7 +1525,6 @@ impl Editor {
             placeholder_text: None,
             highlighted_rows: None,
             background_highlights: Default::default(),
-            inlay_background_highlights: Default::default(),
             nav_history: None,
             context_menu: RwLock::new(None),
             mouse_context_menu: None,
@@ -8148,7 +8144,7 @@ impl Editor {
                                                 scrollbar_width: cx.editor_style.scrollbar_width,
                                                 syntax: cx.editor_style.syntax.clone(),
                                                 status: cx.editor_style.status.clone(),
-                                                inlays_style: HighlightStyle {
+                                                inlay_hints_style: HighlightStyle {
                                                     color: Some(cx.theme().status().hint),
                                                     font_weight: Some(FontWeight::BOLD),
                                                     ..HighlightStyle::default()
@@ -8955,29 +8951,11 @@ impl Editor {
         cx.notify();
     }
 
-    pub(crate) fn highlight_inlay_background<T: 'static>(
-        &mut self,
-        ranges: Vec<InlayHighlight>,
-        color_fetcher: fn(&ThemeColors) -> Hsla,
-        cx: &mut ViewContext<Self>,
-    ) {
-        // TODO: no actual highlights happen for inlays currently, find a way to do that
-        self.inlay_background_highlights
-            .insert(Some(TypeId::of::<T>()), (color_fetcher, ranges));
-        cx.notify();
-    }
-
     pub fn clear_background_highlights<T: 'static>(
         &mut self,
-        cx: &mut ViewContext<Self>,
+        _cx: &mut ViewContext<Self>,
     ) -> Option<BackgroundHighlight> {
         let text_highlights = self.background_highlights.remove(&TypeId::of::<T>());
-        let inlay_highlights = self
-            .inlay_background_highlights
-            .remove(&Some(TypeId::of::<T>()));
-        if text_highlights.is_some() || inlay_highlights.is_some() {
-            cx.notify();
-        }
         text_highlights
     }
 
@@ -10089,7 +10067,7 @@ impl Render for Editor {
                 scrollbar_width: px(12.),
                 syntax: cx.theme().syntax().clone(),
                 status: cx.theme().status().clone(),
-                inlays_style: HighlightStyle {
+                inlay_hints_style: HighlightStyle {
                     color: Some(cx.theme().status().hint),
                     ..HighlightStyle::default()
                 },

crates/editor/src/hover_popover.rs 🔗

@@ -114,12 +114,7 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
                 };
 
                 this.update(&mut cx, |this, cx| {
-                    // Highlight the selected symbol using a background highlight
-                    this.highlight_inlay_background::<HoverState>(
-                        vec![inlay_hover.range],
-                        |theme| theme.element_hover, // todo("use a proper background here")
-                        cx,
-                    );
+                    // TODO: no background highlights happen for inlays currently
                     this.hover_state.info_popover = Some(hover_popover);
                     cx.notify();
                 })?;