Consider padding during hint highlight range mapping

Kirill Bulatov created

Change summary

crates/editor/src/hover_popover.rs         | 15 +++++++++++++--
crates/editor/src/link_go_to_definition.rs | 15 +++++++++++++--
2 files changed, 26 insertions(+), 4 deletions(-)

Detailed changes

crates/editor/src/hover_popover.rs 🔗

@@ -57,19 +57,30 @@ pub struct InlayHover {
 
 pub fn find_hovered_hint_part(
     label_parts: Vec<InlayHintLabelPart>,
+    padding_left: bool,
+    padding_right: bool,
     hint_range: Range<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;
-        for part in label_parts {
+        let last_label_part_index = label_parts.len() - 1;
+        for (i, part) in label_parts.into_iter().enumerate() {
             let part_len = part.value.chars().count();
             if hovered_character >= part_len {
                 hovered_character -= part_len;
                 part_start.0 += part_len;
             } else {
-                return Some((part, part_start..InlayOffset(part_start.0 + part_len)));
+                let mut part_end = InlayOffset(part_start.0 + part_len);
+                if padding_left {
+                    part_start.0 += 1;
+                    part_end.0 += 1;
+                }
+                if padding_right && i == last_label_part_index {
+                    part_end.0 -= 1;
+                }
+                return Some((part, part_start..part_end));
             }
         }
     }
@@ -218,6 +218,15 @@ pub fn update_inlay_link_and_hover_points(
                     ResolveState::Resolved => {
                         match cached_hint.label {
                             project::InlayHintLabel::String(_) => {
+                                let mut highlight_start = hint_start_offset;
+                                let mut highlight_end = hint_end_offset;
+                                if cached_hint.padding_left {
+                                    highlight_start.0 += 1;
+                                    highlight_end.0 += 1;
+                                }
+                                if cached_hint.padding_right {
+                                    highlight_end.0 -= 1;
+                                }
                                 if let Some(tooltip) = cached_hint.tooltip {
                                     hover_popover::hover_at_inlay(
                                         editor,
@@ -238,8 +247,8 @@ pub fn update_inlay_link_and_hover_points(
                                             triggered_from: hovered_offset,
                                             range: InlayRange {
                                                 inlay_position: hovered_hint.position,
-                                                highlight_start: hint_start_offset,
-                                                highlight_end: hint_end_offset,
+                                                highlight_start,
+                                                highlight_end,
                                             },
                                         },
                                         cx,
@@ -251,6 +260,8 @@ pub fn update_inlay_link_and_hover_points(
                                 if let Some((hovered_hint_part, part_range)) =
                                     hover_popover::find_hovered_hint_part(
                                         label_parts,
+                                        cached_hint.padding_left,
+                                        cached_hint.padding_right,
                                         hint_start_offset..hint_end_offset,
                                         hovered_offset,
                                     )