(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
- For every diagnostic in a file
- Request all code actions for that diagnostic.
- 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
- Assuming we have UI that shows a
auto fix all errors of type X suggestion .
- For each diagnostic of type
X in the file, request code actions.
- Filter to only those that
CodeAction.diagnostics set to include the diagnostic of type X.
- 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?
(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 }toArray<{ x: string }>. This functionality is quite useful but is currently implemented per extension. It would be nice if we could:Related
Many extensions implement a
fix all of this typecode action / quick fix. This can be viewed as a special case ofauto fix on savewhere 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
Drawbacks
CodeAction.autoFixableAdd an
autoFixableflag toCodeActionUse this flag to determine which code actions should be applied on save.
Introduce a
editor.autoFixOnSavesetting to enable or disable auto fix on saveImplementing
auto fix on saveautoFixablein the set, then apply that code actionImplementing
auto fix all errors of type Xauto fix all errors of type Xsuggestion .Xin the file, request code actions.CodeAction.diagnosticsset to include the diagnostic of typeX.Maybe
autoFixablehere should actually be an array of diagnostics? Would that help with filtering.Benefits
Drawbacks / Open questions
CodeActionKind.SourceAutoFixAdd 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 saveImplementing
auto fix on saveBasically no work on VS Code side. Get extensions to adopt this new API.
Implementing
auto fix all errors of type XWe could do something like have multiple source code actions for autofix, such as:
source.autoFix.123source.autoFix.456This may gets confusing though since requesting the code actions for
source.autoFixwould end up including the source code actions ofsource.autoFix.123andsource.autoFix.456unless the extension is smart. Maybe we'd have to have asource.autoFix.allto prevent this for the autofix on save case? Or perhaps it doesn't matter? Ifeditor.sourceActionsOnSaveapplies all actions ofsource.autoFix, presumably applyingsource.autoFix.123andsource.autoFix.456should work?Benefits
"editor.sourceActionsOnSave": ["source.autoFix"]Drawbacks / Open questions
fix allactions? With current proposal, the source code menu would just show anfix allaction 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)auto fix all errors of type X?autofixin the UI with this proposal?