Description
Problem:
LSP server may be under heavy load when a client makes excessive calls to textDocument/codeActions
in order to display a code action icon in the margin. The icon depends solely on a single CodeActionKind
, yet the textDocument/codeActions
requires server to compute all actions that are available at a given location. This request is made frequently: whenever caret moves and lightbulb is not yet present in the margin. This places heavy computational burden on the server.
Client chooses an icon based on CodeActionKind
available at a line of code.
Goal:
The goal of the following proposal is to expose a request which allows a client to query for available CodeActionKind
s without requiring the server to perform expensive computation of all code actions. This request is expected to be lightweight, as a client may make it frequently: for example, whenever caret moves and lightbulb is not yet present in the margin.
Proposed solution:
The prepare code action request is sent from the client to the server to display the appropriate lightbulb icon in the margin at a given caret location or selected range.
Request:
- method:
textDocument/prepareCodeAction
- params:
prepareCodeActionsParams
defined as follows:
export interface PrepareCodeActionParams {
/**
* The document in which the command was invoked.
*/
textDocument: TextDocumentIdentifier;
/**
* The range for which the command was invoked.
*/
range: Range;
}
Note: This matches textDocument/codeAction
request which does not extend TextDocumentPositionParams
but passes in Range instead of Position
Response:
- result:
CodeActionKind[] | null
describing all or single CodeActionKind available at requested position. Client will display lightbulb icon based on its own understanding of precedence of CodeActionKinds. Ifnull
is returned then it is deemed thattextDocument/codeAction
request is not valid at the given range, andtextDocument/prepareCodeActions
will be queried as soon as the caret moves.
Server capability:
export interface CodeActionOptions extends WorkDoneProgressOptions {
/**
* Server supports testing for available code action kinds.
*/
prepareSupport?: boolean;
}
Behavior for servers which don't support this capability:
Visual Studio will continue to query textDocument/codeAction
on caret move to obtain CodeActionKind
. Remaining information will be discarded.
Difference from codeAction/resolve
codeAction/resolve
allows a server to lazily compute TextEdit
s and other properties of a previously known code action which was selected by the developer. The proposed request doesn't require the server to discover and name all available actions. It only requires the server to determine whether a single action exists, and what is its kind.
Other considerations:
It looks like CodeActionOptions
is tied to supporting code action literals. I don't fully understand these, and am curious whether there are clients or servers which would like to support textDocument/prepareCodeAction
but don't support the literals.