uncomment mouse moved

Piotr Osiewicz created

Change summary

crates/editor2/src/element.rs               | 108 ++++---
crates/editor2/src/link_go_to_definition.rs | 329 +++++++++++-----------
2 files changed, 225 insertions(+), 212 deletions(-)

Detailed changes

crates/editor2/src/element.rs 🔗

@@ -2,6 +2,10 @@ use crate::{
     display_map::{BlockStyle, DisplaySnapshot, FoldStatus, HighlightedChunk, ToDisplayPoint},
     editor_settings::ShowScrollbar,
     git::{diff_hunk_to_display, DisplayDiffHunk},
+    hover_popover::hover_at,
+    link_go_to_definition::{
+        update_go_to_definition_link, update_inlay_link_and_hover_points, GoToDefinitionTrigger,
+    },
     scroll::scroll_amount::ScrollAmount,
     CursorShape, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle,
     HalfPageDown, HalfPageUp, LineDown, LineUp, MoveDown, PageDown, PageUp, Point, Selection,
@@ -12,9 +16,9 @@ use collections::{BTreeMap, HashMap};
 use gpui::{
     black, hsla, point, px, relative, size, transparent_black, Action, AnyElement,
     BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, DispatchContext, DispatchPhase,
-    Edges, Element, ElementId, Entity, Hsla, KeyDownEvent, KeyListener, KeyMatch, Line, Pixels,
-    ScrollWheelEvent, ShapedGlyph, Size, StatefulInteraction, Style, TextRun, TextStyle,
-    TextSystem, ViewContext, WindowContext,
+    Edges, Element, ElementId, Entity, Hsla, KeyDownEvent, KeyListener, KeyMatch, Line, Modifiers,
+    MouseMoveEvent, Pixels, ScrollWheelEvent, ShapedGlyph, Size, StatefulInteraction, Style,
+    TextRun, TextStyle, TextSystem, ViewContext, WindowContext,
 };
 use itertools::Itertools;
 use language::language_settings::ShowWhitespaceSetting;
@@ -423,50 +427,50 @@ impl EditorElement {
     //     }
     // }
 
-    // fn mouse_moved(
-    //     editor: &mut Editor,
-    //     MouseMovedEvent {
-    //         modifiers: Modifiers { shift, cmd, .. },
-    //         position,
-    //         ..
-    //     }: MouseMovedEvent,
-    //     position_map: &PositionMap,
-    //     text_bounds: Bounds<Pixels>,
-    //     cx: &mut ViewContext<Editor>,
-    // ) -> bool {
-    //     // This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed
-    //     // Don't trigger hover popover if mouse is hovering over context menu
-    //     if text_bounds.contains_point(position) {
-    //         let point_for_position = position_map.point_for_position(text_bounds, position);
-    //         match point_for_position.as_valid() {
-    //             Some(point) => {
-    //                 update_go_to_definition_link(
-    //                     editor,
-    //                     Some(GoToDefinitionTrigger::Text(point)),
-    //                     cmd,
-    //                     shift,
-    //                     cx,
-    //                 );
-    //                 hover_at(editor, Some(point), cx);
-    //             }
-    //             None => {
-    //                 update_inlay_link_and_hover_points(
-    //                     &position_map.snapshot,
-    //                     point_for_position,
-    //                     editor,
-    //                     cmd,
-    //                     shift,
-    //                     cx,
-    //                 );
-    //             }
-    //         }
-    //     } else {
-    //         update_go_to_definition_link(editor, None, cmd, shift, cx);
-    //         hover_at(editor, None, cx);
-    //     }
+    fn mouse_moved(
+        editor: &mut Editor,
+        MouseMoveEvent {
+            modifiers: Modifiers { shift, command, .. },
+            position,
+            ..
+        }: &MouseMoveEvent,
+        position_map: &PositionMap,
+        text_bounds: Bounds<Pixels>,
+        cx: &mut ViewContext<Editor>,
+    ) -> bool {
+        // This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed
+        // Don't trigger hover popover if mouse is hovering over context menu
+        if text_bounds.contains_point(position) {
+            let point_for_position = position_map.point_for_position(text_bounds, position.clone());
+            match point_for_position.as_valid() {
+                Some(point) => {
+                    update_go_to_definition_link(
+                        editor,
+                        Some(GoToDefinitionTrigger::Text(point)),
+                        *command,
+                        *shift,
+                        cx,
+                    );
+                    hover_at(editor, Some(point), cx);
+                }
+                None => {
+                    update_inlay_link_and_hover_points(
+                        &position_map.snapshot,
+                        point_for_position,
+                        editor,
+                        *command,
+                        *shift,
+                        cx,
+                    );
+                }
+            }
+        } else {
+            update_go_to_definition_link(editor, None, *command, *shift, cx);
+            hover_at(editor, None, cx);
+        }
 
-    //     true
-    // }
+        true
+    }
 
     fn scroll(
         editor: &mut Editor,
@@ -2772,6 +2776,18 @@ impl Element<Editor> for EditorElement {
                 }
             }
         });
+        cx.on_mouse_event({
+            let position_map = layout.position_map.clone();
+            move |editor, event: &MouseMoveEvent, phase, cx| {
+                if phase != DispatchPhase::Bubble {
+                    return;
+                }
+
+                if Self::mouse_moved(editor, event, &position_map, bounds, cx) {
+                    cx.stop_propagation()
+                }
+            }
+        });
 
         if editor.focus_handle.is_focused(cx) {
             cx.handle_text_input();
@@ -171,173 +171,170 @@ pub fn update_inlay_link_and_hover_points(
     shift_held: bool,
     cx: &mut ViewContext<'_, Editor>,
 ) {
-    todo!("old implementation below")
-}
-// ) {
-//     let hovered_offset = if point_for_position.column_overshoot_after_line_end == 0 {
-//         Some(snapshot.display_point_to_inlay_offset(point_for_position.exact_unclipped, Bias::Left))
-//     } else {
-//         None
-//     };
-//     let mut go_to_definition_updated = false;
-//     let mut hover_updated = false;
-//     if let Some(hovered_offset) = hovered_offset {
-//         let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
-//         let previous_valid_anchor = buffer_snapshot.anchor_at(
-//             point_for_position.previous_valid.to_point(snapshot),
-//             Bias::Left,
-//         );
-//         let next_valid_anchor = buffer_snapshot.anchor_at(
-//             point_for_position.next_valid.to_point(snapshot),
-//             Bias::Right,
-//         );
-//         if let Some(hovered_hint) = editor
-//             .visible_inlay_hints(cx)
-//             .into_iter()
-//             .skip_while(|hint| {
-//                 hint.position
-//                     .cmp(&previous_valid_anchor, &buffer_snapshot)
-//                     .is_lt()
-//             })
-//             .take_while(|hint| {
-//                 hint.position
-//                     .cmp(&next_valid_anchor, &buffer_snapshot)
-//                     .is_le()
-//             })
-//             .max_by_key(|hint| hint.id)
-//         {
-//             let inlay_hint_cache = editor.inlay_hint_cache();
-//             let excerpt_id = previous_valid_anchor.excerpt_id;
-//             if let Some(cached_hint) = inlay_hint_cache.hint_by_id(excerpt_id, hovered_hint.id) {
-//                 match cached_hint.resolve_state {
-//                     ResolveState::CanResolve(_, _) => {
-//                         if let Some(buffer_id) = previous_valid_anchor.buffer_id {
-//                             inlay_hint_cache.spawn_hint_resolve(
-//                                 buffer_id,
-//                                 excerpt_id,
-//                                 hovered_hint.id,
-//                                 cx,
-//                             );
-//                         }
-//                     }
-//                     ResolveState::Resolved => {
-//                         let mut extra_shift_left = 0;
-//                         let mut extra_shift_right = 0;
-//                         if cached_hint.padding_left {
-//                             extra_shift_left += 1;
-//                             extra_shift_right += 1;
-//                         }
-//                         if cached_hint.padding_right {
-//                             extra_shift_right += 1;
-//                         }
-//                         match cached_hint.label {
-//                             project::InlayHintLabel::String(_) => {
-//                                 if let Some(tooltip) = cached_hint.tooltip {
-//                                     hover_popover::hover_at_inlay(
-//                                         editor,
-//                                         InlayHover {
-//                                             excerpt: excerpt_id,
-//                                             tooltip: match tooltip {
-//                                                 InlayHintTooltip::String(text) => HoverBlock {
-//                                                     text,
-//                                                     kind: HoverBlockKind::PlainText,
-//                                                 },
-//                                                 InlayHintTooltip::MarkupContent(content) => {
-//                                                     HoverBlock {
-//                                                         text: content.value,
-//                                                         kind: content.kind,
-//                                                     }
-//                                                 }
-//                                             },
-//                                             range: InlayHighlight {
-//                                                 inlay: hovered_hint.id,
-//                                                 inlay_position: hovered_hint.position,
-//                                                 range: extra_shift_left
-//                                                     ..hovered_hint.text.len() + extra_shift_right,
-//                                             },
-//                                         },
-//                                         cx,
-//                                     );
-//                                     hover_updated = true;
-//                                 }
-//                             }
-//                             project::InlayHintLabel::LabelParts(label_parts) => {
-//                                 let hint_start =
-//                                     snapshot.anchor_to_inlay_offset(hovered_hint.position);
-//                                 if let Some((hovered_hint_part, part_range)) =
-//                                     hover_popover::find_hovered_hint_part(
-//                                         label_parts,
-//                                         hint_start,
-//                                         hovered_offset,
-//                                     )
-//                                 {
-//                                     let highlight_start =
-//                                         (part_range.start - hint_start).0 + extra_shift_left;
-//                                     let highlight_end =
-//                                         (part_range.end - hint_start).0 + extra_shift_right;
-//                                     let highlight = InlayHighlight {
-//                                         inlay: hovered_hint.id,
-//                                         inlay_position: hovered_hint.position,
-//                                         range: highlight_start..highlight_end,
-//                                     };
-//                                     if let Some(tooltip) = hovered_hint_part.tooltip {
-//                                         hover_popover::hover_at_inlay(
-//                                             editor,
-//                                             InlayHover {
-//                                                 excerpt: excerpt_id,
-//                                                 tooltip: match tooltip {
-//                                                     InlayHintLabelPartTooltip::String(text) => {
-//                                                         HoverBlock {
-//                                                             text,
-//                                                             kind: HoverBlockKind::PlainText,
-//                                                         }
-//                                                     }
-//                                                     InlayHintLabelPartTooltip::MarkupContent(
-//                                                         content,
-//                                                     ) => HoverBlock {
-//                                                         text: content.value,
-//                                                         kind: content.kind,
-//                                                     },
-//                                                 },
-//                                                 range: highlight.clone(),
-//                                             },
-//                                             cx,
-//                                         );
-//                                         hover_updated = true;
-//                                     }
-//                                     if let Some((language_server_id, location)) =
-//                                         hovered_hint_part.location
-//                                     {
-//                                         go_to_definition_updated = true;
-//                                         update_go_to_definition_link(
-//                                             editor,
-//                                             Some(GoToDefinitionTrigger::InlayHint(
-//                                                 highlight,
-//                                                 location,
-//                                                 language_server_id,
-//                                             )),
-//                                             cmd_held,
-//                                             shift_held,
-//                                             cx,
-//                                         );
-//                                     }
-//                                 }
-//                             }
-//                         };
-//                     }
-//                     ResolveState::Resolving => {}
-//                 }
-//             }
-//         }
-//     }
+    let hovered_offset = if point_for_position.column_overshoot_after_line_end == 0 {
+        Some(snapshot.display_point_to_inlay_offset(point_for_position.exact_unclipped, Bias::Left))
+    } else {
+        None
+    };
+    let mut go_to_definition_updated = false;
+    let mut hover_updated = false;
+    if let Some(hovered_offset) = hovered_offset {
+        let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
+        let previous_valid_anchor = buffer_snapshot.anchor_at(
+            point_for_position.previous_valid.to_point(snapshot),
+            Bias::Left,
+        );
+        let next_valid_anchor = buffer_snapshot.anchor_at(
+            point_for_position.next_valid.to_point(snapshot),
+            Bias::Right,
+        );
+        if let Some(hovered_hint) = editor
+            .visible_inlay_hints(cx)
+            .into_iter()
+            .skip_while(|hint| {
+                hint.position
+                    .cmp(&previous_valid_anchor, &buffer_snapshot)
+                    .is_lt()
+            })
+            .take_while(|hint| {
+                hint.position
+                    .cmp(&next_valid_anchor, &buffer_snapshot)
+                    .is_le()
+            })
+            .max_by_key(|hint| hint.id)
+        {
+            let inlay_hint_cache = editor.inlay_hint_cache();
+            let excerpt_id = previous_valid_anchor.excerpt_id;
+            if let Some(cached_hint) = inlay_hint_cache.hint_by_id(excerpt_id, hovered_hint.id) {
+                match cached_hint.resolve_state {
+                    ResolveState::CanResolve(_, _) => {
+                        if let Some(buffer_id) = previous_valid_anchor.buffer_id {
+                            inlay_hint_cache.spawn_hint_resolve(
+                                buffer_id,
+                                excerpt_id,
+                                hovered_hint.id,
+                                cx,
+                            );
+                        }
+                    }
+                    ResolveState::Resolved => {
+                        let mut extra_shift_left = 0;
+                        let mut extra_shift_right = 0;
+                        if cached_hint.padding_left {
+                            extra_shift_left += 1;
+                            extra_shift_right += 1;
+                        }
+                        if cached_hint.padding_right {
+                            extra_shift_right += 1;
+                        }
+                        match cached_hint.label {
+                            project::InlayHintLabel::String(_) => {
+                                if let Some(tooltip) = cached_hint.tooltip {
+                                    hover_popover::hover_at_inlay(
+                                        editor,
+                                        InlayHover {
+                                            excerpt: excerpt_id,
+                                            tooltip: match tooltip {
+                                                InlayHintTooltip::String(text) => HoverBlock {
+                                                    text,
+                                                    kind: HoverBlockKind::PlainText,
+                                                },
+                                                InlayHintTooltip::MarkupContent(content) => {
+                                                    HoverBlock {
+                                                        text: content.value,
+                                                        kind: content.kind,
+                                                    }
+                                                }
+                                            },
+                                            range: InlayHighlight {
+                                                inlay: hovered_hint.id,
+                                                inlay_position: hovered_hint.position,
+                                                range: extra_shift_left
+                                                    ..hovered_hint.text.len() + extra_shift_right,
+                                            },
+                                        },
+                                        cx,
+                                    );
+                                    hover_updated = true;
+                                }
+                            }
+                            project::InlayHintLabel::LabelParts(label_parts) => {
+                                let hint_start =
+                                    snapshot.anchor_to_inlay_offset(hovered_hint.position);
+                                if let Some((hovered_hint_part, part_range)) =
+                                    hover_popover::find_hovered_hint_part(
+                                        label_parts,
+                                        hint_start,
+                                        hovered_offset,
+                                    )
+                                {
+                                    let highlight_start =
+                                        (part_range.start - hint_start).0 + extra_shift_left;
+                                    let highlight_end =
+                                        (part_range.end - hint_start).0 + extra_shift_right;
+                                    let highlight = InlayHighlight {
+                                        inlay: hovered_hint.id,
+                                        inlay_position: hovered_hint.position,
+                                        range: highlight_start..highlight_end,
+                                    };
+                                    if let Some(tooltip) = hovered_hint_part.tooltip {
+                                        hover_popover::hover_at_inlay(
+                                            editor,
+                                            InlayHover {
+                                                excerpt: excerpt_id,
+                                                tooltip: match tooltip {
+                                                    InlayHintLabelPartTooltip::String(text) => {
+                                                        HoverBlock {
+                                                            text,
+                                                            kind: HoverBlockKind::PlainText,
+                                                        }
+                                                    }
+                                                    InlayHintLabelPartTooltip::MarkupContent(
+                                                        content,
+                                                    ) => HoverBlock {
+                                                        text: content.value,
+                                                        kind: content.kind,
+                                                    },
+                                                },
+                                                range: highlight.clone(),
+                                            },
+                                            cx,
+                                        );
+                                        hover_updated = true;
+                                    }
+                                    if let Some((language_server_id, location)) =
+                                        hovered_hint_part.location
+                                    {
+                                        go_to_definition_updated = true;
+                                        update_go_to_definition_link(
+                                            editor,
+                                            Some(GoToDefinitionTrigger::InlayHint(
+                                                highlight,
+                                                location,
+                                                language_server_id,
+                                            )),
+                                            cmd_held,
+                                            shift_held,
+                                            cx,
+                                        );
+                                    }
+                                }
+                            }
+                        };
+                    }
+                    ResolveState::Resolving => {}
+                }
+            }
+        }
+    }
 
-//     if !go_to_definition_updated {
-//         update_go_to_definition_link(editor, None, cmd_held, shift_held, cx);
-//     }
-//     if !hover_updated {
-//         hover_popover::hover_at(editor, None, cx);
-//     }
-// }
+    if !go_to_definition_updated {
+        update_go_to_definition_link(editor, None, cmd_held, shift_held, cx);
+    }
+    if !hover_updated {
+        hover_popover::hover_at(editor, None, cx);
+    }
+}
 
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub enum LinkDefinitionKind {