Hide hover when font changes, and handle case where delay was preventing hover with large symbol range

Keith Simmons created

Change summary

crates/editor/src/display_map.rs          |  4 +-
crates/editor/src/display_map/wrap_map.rs | 12 ++++++++-
crates/editor/src/editor.rs               | 15 ++++++++++++
crates/editor/src/hover_popover.rs        | 29 ++++++++++++++----------
4 files changed, 43 insertions(+), 17 deletions(-)

Detailed changes

crates/editor/src/display_map.rs 🔗

@@ -193,9 +193,9 @@ impl DisplayMap {
         self.text_highlights.remove(&Some(type_id))
     }
 
-    pub fn set_font(&self, font_id: FontId, font_size: f32, cx: &mut ModelContext<Self>) {
+    pub fn set_font(&self, font_id: FontId, font_size: f32, cx: &mut ModelContext<Self>) -> bool {
         self.wrap_map
-            .update(cx, |map, cx| map.set_font(font_id, font_size, cx));
+            .update(cx, |map, cx| map.set_font(font_id, font_size, cx))
     }
 
     pub fn set_wrap_width(&self, width: Option<f32>, cx: &mut ModelContext<Self>) -> bool {

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

@@ -121,10 +121,18 @@ impl WrapMap {
         (self.snapshot.clone(), mem::take(&mut self.edits_since_sync))
     }
 
-    pub fn set_font(&mut self, font_id: FontId, font_size: f32, cx: &mut ModelContext<Self>) {
+    pub fn set_font(
+        &mut self,
+        font_id: FontId,
+        font_size: f32,
+        cx: &mut ModelContext<Self>,
+    ) -> bool {
         if (font_id, font_size) != self.font {
             self.font = (font_id, font_size);
-            self.rewrap(cx)
+            self.rewrap(cx);
+            true
+        } else {
+            false
         }
     }
 

crates/editor/src/editor.rs 🔗

@@ -5688,9 +5688,22 @@ impl Entity for Editor {
 impl View for Editor {
     fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
         let style = self.style(cx);
-        self.display_map.update(cx, |map, cx| {
+        let font_changed = self.display_map.update(cx, |map, cx| {
             map.set_font(style.text.font_id, style.text.font_size, cx)
         });
+
+        // If the
+        if font_changed {
+            let handle = self.handle.clone();
+            cx.defer(move |cx| {
+                if let Some(editor) = handle.upgrade(cx) {
+                    editor.update(cx, |editor, cx| {
+                        hide_hover(editor, cx);
+                    })
+                }
+            });
+        }
+
         EditorElement::new(self.handle.clone(), style.clone(), self.cursor_shape).boxed()
     }
 

crates/editor/src/hover_popover.rs 🔗

@@ -62,11 +62,10 @@ pub fn hide_hover(editor: &mut Editor, cx: &mut ViewContext<Editor>) -> bool {
         did_hide = true;
         cx.notify();
     }
+    editor.hover_state.task = None;
 
     editor.clear_background_highlights::<HoverState>(cx);
 
-    editor.hover_state.task = None;
-
     did_hide
 }
 
@@ -86,16 +85,6 @@ fn show_hover(
     let snapshot = editor.snapshot(cx);
     let multibuffer_offset = point.to_offset(&snapshot.display_snapshot, Bias::Left);
 
-    if let Some(range) = &editor.hover_state.symbol_range {
-        if range
-            .to_offset(&snapshot.buffer_snapshot)
-            .contains(&multibuffer_offset)
-        {
-            // Hover triggered from same location as last time. Don't show again.
-            return;
-        }
-    }
-
     let (buffer, buffer_position) = if let Some(output) = editor
         .buffer
         .read(cx)
@@ -137,6 +126,18 @@ fn show_hover(
             .unwrap_or(true) // Hover was visible recently enough
         && !ignore_timeout; // Hover triggered from keyboard
 
+    if should_delay {
+        if let Some(range) = &editor.hover_state.symbol_range {
+            if range
+                .to_offset(&snapshot.buffer_snapshot)
+                .contains(&multibuffer_offset)
+            {
+                // Hover triggered from same location as last time. Don't show again.
+                return;
+            }
+        }
+    }
+
     // Get input anchor
     let anchor = snapshot
         .buffer_snapshot
@@ -206,6 +207,10 @@ fn show_hover(
 
                         cx.notify();
                     }
+
+                    if this.hover_state.popover.is_none() {
+                        this.hover_state.symbol_range = None;
+                    }
                 });
             }
             Ok::<_, anyhow::Error>(())