lsp: Resolve code lenses before surfacing them as code actions - #54175
lsp: Resolve code lenses before surfacing them as code actions#54175aviatesk wants to merge 1 commit into
Conversation
Code lens items are currently exposed through the code action menu. When a language server returns lenses lazily (rust-analyzer's `N implementations` etc.), they arrive with no `command` field until `codeLens/resolve` fills it in. This caused two user-visible issues in the menu: 1. The item's label displayed as "Unknown command" instead of the real title. 2. Clicking the item dispatched to `workspace/executeCommand` instead of the intended client-side handler (references panel, runnable scheduler). `try_handle_client_command` runs before `apply_code_action`, so it saw `command = None`, returned false, and the action fell through to the generic apply path — by which point resolving the action was too late to redirect. Resolve lazy lenses inline in `Entity<Project>::code_actions` so that by the time the menu renders (and by the time the user clicks), the `command` field is populated. `refresh_code_actions` is already 250ms debounced, and already-resolved actions short-circuit the new `Project::resolve_code_action` / `LspStore::resolve_code_action`, so the extra request only fires once the user has parked their cursor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Thank you, we try to do improve lens resolution in #54100 so most probably if we want to do it, we should do it there. The new approach attempts to resolve the lens in the viewport eagerly, which presumably covers all action-related, selection-based cases this PR solves too? |
|
With #54100 landing the inline code lens UI, do we still need code lens items in the code action menu? If not, this PR isn't needed. If we keep that surface, I think two things matter:
I'd rather drop the menu surface entirely in #54100. Keeping it means fixing both. |
|
Thank you for flagging, we need to fix both either way I think. |
Code lens items are currently exposed through the code action menu. When a language server returns lenses lazily (rust-analyzer's
N implementationsetc.), they arrive with nocommandfield untilcodeLens/resolvefills it in.This caused two user-visible issues in the menu:
workspace/executeCommandinstead of the intended client-side handler (references panel, runnable scheduler).try_handle_client_commandruns beforeapply_code_action, so it sawcommand = None, returned false, and the action fell through to the generic apply path — by which point resolving the action was too late to redirect.Resolve lazy lenses inline in
Entity<Project>::code_actionsso that by the time the menu renders (and by the time the user clicks), thecommandfield is populated.refresh_code_actionsis already 250ms debounced, and already-resolved actions short-circuit the newProject::resolve_code_action/LspStore::resolve_code_action, so the extra request only fires once the user has parked their cursor.Notes on scope:
In this PR,
codeLens/resolvefires wheneverrefresh_code_actionsruns i.e. on every cursor row change (250 ms debounced), regardless of whether the user actually opens the code action menu. So that can produce unnecessary resolve requests.The ideal would be to resolve lazily when the menu is opened, but this PR keeps the scope narrow to the correctness fix (lazy lenses showing "Unknown command" in the menu, and client-side command dispatch missing) so it's easy to review in isolation.
Separately: now that the inline code lens UI landed in #54100, it may be worth considering whether surfacing code lenses through the code action menu is still justified. Removing that feature would eliminate the eager-resolve overhead entirely, and the inline UI already covers the functionality. Happy to follow up on either of these in separate changes.
Self-Review Checklist:
Release Notes: