microsoft / microsoft/language-server-protocol

Proposal: Easier codeAction/resolve handling

Open
#1,748 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

code actions feature-request
Dominant language
TypeScript
Stars
13k
Forks
1k
Avg merge
6d 1h
Merged PRs (30d)
10

Description

This is a proposal for an easier workflow for lazy code actions.
A lazy code action is a code action where we separate the following, usually for performance:

  • resolving the title, kind, and location of the code action
  • resolving the edits for the code action

Status Quo

The current flow for lazy code actions is:

  1. client sends a textDocument/codeAction request, the body of which has type CodeActionParams
  2. If the server replies with a code action missing edit and command fields and (optional) data field of any type
  3. Then client sends textDocument/resolve, including the data the client replied to textDocument/codeAction with

The idea of the existing flow, as I understand it, is that the information in data will be sufficient to fill in the edit field of the code action.

The difficulty in implementing is that an LSP server implementor must design and implement a custom protocol for every lazy code action: what information to serialize into data and then read back.
There is no standard way of doing this and it sounds mistake-prone.

Alternative

I suggest adding an alternative flow:

  1. client sends a textDocument/codeAction request, the body of which has type CodeActionParams
  2. If the server replies with a code action missing edit and command fields
  3. Then client sends textDocument/resolve, including a codeActionParams field of type CodeActionParams corresponding to (1)

For backwards compatibility, the flow can be opt-in via a server and client capability called something like supportsCodeActionParamsInResolve.

I found a flow like this easier and simpler to implement because:

Simulating the alternative lazy resolution flow today

I simulated this alernative lazy code action flow with:

textDocument/codeAction server reply implementation:

  • Step 1: set edit to a () => WorkspaceEdit[] (In OCaml I used a lazy, but it shakes out to the same thing)
  • Step 2: Before serializing, replace edit with undefined and copy the codeActionParams to the data field of each code action.

testDocument/resolve server reply implementation:

  • Step 1: same code path as step 1 for textDocument/codeAction
  • Step 2: Before serializing, replace the edit field (set to () => WorkspaceEdit[] ) with the result of applying the function, so we
    return a fully resolved code action {edit: WorkspaceEdit[], ...}

Downsides of merely simulating are:

  • The hack is non-obvious and not discoverable for LSP server implementors
  • The CodeActionParams payload is repeated by the server once for every code action returned in textDocument/codeAction, which
    makes messages harder to read for debugging and testing and has a (small) speed and memory cost

Next steps

I could adapt this into a full proposal after getting feedback.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the textDocument/codeAction and textDocument/resolve entry points and the related client and server capability negotiation described in the proposal. Done means producing an agreed protocol design that addresses compatibility, payload shape, and the proposed supportsCodeActionParamsInResolve capability.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.