Skip to content

Proposal: textDocument/prepareCodeAction #1386

Open
@AmadeusW

Description

@AmadeusW

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.

image image image
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 CodeActionKinds 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. If null is returned then it is deemed that textDocument/codeAction request is not valid at the given range, and textDocument/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 TextEdits 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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions