Use the `alt` modifier when going to a definition with cmd-click (#38148)

Tim Vermeulen and Joseph T. Lyons created

I don't totally follow how the `cmd_click_reveal_task` function works,
but it branches on whether `self.hovered_link_state` exists and contains
any links, and in case it doesn't, it doesn't use `modifiers.alt` for
deciding where to navigate. This PR addresses that.

The problem I've been having is that cmd-alt-click sometimes behaves as
cmd-click, i.e. it navigates to the definition in the current pane. This
appears to happen whenever I cmd-alt-click while the symbol I'm hovering
over isn't underlined, possibly when I click too quickly?

An alternative way to reliably reproduce this is to cmd-alt-click on a
symbol without letting go of cmd and alt and without moving the cursor.
Now the symbol is no longer underlined (and the hover preview has
disappeared as well), so clicking again (while still holding cmd and
alt) goes to the definition in the current pane:


https://github.com/user-attachments/assets/34003e01-fd95-4741-8a7d-6240d1c5a495

Release notes:

- Fixed a bug that caused cmd-alt-click to sometimes go to the
definition in the current pane

Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>

Change summary

crates/editor/src/hover_links.rs | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

Detailed changes

crates/editor/src/hover_links.rs 🔗

@@ -1,6 +1,7 @@
 use crate::{
     Anchor, Editor, EditorSettings, EditorSnapshot, FindAllReferences, GoToDefinition,
-    GoToTypeDefinition, GotoDefinitionKind, InlayId, Navigated, PointForPosition, SelectPhase,
+    GoToDefinitionSplit, GoToTypeDefinition, GoToTypeDefinitionSplit, GotoDefinitionKind, InlayId,
+    Navigated, PointForPosition, SelectPhase,
     editor_settings::GoToDefinitionFallback,
     hover_popover::{self, InlayHover},
     scroll::ScrollAmount,
@@ -266,10 +267,13 @@ impl Editor {
         );
 
         let navigate_task = if point.as_valid().is_some() {
-            if modifiers.shift {
-                self.go_to_type_definition(&GoToTypeDefinition, window, cx)
-            } else {
-                self.go_to_definition(&GoToDefinition, window, cx)
+            match (modifiers.shift, modifiers.alt) {
+                (true, true) => {
+                    self.go_to_type_definition_split(&GoToTypeDefinitionSplit, window, cx)
+                }
+                (true, false) => self.go_to_type_definition(&GoToTypeDefinition, window, cx),
+                (false, true) => self.go_to_definition_split(&GoToDefinitionSplit, window, cx),
+                (false, false) => self.go_to_definition(&GoToDefinition, window, cx),
             }
         } else {
             Task::ready(Ok(Navigated::No))