diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index f06706b7a4139ab39811d0156e8fbfb8a1b8616b..0b4fa587ec0d5e0a306787923fdd7f32d2d8ceeb 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -240,7 +240,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { const results = new CodeActionSet(); for (const tsCodeFix of response.body) { - this.addAllFixesForTsCodeAction(results, document, file, diagnostic, tsCodeFix); + this.addAllFixesForTsCodeAction(results, document, file, diagnostic, tsCodeFix as Proto.CodeFixAction); } return results.values; } @@ -250,7 +250,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { document: vscode.TextDocument, file: string, diagnostic: vscode.Diagnostic, - tsAction: Proto.CodeAction + tsAction: Proto.CodeFixAction ): CodeActionSet { results.addAction(this.getSingleFixForTsCodeAction(diagnostic, tsAction)); this.addFixAllForTsCodeAction(results, document, file, diagnostic, tsAction as Proto.CodeFixAction); @@ -259,7 +259,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { private getSingleFixForTsCodeAction( diagnostic: vscode.Diagnostic, - tsAction: Proto.CodeAction + tsAction: Proto.CodeFixAction ): vscode.CodeAction { const codeAction = new vscode.CodeAction(tsAction.description, vscode.CodeActionKind.QuickFix); codeAction.edit = getEditForCodeAction(this.client, tsAction); @@ -269,6 +269,9 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { arguments: [tsAction], title: '' }; + if (tsAction.fixName === 'spelling') { + codeAction.canAutoApply = true; + } return codeAction; } diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 55581b24c795c80be02743bae699aff9ef4e984d..80eb6e5d05792771c24381983cb82dd1fe30502f 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -516,6 +516,7 @@ export interface CodeAction { edit?: WorkspaceEdit; diagnostics?: IMarkerData[]; kind?: string; + canAutoApply?: boolean; } /** diff --git a/src/vs/editor/contrib/codeAction/codeAction.ts b/src/vs/editor/contrib/codeAction/codeAction.ts index ee8ecbb90480feef51481c80b19603a706838b50..8d012d07be3347f30d978800a5ae8b2c234136d8 100644 --- a/src/vs/editor/contrib/codeAction/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/codeAction.ts @@ -15,7 +15,12 @@ import { CodeAction, CodeActionContext, CodeActionProviderRegistry, CodeActionTr import { IModelService } from 'vs/editor/common/services/modelService'; import { CodeActionFilter, CodeActionKind, CodeActionTrigger } from './codeActionTrigger'; -export function getCodeActions(model: ITextModel, rangeOrSelection: Range | Selection, trigger?: CodeActionTrigger, token: CancellationToken = CancellationToken.None): Promise { +export function getCodeActions( + model: ITextModel, + rangeOrSelection: Range | Selection, + trigger?: CodeActionTrigger, + token: CancellationToken = CancellationToken.None +): Promise { const codeActionContext: CodeActionContext = { only: trigger && trigger.filter && trigger.filter.kind ? trigger.filter.kind.value : undefined, trigger: trigger && trigger.type === 'manual' ? CodeActionTriggerKind.Manual : CodeActionTriggerKind.Automatic @@ -65,7 +70,9 @@ export function getCodeActions(model: ITextModel, rangeOrSelection: Range | Sele } function isValidAction(filter: CodeActionFilter | undefined, action: CodeAction): boolean { - return action && isValidActionKind(filter, action.kind); + return action + && isValidActionKind(filter, action.kind) + && (filter && filter.autoFixesOnly ? !!action.canAutoApply : true); } function isValidActionKind(filter: CodeActionFilter | undefined, kind: string | undefined): boolean { diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 14acb6ee5b63be9f709517e3473291dd72c516a7..072d6b4ea58fdf7bddbc51f0b62147cceac21e9d 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -358,3 +358,31 @@ export class OrganizeImportsAction extends EditorAction { CodeActionAutoApply.IfSingle); } } + +export class AutoFixAction extends EditorAction { + + static readonly Id = 'editor.action.autoFix'; + + constructor() { + super({ + id: AutoFixAction.Id, + label: nls.localize('autoFix.label', "Auto Fix"), + alias: 'Auto Fix', + precondition: ContextKeyExpr.and( + EditorContextKeys.writable, + contextKeyForSupportedActions(CodeActionKind.QuickFix)), + kbOpts: { + kbExpr: EditorContextKeys.editorTextFocus, + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.US_DOT, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(_accessor: ServicesAccessor, editor: ICodeEditor): void { + return showCodeActionsForEditorSelection(editor, + nls.localize('editor.action.autoFix.noneMessage', "No auto fixes available"), + { kind: CodeActionKind.QuickFix, autoFixesOnly: true }, + CodeActionAutoApply.IfSingle); + } +} diff --git a/src/vs/editor/contrib/codeAction/codeActionContributions.ts b/src/vs/editor/contrib/codeAction/codeActionContributions.ts index 4f7315db0f83094763ae9ca6997007983b4c8ae0..7a022b495b4f67844a0186561baf59dc7e167aff 100644 --- a/src/vs/editor/contrib/codeAction/codeActionContributions.ts +++ b/src/vs/editor/contrib/codeAction/codeActionContributions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { CodeActionCommand, OrganizeImportsAction, QuickFixAction, QuickFixController, RefactorAction, SourceAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; +import { CodeActionCommand, OrganizeImportsAction, QuickFixAction, QuickFixController, RefactorAction, SourceAction, AutoFixAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; registerEditorContribution(QuickFixController); @@ -12,4 +12,5 @@ registerEditorAction(QuickFixAction); registerEditorAction(RefactorAction); registerEditorAction(SourceAction); registerEditorAction(OrganizeImportsAction); +registerEditorAction(AutoFixAction); registerEditorCommand(new CodeActionCommand()); diff --git a/src/vs/editor/contrib/codeAction/codeActionTrigger.ts b/src/vs/editor/contrib/codeAction/codeActionTrigger.ts index b8ed8cde8fc3ca8a5a3da80331099b0e549cca8d..ad1bbfe85b1449eaedb2cd298b20b383fcd5dce9 100644 --- a/src/vs/editor/contrib/codeAction/codeActionTrigger.ts +++ b/src/vs/editor/contrib/codeAction/codeActionTrigger.ts @@ -32,6 +32,7 @@ export const enum CodeActionAutoApply { export interface CodeActionFilter { readonly kind?: CodeActionKind; readonly includeSourceActions?: boolean; + readonly autoFixesOnly?: boolean; } export interface CodeActionTrigger { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 4ec47e159d8cfed960aa0effc0c0e6198e565a3b..0cd4c9504fdba9b14cac9580312f743be3155cd9 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4848,6 +4848,7 @@ declare namespace monaco.languages { edit?: WorkspaceEdit; diagnostics?: editor.IMarkerData[]; kind?: string; + canAutoApply?: boolean; } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index edbf4b240fa2a7547b2d608bbd770b65d594601b..f659d20660c488d80cc634d567d72b1e6460f2c9 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1098,4 +1098,17 @@ declare module 'vscode' { readonly activeSignatureHelp?: SignatureHelp; } //#endregion + + //#region CodeAction.canAutoApply - mjbvz + export interface CodeAction { + /** + * If the action can be safely automatically applied without the user selecting it from a list. + * + * Set this on quick fixes to indicate that the fix properly addresses the underlying error. + */ + canAutoApply?: boolean; + } + //#endregion + + } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 08baa7337110dcf0395da2331ad06f272a2d5c27..7ecd69fcb54cda7ad621634681bfc7dfef40474c 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -864,6 +864,7 @@ export interface CodeActionDto { diagnostics?: IMarkerData[]; command?: modes.Command; kind?: string; + canAutoApply?: boolean; } export interface ExtHostLanguageFeaturesShape { diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 0801f8f05d9303ad56d9fe704534994b9627480c..df6512c9b6b2030413ae339a13d6466bc358371f 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -342,7 +342,8 @@ class CodeActionAdapter { command: candidate.command && this._commands.toInternal(candidate.command), diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from), edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit), - kind: candidate.kind && candidate.kind.value + kind: candidate.kind && candidate.kind.value, + canAutoApply: candidate.canAutoApply, }); } }