Skip to content

feat(lsp): show a picker for jump-to-definition with multiple targets - #3118

Open
abose wants to merge 3 commits into
mainfrom
ai
Open

feat(lsp): show a picker for jump-to-definition with multiple targets#3118
abose wants to merge 3 commits into
mainfrom
ai

Conversation

@abose

@abose abose commented Aug 20, 2026

Copy link
Copy Markdown
Member

Fixes #3093.

image image
Screencast.From.2026-08-20.21-44-38.mp4

When textDocument/definition resolves to multiple locations (e.g. a
polymorphic call with several overrides), Phoenix used to silently jump
to whichever one was last in the array. This shows a Code-Hints-style
dropdown at the cursor instead, listing every candidate, mouse- and
keyboard-navigable — reusing the existing InlineMenu widget.

  • Each item shows a hover/keyboard-driven code excerpt so same-named
    overrides in different classes are distinguishable.
  • If definition resolves to just the base declaration,
    implementation is also queried and merged in (declaration first,
    deduped by file+line), since that's the common polymorphic case.
    Merged-in rows get a small badge to mark them as implementations.
  • Adds LSPClient.gotoImplementation().
  • Hover quickview is suppressed while the picker (or any other
    dropdown/menu) is open.

Tests: JumpToDefinitionMultiTarget-integ-test.js — picker
interaction (mocked provider), merge/dedup logic, excerpt-building
logic, and a desktop-only real-vtsls repro.

abose added 2 commits August 20, 2026 21:02
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.
…e jump-to-definition picker

When a single textDocument/definition result was just the base declaration
(no polymorphism resolved), fall back to textDocument/implementation and
merge its results with the original instead of discarding one in favor of
the other. Locations are deduped by file+line rather than exact character,
since definition/implementation requests routinely anchor the same
declaration at different columns.

Implementation rows in the merged picker now get a small rotated
fa-code-branch badge so they're visually distinguishable from the
declaration row, which otherwise looks identical once merged into one
list. Badge is positioned with float:right rather than a flex wrapper -
a flex child nested inside InlineMenu's own inline item wrapper picked up
an anonymous-block "strut" from the parent's line-height, inflating every
row's height regardless of whether it had a badge.
…not a color chip

li.inlinemenu-header used a solid @bc-panel-bg-alt background, which read
as a mismatched floating block against the menu's own near-black
@dark-bc-menu-bg surface in dark theme. Drop the background entirely and
style it as a plain muted title with a hairline divider (the same
@dark-bc-menu-separator token this menu family's .divider rule already
uses, so it stays visible against a near-black surface) - matching the
minimal title treatment the code-excerpt side panel already uses, so both
halves of the picker read as one cohesive surface.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] Jump to definition when there are multiple jump points

1 participant