From 15d700b97749dd113d478de63137be7493b58bcb Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 20 Aug 2026 21:02:02 +0530 Subject: [PATCH 1/3] feat(lsp): show a picker for jump-to-definition with multiple targets Fixes #3093. When an LSP server resolves textDocument/definition to multiple locations (e.g. a polymorphic call with several overrides), Phoenix used to silently jump to whichever one happened to be last in the array. Now it shows a Code-Hints-style dropdown near the cursor listing every candidate, mouse- and keyboard-navigable, reusing the existing InlineMenu widget (same one Extract to Variable/Function already use) rather than a top-of-editor ModalBar. - DefaultProviders.js: showJumpTargetPicker() builds the picker; fallBackToImplementations() additionally queries textDocument/implementation when gotoDefinition resolves to a single location, since that's frequently just the base/interface declaration for a polymorphic call site. - Each item shows a hover/keyboard-driven side excerpt (reusing the LSP hint doc-popup mechanism) with a short code preview so same-named overrides in different classes are distinguishable, not just by file:line. The enclosing declaration and the target's own block boundaries are found via indentation scanning rather than hand-listed per-language keywords, so it isn't TS-specific. - LSPClient.js: adds gotoImplementation(), factored out of gotoDefinition()'s shared request/normalize logic. - QuickViewManager.js: the picker (and Code Hints, and any other dropdown/context-menu) now suppresses the unrelated hover quickview while open, checked live via a DOM query rather than an imperative suppress/unsuppress pairing that could get stuck if a popup closes through a path that doesn't notify it. - Tests: JumpToDefinitionMultiTarget-integ-test.js covers the picker end-to-end against a mocked provider, the excerpt-building logic directly, and - desktop only - the same repro against the real vtsls server. --- src/features/QuickViewManager.js | 19 +- src/languageTools/DefaultProviders.js | 365 ++++++++- src/languageTools/LSPClient.js | 24 +- src/nls/root/strings.js | 2 + src/styles/brackets.less | 33 + src/styles/brackets_patterns_override.less | 38 +- test/UnitTestSuite.js | 1 + .../JumpToDefinitionMultiTarget-integ-test.js | 700 ++++++++++++++++++ .../aliceClass.js | 11 + .../polymorphism.js | 25 + .../realLspAliceClass.js | 38 + .../realLspPolymorphism.js | 38 + 12 files changed, 1248 insertions(+), 46 deletions(-) create mode 100644 test/spec/JumpToDefinitionMultiTarget-integ-test.js create mode 100644 test/spec/JumpToDefinitionMultiTarget-test-files/aliceClass.js create mode 100644 test/spec/JumpToDefinitionMultiTarget-test-files/polymorphism.js create mode 100644 test/spec/JumpToDefinitionMultiTarget-test-files/realLspAliceClass.js create mode 100644 test/spec/JumpToDefinitionMultiTarget-test-files/realLspPolymorphism.js diff --git a/src/features/QuickViewManager.js b/src/features/QuickViewManager.js index 17a47f7adf..2970f9fd48 100644 --- a/src/features/QuickViewManager.js +++ b/src/features/QuickViewManager.js @@ -241,6 +241,23 @@ define(function (require, exports, module) { animationRequest, quickViewLocked = false; + // True while some other menu-like UI is open - the top menu bar, a context menu (including the + // editor's right-click menu), the autocomplete Code Hints list, or an InlineMenu picker like + // jump-to-definition's multi-target picker (see languageTools/DefaultProviders.js) or Extract + // to Variable/Function. QuickView shouldn't pop up while any of those has the user's attention. + // All of them share the same underlying convention - a `