Skip to content

[Api] Auto fix on save and fix all #62110

@mjbvz

Description

@mjbvz

(edit: see here for a more recent proposal. Original proposal below)

Problem

ES Lint, TS Lint, and other extensions have the concept of auto fix on save. On save, this goes through the errors file and fixes all simple ones, such as removing tailing whitespace or converting { x: string } to Array<{ x: string }>. This functionality is quite useful but is currently implemented per extension. It would be nice if we could:

  • Control auto fix on save with a single setting.
  • Indicate auto fixes in the code action context menu (since these are usually the preferred fixes)
  • Bind auto fix to a keyboard shortcut

Related
Many extensions implement a fix all of this type code action / quick fix. This can be viewed as a special case of auto fix on save where the candidate fixes are only of a single type.

Sketches

(Note that the sketch below record some of the options being considered for this API. They are not yet concrete proposals)


Do nothing

Keep things as is. Let extensions handle this all individually

Benefits

  • No work! (unless we maybe try to establish some sort of convention for extensions to follow)

Drawbacks

  • Many different ways of implementing the same thing
  • Cannot bring auto fix or fix all into UI in a consistent way
  • Cannot support things that require standardization, such as keybindings or commands

CodeAction.autoFixable

Add an autoFixable flag to CodeAction

class CodeAction {
    ...

   autoFixable?: boolean;
}

Use this flag to determine which code actions should be applied on save.

Introduce a editor.autoFixOnSave setting to enable or disable auto fix on save

Implementing auto fix on save

  1. For every diagnostic in a file
  2. Request all code actions for that diagnostic.
  3. If there are is only one code action marked autoFixable in the set, then apply that code action

Implementing auto fix all errors of type X

  1. Assuming we have UI that shows a auto fix all errors of type X suggestion .
  2. For each diagnostic of type X in the file, request code actions.
  3. Filter to only those that CodeAction.diagnostics set to include the diagnostic of type X.
  4. Then, if we only have one code action left for that diagnostic, apply it.

Maybe autoFixable here should actually be an array of diagnostics? Would that help with filtering.

Benefits

  • Theoretically this lets us address all requirements (perhaps with a few api tweaks)

Drawbacks / Open questions

  • Supper chatty api
  • Not easy to handle recursive or overlapping fixes

CodeActionKind.SourceAutoFix

Add a new code action kind called source.autoFix. Update extensions to return a source code action that fixes all auto fixable errors in the file.

Use "editor.sourceActionsOnSave": ["source.autoFix"] to apply code actions on save

Implementing auto fix on save
Basically no work on VS Code side. Get extensions to adopt this new API.

Implementing auto fix all errors of type X
We could do something like have multiple source code actions for autofix, such as:

  • source.autoFix.123
  • source.autoFix.456

This may gets confusing though since requesting the code actions for source.autoFix would end up including the source code actions of source.autoFix.123 and source.autoFix.456 unless the extension is smart. Maybe we'd have to have a source.autoFix.all to prevent this for the autofix on save case? Or perhaps it doesn't matter? If editor.sourceActionsOnSave applies all actions of source.autoFix, presumably applying source.autoFix.123 and source.autoFix.456 should work?

Benefits

  • Easy to implement
  • Allows extensions to compute a batch of edits
  • "editor.sourceActionsOnSave": ["source.autoFix"]

Drawbacks / Open questions

  • What happens if multiple extensions contribute fix all actions? With current proposal, the source code menu would just show an fix all action for each extension. Would be nice if we just have one entry (autofix on save may still work though, at least as long as the fixes don't overlap)
  • Can we actually implement auto fix all errors of type X?
  • Is there any standard way to surface autofix in the UI with this proposal?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions