Fix `hover_popover.rs` after bad rebase

Julia created

Change summary

crates/editor/src/editor.rs        |  35 +-------
crates/editor/src/hover_popover.rs | 128 ++++++++++++++-----------------
crates/language/src/markdown.rs    |  31 +++++++
3 files changed, 92 insertions(+), 102 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -60,7 +60,6 @@ use itertools::Itertools;
 pub use language::{char_kind, CharKind};
 use language::{
     language_settings::{self, all_language_settings, InlayHintSettings},
-    markdown::MarkdownHighlight,
     point_from_lsp, AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion,
     CursorShape, Diagnostic, DiagnosticSeverity, Documentation, File, IndentKind, IndentSize,
     Language, LanguageServerName, OffsetRangeExt, OffsetUtf16, Point, Selection, SelectionGoal,
@@ -139,45 +138,21 @@ pub fn render_parsed_markdown(
                 .highlights
                 .iter()
                 .filter_map(|(range, highlight)| {
-                    let highlight = match highlight {
-                        MarkdownHighlight::Style(style) => {
-                            let mut highlight = HighlightStyle::default();
-
-                            if style.italic {
-                                highlight.italic = Some(true);
-                            }
-
-                            if style.underline {
-                                highlight.underline = Some(fonts::Underline {
-                                    thickness: 1.0.into(),
-                                    ..Default::default()
-                                });
-                            }
-
-                            if style.weight != fonts::Weight::default() {
-                                highlight.weight = Some(style.weight);
-                            }
-
-                            highlight
-                        }
-
-                        MarkdownHighlight::Code(id) => id.style(&editor_style.syntax)?,
-                    };
-
+                    let highlight = highlight.to_highlight_style(&editor_style.syntax)?;
                     Some((range.clone(), highlight))
                 })
                 .collect::<Vec<_>>(),
         )
-        .with_custom_runs(parsed.region_ranges, move |ix, bounds, scene, _| {
+        .with_custom_runs(parsed.region_ranges, move |ix, bounds, cx| {
             region_id += 1;
             let region = parsed.regions[ix].clone();
 
             if let Some(url) = region.link_url {
-                scene.push_cursor_region(CursorRegion {
+                cx.scene().push_cursor_region(CursorRegion {
                     bounds,
                     style: CursorStyle::PointingHand,
                 });
-                scene.push_mouse_region(
+                cx.scene().push_mouse_region(
                     MouseRegion::new::<RenderedMarkdown>(view_id, region_id, bounds)
                         .on_click::<Editor, _>(MouseButton::Left, move |_, _, cx| {
                             cx.platform().open_url(&url)
@@ -186,7 +161,7 @@ pub fn render_parsed_markdown(
             }
 
             if region.code {
-                scene.push_quad(gpui::Quad {
+                cx.scene().push_quad(gpui::Quad {
                     bounds,
                     background: Some(code_span_background_color),
                     border: Default::default(),

crates/editor/src/hover_popover.rs 🔗

@@ -1,6 +1,6 @@
 use crate::{
     display_map::{InlayOffset, ToDisplayPoint},
-    link_go_to_definition::{DocumentRange, InlayRange},
+    link_go_to_definition::{InlayHighlight, RangeInEditor},
     Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSettings, EditorSnapshot, EditorStyle,
     ExcerptId, RangeToAnchorExt,
 };
@@ -51,19 +51,18 @@ pub fn hover_at(editor: &mut Editor, point: Option<DisplayPoint>, cx: &mut ViewC
 
 pub struct InlayHover {
     pub excerpt: ExcerptId,
-    pub triggered_from: InlayOffset,
-    pub range: InlayRange,
+    pub range: InlayHighlight,
     pub tooltip: HoverBlock,
 }
 
 pub fn find_hovered_hint_part(
     label_parts: Vec<InlayHintLabelPart>,
-    hint_range: Range<InlayOffset>,
+    hint_start: InlayOffset,
     hovered_offset: InlayOffset,
 ) -> Option<(InlayHintLabelPart, Range<InlayOffset>)> {
-    if hovered_offset >= hint_range.start && hovered_offset <= hint_range.end {
-        let mut hovered_character = (hovered_offset - hint_range.start).0;
-        let mut part_start = hint_range.start;
+    if hovered_offset >= hint_start {
+        let mut hovered_character = (hovered_offset - hint_start).0;
+        let mut part_start = hint_start;
         for part in label_parts {
             let part_len = part.value.chars().count();
             if hovered_character > part_len {
@@ -89,10 +88,8 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
         };
 
         if let Some(InfoPopover { symbol_range, .. }) = &editor.hover_state.info_popover {
-            if let DocumentRange::Inlay(range) = symbol_range {
-                if (range.highlight_start..range.highlight_end)
-                    .contains(&inlay_hover.triggered_from)
-                {
+            if let RangeInEditor::Inlay(range) = symbol_range {
+                if range == &inlay_hover.range {
                     // Hover triggered from same location as last time. Don't show again.
                     return;
                 }
@@ -100,18 +97,6 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
             hide_hover(editor, cx);
         }
 
-        let snapshot = editor.snapshot(cx);
-        // Don't request again if the location is the same as the previous request
-        if let Some(triggered_from) = editor.hover_state.triggered_from {
-            if inlay_hover.triggered_from
-                == snapshot
-                    .display_snapshot
-                    .anchor_to_inlay_offset(triggered_from)
-            {
-                return;
-            }
-        }
-
         let task = cx.spawn(|this, mut cx| {
             async move {
                 cx.background()
@@ -127,7 +112,7 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
 
                 let hover_popover = InfoPopover {
                     project: project.clone(),
-                    symbol_range: DocumentRange::Inlay(inlay_hover.range),
+                    symbol_range: RangeInEditor::Inlay(inlay_hover.range.clone()),
                     blocks,
                     parsed_content,
                 };
@@ -331,7 +316,7 @@ fn show_hover(
 
                     Some(InfoPopover {
                         project: project.clone(),
-                        symbol_range: DocumentRange::Text(range),
+                        symbol_range: RangeInEditor::Text(range),
                         blocks,
                         parsed_content,
                     })
@@ -449,8 +434,8 @@ impl HoverState {
                 self.info_popover
                     .as_ref()
                     .map(|info_popover| match &info_popover.symbol_range {
-                        DocumentRange::Text(range) => &range.start,
-                        DocumentRange::Inlay(range) => &range.inlay_position,
+                        RangeInEditor::Text(range) => &range.start,
+                        RangeInEditor::Inlay(range) => &range.inlay_position,
                     })
             })?;
         let point = anchor.to_display_point(&snapshot.display_snapshot);
@@ -476,7 +461,7 @@ impl HoverState {
 #[derive(Debug, Clone)]
 pub struct InfoPopover {
     pub project: ModelHandle<Project>,
-    symbol_range: DocumentRange,
+    symbol_range: RangeInEditor,
     pub blocks: Vec<HoverBlock>,
     parsed_content: ParsedMarkdown,
 }
@@ -587,14 +572,12 @@ mod tests {
         inlay_hint_cache::tests::{cached_hint_labels, visible_hint_labels},
         link_go_to_definition::update_inlay_link_and_hover_points,
         test::editor_lsp_test_context::EditorLspTestContext,
+        InlayId,
     };
     use collections::BTreeSet;
-    use gpui::fonts::Weight;
+    use gpui::fonts::{HighlightStyle, Underline, Weight};
     use indoc::indoc;
-    use language::{
-        language_settings::InlayHintSettings, markdown::MarkdownHighlightStyle, Diagnostic,
-        DiagnosticSet,
-    };
+    use language::{language_settings::InlayHintSettings, Diagnostic, DiagnosticSet};
     use lsp::LanguageServerId;
     use project::{HoverBlock, HoverBlockKind};
     use smol::stream::StreamExt;
@@ -896,17 +879,16 @@ mod tests {
 
     #[gpui::test]
     fn test_render_blocks(cx: &mut gpui::TestAppContext) {
-        use markdown::MarkdownHighlight;
-
         init_test(cx, |_| {});
 
         cx.add_window(|cx| {
             let editor = Editor::single_line(None, cx);
+            let style = editor.style(cx);
 
             struct Row {
                 blocks: Vec<HoverBlock>,
                 expected_marked_text: String,
-                expected_styles: Vec<MarkdownHighlight>,
+                expected_styles: Vec<HighlightStyle>,
             }
 
             let rows = &[
@@ -917,10 +899,10 @@ mod tests {
                         kind: HoverBlockKind::Markdown,
                     }],
                     expected_marked_text: "one «two» three".to_string(),
-                    expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
-                        weight: Weight::BOLD,
+                    expected_styles: vec![HighlightStyle {
+                        weight: Some(Weight::BOLD),
                         ..Default::default()
-                    })],
+                    }],
                 },
                 // Links
                 Row {
@@ -929,10 +911,13 @@ mod tests {
                         kind: HoverBlockKind::Markdown,
                     }],
                     expected_marked_text: "one «two» three".to_string(),
-                    expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
-                        underline: true,
+                    expected_styles: vec![HighlightStyle {
+                        underline: Some(Underline {
+                            thickness: 1.0.into(),
+                            ..Default::default()
+                        }),
                         ..Default::default()
-                    })],
+                    }],
                 },
                 // Lists
                 Row {
@@ -957,10 +942,13 @@ mod tests {
                           - «c»
                           - d"
                     .unindent(),
-                    expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
-                        underline: true,
+                    expected_styles: vec![HighlightStyle {
+                        underline: Some(Underline {
+                            thickness: 1.0.into(),
+                            ..Default::default()
+                        }),
                         ..Default::default()
-                    })],
+                    }],
                 },
                 // Multi-paragraph list items
                 Row {
@@ -988,10 +976,13 @@ mod tests {
                           - ten
                         - six"
                         .unindent(),
-                    expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
-                        underline: true,
+                    expected_styles: vec![HighlightStyle {
+                        underline: Some(Underline {
+                            thickness: 1.0.into(),
+                            ..Default::default()
+                        }),
                         ..Default::default()
-                    })],
+                    }],
                 },
             ];
 
@@ -1012,8 +1003,18 @@ mod tests {
                     rendered.text, expected_text,
                     "wrong text for input {blocks:?}"
                 );
+
+                let rendered_highlights: Vec<_> = rendered
+                    .highlights
+                    .iter()
+                    .filter_map(|(range, highlight)| {
+                        let highlight = highlight.to_highlight_style(&style.syntax)?;
+                        Some((range.clone(), highlight))
+                    })
+                    .collect();
+
                 assert_eq!(
-                    rendered.highlights, expected_highlights,
+                    rendered_highlights, expected_highlights,
                     "wrong highlights for input {blocks:?}"
                 );
             }
@@ -1247,25 +1248,16 @@ mod tests {
             .advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100));
         cx.foreground().run_until_parked();
         cx.update_editor(|editor, cx| {
-            let snapshot = editor.snapshot(cx);
             let hover_state = &editor.hover_state;
             assert!(hover_state.diagnostic_popover.is_none() && hover_state.info_popover.is_some());
             let popover = hover_state.info_popover.as_ref().unwrap();
             let buffer_snapshot = editor.buffer().update(cx, |buffer, cx| buffer.snapshot(cx));
-            let entire_inlay_start = snapshot.display_point_to_inlay_offset(
-                inlay_range.start.to_display_point(&snapshot),
-                Bias::Left,
-            );
-
-            let expected_new_type_label_start = InlayOffset(entire_inlay_start.0 + ": ".len());
             assert_eq!(
                 popover.symbol_range,
-                DocumentRange::Inlay(InlayRange {
+                RangeInEditor::Inlay(InlayHighlight {
+                    inlay: InlayId::Hint(0),
                     inlay_position: buffer_snapshot.anchor_at(inlay_range.start, Bias::Right),
-                    highlight_start: expected_new_type_label_start,
-                    highlight_end: InlayOffset(
-                        expected_new_type_label_start.0 + new_type_label.len()
-                    ),
+                    range: ": ".len()..": ".len() + new_type_label.len(),
                 }),
                 "Popover range should match the new type label part"
             );
@@ -1309,23 +1301,17 @@ mod tests {
             .advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100));
         cx.foreground().run_until_parked();
         cx.update_editor(|editor, cx| {
-            let snapshot = editor.snapshot(cx);
             let hover_state = &editor.hover_state;
             assert!(hover_state.diagnostic_popover.is_none() && hover_state.info_popover.is_some());
             let popover = hover_state.info_popover.as_ref().unwrap();
             let buffer_snapshot = editor.buffer().update(cx, |buffer, cx| buffer.snapshot(cx));
-            let entire_inlay_start = snapshot.display_point_to_inlay_offset(
-                inlay_range.start.to_display_point(&snapshot),
-                Bias::Left,
-            );
-            let expected_struct_label_start =
-                InlayOffset(entire_inlay_start.0 + ": ".len() + new_type_label.len() + "<".len());
             assert_eq!(
                 popover.symbol_range,
-                DocumentRange::Inlay(InlayRange {
+                RangeInEditor::Inlay(InlayHighlight {
+                    inlay: InlayId::Hint(0),
                     inlay_position: buffer_snapshot.anchor_at(inlay_range.start, Bias::Right),
-                    highlight_start: expected_struct_label_start,
-                    highlight_end: InlayOffset(expected_struct_label_start.0 + struct_label.len()),
+                    range: ": ".len() + new_type_label.len() + "<".len()
+                        ..": ".len() + new_type_label.len() + "<".len() + struct_label.len(),
                 }),
                 "Popover range should match the struct label part"
             );

crates/language/src/markdown.rs 🔗

@@ -2,7 +2,7 @@ use std::ops::Range;
 use std::sync::Arc;
 
 use crate::{HighlightId, Language, LanguageRegistry};
-use gpui::fonts::Weight;
+use gpui::fonts::{self, HighlightStyle, Weight};
 use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
 
 #[derive(Debug, Clone)]
@@ -19,6 +19,35 @@ pub enum MarkdownHighlight {
     Code(HighlightId),
 }
 
+impl MarkdownHighlight {
+    pub fn to_highlight_style(&self, theme: &theme::SyntaxTheme) -> Option<HighlightStyle> {
+        match self {
+            MarkdownHighlight::Style(style) => {
+                let mut highlight = HighlightStyle::default();
+
+                if style.italic {
+                    highlight.italic = Some(true);
+                }
+
+                if style.underline {
+                    highlight.underline = Some(fonts::Underline {
+                        thickness: 1.0.into(),
+                        ..Default::default()
+                    });
+                }
+
+                if style.weight != fonts::Weight::default() {
+                    highlight.weight = Some(style.weight);
+                }
+
+                Some(highlight)
+            }
+
+            MarkdownHighlight::Code(id) => id.style(theme),
+        }
+    }
+}
+
 #[derive(Debug, Clone, Default, PartialEq, Eq)]
 pub struct MarkdownHighlightStyle {
     pub italic: bool,