Skip to content

CodeAction.disabled #85160

Closed
Closed
@mjbvz

Description

@mjbvz

Problems

A user selects some text in a JS file and tries to run extract constant (though a keyboard shortcut). The selected text is not extractable. However, there is currently no feedback in the editor about why the selected text could not be extracted.

Also, unless the already user know that JS/TS supports extract constant, they may never discover this refactoring exists at all; it will only show up in the refactor menu when the current selection is extractable.

Desired UX

  • If the user explicitly requests to apply a refactoring that cannot be applied (such as extract constant for an invalid selection) let extensions surface a human readable error message describing why the refactoring cannot be applied.

  • Provide a way for extensions to show refactorings that they support but are currently not supported in the refactor menu. This would help users understand what refactorings are available, while also seeing that those refactorings are not possible (ideally we'd also find a way to surface the error message here too)

Proposal

With microsoft/TypeScript#35098, we are requesting that TypeScript return the reason why a given JS/TS refactoring is not possible. This issue tracks the VS Code side API required and how information from this new API would be surfaced to users.

My API proposal is to let extensions set an disabled property on the code actions they return:

export class CodeAction {
	...

	disabled?: {
		/**
		 * Human readable description of why the code action is currently disabled.
		 *
		 * This is displayed in the UI.
		 */
		reason: string;
	};
}

I propose including .disabled on the CodeAction class because it would let us reuse the existing code action metadata (title, kind, ...) without having to introduce new classes (such as InvalidCodeAction)

How .disabled would be surfaced to users

Lightbulb menu

This automatic lightbulb menu would drop all error code actions. It would likely be overwhelming to show them all.

I like keeping the lightbulb as showing: here is everything that is possible right now.

Keybinding for code action

There are a few cases here:

  • All returned code actions for the keybinding are errors.

    If the user has enabled apply as part of the keybinding, in this case we would want to show the .error from the code action that would have been applied if it were valid.

  • A mix of error and valid actions are returned, and the user has not selected to apply the code actions.

    Here we would want to show a full list of actions, including the invalid actions disabled.

  • A mix of code error and valid actions are returned, and the user has selected to apply code actions.

    We would apply the code actions as if the error code actions were not there. For example, use "apply": "ifOnly" would apply the valid code action if it is the only valid code action (ignoring the errored ones)

Refactoring menu

We'd show the errored actions in the refactoring menu but as disabled. The goal of this is to improve discoverability.

With the current proposal it would be up to extensions to say which code actions they return in the error state and which ones they simply drop. For example, it may be overwhelming if JS/TS to showed all of its refactorings in the refactor menu all the time (including rarely used ones such as rewrite export). Instead, for the generic code action menu, JS/TS would likely always return the most common actions (such as extract constant) either in a valid or in an error state

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions