Skip to content

Commit 4eb65f9

Browse files
committed
Split codeActonController to own file
1 parent fe01a19 commit 4eb65f9

6 files changed

Lines changed: 164 additions & 150 deletions

File tree

src/vs/editor/contrib/codeAction/codeAction.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { ITextModel } from 'vs/editor/common/model';
1414
import { CodeAction, CodeActionContext, CodeActionProviderRegistry, CodeActionTrigger as CodeActionTriggerKind } from 'vs/editor/common/modes';
1515
import { IModelService } from 'vs/editor/common/services/modelService';
1616
import { CodeActionKind, CodeActionTrigger, filtersAction, mayIncludeActionsOfKind, CodeActionFilter } from './codeActionTrigger';
17+
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
18+
import { ICommandService } from 'vs/platform/commands/common/commands';
19+
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
1720

1821
export function getCodeActions(
1922
model: ITextModel,
@@ -78,6 +81,21 @@ function codeActionsComparator(a: CodeAction, b: CodeAction): number {
7881
}
7982
}
8083

84+
export async function applyCodeAction(
85+
action: CodeAction,
86+
bulkEditService: IBulkEditService,
87+
commandService: ICommandService,
88+
editor?: ICodeEditor,
89+
): Promise<void> {
90+
if (action.edit) {
91+
await bulkEditService.apply(action.edit, { editor });
92+
}
93+
if (action.command) {
94+
await commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
95+
}
96+
}
97+
98+
8199
registerLanguageCommand('_executeCodeActionProvider', function (accessor, args) {
82100
const { resource, range, kind } = args;
83101
if (!(resource instanceof URI) || !Range.isIRange(range)) {

src/vs/editor/contrib/codeAction/codeActionCommands.ts

Lines changed: 5 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -3,163 +3,25 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { CancelablePromise } from 'vs/base/common/async';
76
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
8-
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
97
import { escapeRegExpCharacters } from 'vs/base/common/strings';
108
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
119
import { EditorAction, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
12-
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
13-
import { IEditorContribution } from 'vs/editor/common/editorCommon';
1410
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
15-
import { CodeAction } from 'vs/editor/common/modes';
1611
import { MessageController } from 'vs/editor/contrib/message/messageController';
1712
import * as nls from 'vs/nls';
18-
import { ICommandService } from 'vs/platform/commands/common/commands';
19-
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
20-
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
21-
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
22-
import { IMarkerService } from 'vs/platform/markers/common/markers';
23-
import { IProgressService } from 'vs/platform/progress/common/progress';
24-
import { CodeActionModel, SUPPORTED_CODE_ACTIONS, CodeActionsState } from './codeActionModel';
25-
import { CodeActionAutoApply, CodeActionFilter, CodeActionKind } from './codeActionTrigger';
26-
import { CodeActionContextMenu } from './codeActionWidget';
27-
import { LightBulbWidget } from './lightBulbWidget';
13+
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
2814
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
29-
import { onUnexpectedError } from 'vs/base/common/errors';
15+
import { CodeActionController } from './codeActionController';
16+
import { SUPPORTED_CODE_ACTIONS } from './codeActionModel';
17+
import { CodeActionAutoApply, CodeActionFilter, CodeActionKind } from './codeActionTrigger';
3018

3119
function contextKeyForSupportedActions(kind: CodeActionKind) {
3220
return ContextKeyExpr.regex(
3321
SUPPORTED_CODE_ACTIONS.keys()[0],
3422
new RegExp('(\\s|^)' + escapeRegExpCharacters(kind.value) + '\\b'));
3523
}
3624

37-
export class QuickFixController implements IEditorContribution {
38-
39-
private static readonly ID = 'editor.contrib.quickFixController';
40-
41-
public static get(editor: ICodeEditor): QuickFixController {
42-
return editor.getContribution<QuickFixController>(QuickFixController.ID);
43-
}
44-
45-
private _editor: ICodeEditor;
46-
private _model: CodeActionModel;
47-
private _codeActionContextMenu: CodeActionContextMenu;
48-
private _lightBulbWidget: LightBulbWidget;
49-
private _disposables: IDisposable[] = [];
50-
51-
private _activeRequest: CancelablePromise<CodeAction[]> | undefined;
52-
53-
constructor(editor: ICodeEditor,
54-
@IMarkerService markerService: IMarkerService,
55-
@IContextKeyService contextKeyService: IContextKeyService,
56-
@IProgressService progressService: IProgressService,
57-
@IContextMenuService contextMenuService: IContextMenuService,
58-
@ICommandService private readonly _commandService: ICommandService,
59-
@IKeybindingService private readonly _keybindingService: IKeybindingService,
60-
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
61-
) {
62-
this._editor = editor;
63-
this._model = new CodeActionModel(this._editor, markerService, contextKeyService, progressService);
64-
this._codeActionContextMenu = new CodeActionContextMenu(editor, contextMenuService, action => this._onApplyCodeAction(action));
65-
this._lightBulbWidget = new LightBulbWidget(editor);
66-
67-
this._updateLightBulbTitle();
68-
69-
this._disposables.push(
70-
this._codeActionContextMenu.onDidExecuteCodeAction(_ => this._model.trigger({ type: 'auto', filter: {} })),
71-
this._lightBulbWidget.onClick(this._handleLightBulbSelect, this),
72-
this._model.onDidChangeState(e => this._onDidChangeCodeActionsState(e)),
73-
this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this)
74-
);
75-
}
76-
77-
public dispose(): void {
78-
this._model.dispose();
79-
dispose(this._disposables);
80-
}
81-
82-
private _onDidChangeCodeActionsState(newState: CodeActionsState.State): void {
83-
if (this._activeRequest) {
84-
this._activeRequest.cancel();
85-
this._activeRequest = undefined;
86-
}
87-
88-
if (newState.type === CodeActionsState.Type.Triggered) {
89-
this._activeRequest = newState.actions;
90-
91-
if (newState.trigger.filter && newState.trigger.filter.kind) {
92-
// Triggered for specific scope
93-
newState.actions.then(fixes => {
94-
if (fixes.length > 0) {
95-
// Apply if we only have one action or requested autoApply
96-
if (newState.trigger.autoApply === CodeActionAutoApply.First || (newState.trigger.autoApply === CodeActionAutoApply.IfSingle && fixes.length === 1)) {
97-
this._onApplyCodeAction(fixes[0]);
98-
return;
99-
}
100-
}
101-
this._codeActionContextMenu.show(newState.actions, newState.position);
102-
103-
}).catch(onUnexpectedError);
104-
} else if (newState.trigger.type === 'manual') {
105-
this._codeActionContextMenu.show(newState.actions, newState.position);
106-
} else {
107-
// auto magically triggered
108-
// * update an existing list of code actions
109-
// * manage light bulb
110-
if (this._codeActionContextMenu.isVisible) {
111-
this._codeActionContextMenu.show(newState.actions, newState.position);
112-
} else {
113-
this._lightBulbWidget.tryShow(newState);
114-
}
115-
}
116-
} else {
117-
this._lightBulbWidget.hide();
118-
}
119-
}
120-
121-
public getId(): string {
122-
return QuickFixController.ID;
123-
}
124-
125-
private _handleLightBulbSelect(e: { x: number, y: number, state: CodeActionsState.Triggered }): void {
126-
this._codeActionContextMenu.show(e.state.actions, e);
127-
}
128-
129-
public triggerFromEditorSelection(filter?: CodeActionFilter, autoApply?: CodeActionAutoApply): Promise<CodeAction[] | undefined> {
130-
return this._model.trigger({ type: 'manual', filter, autoApply });
131-
}
132-
133-
private _updateLightBulbTitle(): void {
134-
const kb = this._keybindingService.lookupKeybinding(QuickFixAction.Id);
135-
let title: string;
136-
if (kb) {
137-
title = nls.localize('quickFixWithKb', "Show Fixes ({0})", kb.getLabel());
138-
} else {
139-
title = nls.localize('quickFix', "Show Fixes");
140-
}
141-
this._lightBulbWidget.title = title;
142-
}
143-
144-
private _onApplyCodeAction(action: CodeAction): Promise<void> {
145-
return applyCodeAction(action, this._bulkEditService, this._commandService, this._editor);
146-
}
147-
}
148-
149-
export async function applyCodeAction(
150-
action: CodeAction,
151-
bulkEditService: IBulkEditService,
152-
commandService: ICommandService,
153-
editor?: ICodeEditor,
154-
): Promise<void> {
155-
if (action.edit) {
156-
await bulkEditService.apply(action.edit, { editor });
157-
}
158-
if (action.command) {
159-
await commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
160-
}
161-
}
162-
16325
function showCodeActionsForEditorSelection(
16426
editor: ICodeEditor,
16527
notAvailableMessage: string,
@@ -170,7 +32,7 @@ function showCodeActionsForEditorSelection(
17032
return;
17133
}
17234

173-
const controller = QuickFixController.get(editor);
35+
const controller = CodeActionController.get(editor);
17436
if (!controller) {
17537
return;
17638
}

src/vs/editor/contrib/codeAction/codeActionContributions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
7-
import { CodeActionCommand, OrganizeImportsAction, QuickFixAction, QuickFixController, RefactorAction, SourceAction, AutoFixAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
7+
import { CodeActionCommand, OrganizeImportsAction, QuickFixAction, RefactorAction, SourceAction, AutoFixAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
8+
import { CodeActionController } from 'vs/editor/contrib/codeAction/codeActionController';
89

9-
10-
registerEditorContribution(QuickFixController);
10+
registerEditorContribution(CodeActionController);
1111
registerEditorAction(QuickFixAction);
1212
registerEditorAction(RefactorAction);
1313
registerEditorAction(SourceAction);
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import { CancelablePromise } from 'vs/base/common/async';
6+
import { onUnexpectedError } from 'vs/base/common/errors';
7+
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
8+
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
9+
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
10+
import { IEditorContribution } from 'vs/editor/common/editorCommon';
11+
import { CodeAction } from 'vs/editor/common/modes';
12+
import * as nls from 'vs/nls';
13+
import { ICommandService } from 'vs/platform/commands/common/commands';
14+
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
15+
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
16+
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
17+
import { IMarkerService } from 'vs/platform/markers/common/markers';
18+
import { IProgressService } from 'vs/platform/progress/common/progress';
19+
import { QuickFixAction } from './codeActionCommands';
20+
import { CodeActionModel, CodeActionsState } from './codeActionModel';
21+
import { CodeActionAutoApply, CodeActionFilter } from './codeActionTrigger';
22+
import { CodeActionContextMenu } from './codeActionWidget';
23+
import { LightBulbWidget } from './lightBulbWidget';
24+
import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeAction';
25+
26+
export class CodeActionController implements IEditorContribution {
27+
28+
private static readonly ID = 'editor.contrib.quickFixController';
29+
30+
public static get(editor: ICodeEditor): CodeActionController {
31+
return editor.getContribution<CodeActionController>(CodeActionController.ID);
32+
}
33+
34+
private _editor: ICodeEditor;
35+
private _model: CodeActionModel;
36+
private _codeActionContextMenu: CodeActionContextMenu;
37+
private _lightBulbWidget: LightBulbWidget;
38+
private _disposables: IDisposable[] = [];
39+
40+
private _activeRequest: CancelablePromise<CodeAction[]> | undefined;
41+
42+
constructor(editor: ICodeEditor,
43+
@IMarkerService markerService: IMarkerService,
44+
@IContextKeyService contextKeyService: IContextKeyService,
45+
@IProgressService progressService: IProgressService,
46+
@IContextMenuService contextMenuService: IContextMenuService,
47+
@ICommandService private readonly _commandService: ICommandService,
48+
@IKeybindingService private readonly _keybindingService: IKeybindingService,
49+
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
50+
) {
51+
this._editor = editor;
52+
this._model = new CodeActionModel(this._editor, markerService, contextKeyService, progressService);
53+
this._codeActionContextMenu = new CodeActionContextMenu(editor, contextMenuService, action => this._onApplyCodeAction(action));
54+
this._lightBulbWidget = new LightBulbWidget(editor);
55+
56+
this._updateLightBulbTitle();
57+
58+
this._disposables.push(
59+
this._codeActionContextMenu.onDidExecuteCodeAction(_ => this._model.trigger({ type: 'auto', filter: {} })),
60+
this._lightBulbWidget.onClick(this._handleLightBulbSelect, this),
61+
this._model.onDidChangeState(e => this._onDidChangeCodeActionsState(e)),
62+
this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this)
63+
);
64+
}
65+
66+
public dispose(): void {
67+
this._model.dispose();
68+
dispose(this._disposables);
69+
}
70+
71+
private _onDidChangeCodeActionsState(newState: CodeActionsState.State): void {
72+
if (this._activeRequest) {
73+
this._activeRequest.cancel();
74+
this._activeRequest = undefined;
75+
}
76+
77+
if (newState.type === CodeActionsState.Type.Triggered) {
78+
this._activeRequest = newState.actions;
79+
80+
if (newState.trigger.filter && newState.trigger.filter.kind) {
81+
// Triggered for specific scope
82+
newState.actions.then(fixes => {
83+
if (fixes.length > 0) {
84+
// Apply if we only have one action or requested autoApply
85+
if (newState.trigger.autoApply === CodeActionAutoApply.First || (newState.trigger.autoApply === CodeActionAutoApply.IfSingle && fixes.length === 1)) {
86+
this._onApplyCodeAction(fixes[0]);
87+
return;
88+
}
89+
}
90+
this._codeActionContextMenu.show(newState.actions, newState.position);
91+
92+
}).catch(onUnexpectedError);
93+
} else if (newState.trigger.type === 'manual') {
94+
this._codeActionContextMenu.show(newState.actions, newState.position);
95+
} else {
96+
// auto magically triggered
97+
// * update an existing list of code actions
98+
// * manage light bulb
99+
if (this._codeActionContextMenu.isVisible) {
100+
this._codeActionContextMenu.show(newState.actions, newState.position);
101+
} else {
102+
this._lightBulbWidget.tryShow(newState);
103+
}
104+
}
105+
} else {
106+
this._lightBulbWidget.hide();
107+
}
108+
}
109+
110+
public getId(): string {
111+
return CodeActionController.ID;
112+
}
113+
114+
private _handleLightBulbSelect(e: { x: number, y: number, state: CodeActionsState.Triggered }): void {
115+
this._codeActionContextMenu.show(e.state.actions, e);
116+
}
117+
118+
public triggerFromEditorSelection(filter?: CodeActionFilter, autoApply?: CodeActionAutoApply): Promise<CodeAction[] | undefined> {
119+
return this._model.trigger({ type: 'manual', filter, autoApply });
120+
}
121+
122+
private _updateLightBulbTitle(): void {
123+
const kb = this._keybindingService.lookupKeybinding(QuickFixAction.Id);
124+
let title: string;
125+
if (kb) {
126+
title = nls.localize('quickFixWithKb', "Show Fixes ({0})", kb.getLabel());
127+
} else {
128+
title = nls.localize('quickFix', "Show Fixes");
129+
}
130+
this._lightBulbWidget.title = title;
131+
}
132+
133+
private _onApplyCodeAction(action: CodeAction): Promise<void> {
134+
return applyCodeAction(action, this._bulkEditService, this._commandService, this._editor);
135+
}
136+
}

src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ import { IIdentifiedSingleEditOperation, ISingleEditOperation, ITextModel } from
2020
import { CodeAction } from 'vs/editor/common/modes';
2121
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
2222
import { shouldSynchronizeModel } from 'vs/editor/common/services/modelService';
23-
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
24-
import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
23+
import { getCodeActions, applyCodeAction } from 'vs/editor/contrib/codeAction/codeAction';
2524
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
2625
import { getDocumentFormattingEdits, FormatMode } from 'vs/editor/contrib/format/format';
2726
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';

src/vs/workbench/contrib/markers/electron-browser/markersTreeViewer.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@ import { fillResourceDataTransfers } from 'vs/workbench/browser/dnd';
3636
import { CancelablePromise, createCancelablePromise, Delayer } from 'vs/base/common/async';
3737
import { IModelService } from 'vs/editor/common/services/modelService';
3838
import { Range } from 'vs/editor/common/core/range';
39-
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
39+
import { getCodeActions, applyCodeAction } from 'vs/editor/contrib/codeAction/codeAction';
4040
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
4141
import { ITextModel } from 'vs/editor/common/model';
4242
import { CodeAction } from 'vs/editor/common/modes';
4343
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
4444
import { ICommandService } from 'vs/platform/commands/common/commands';
4545
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
46-
import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
4746

4847
export type TreeElement = ResourceMarkers | Marker | RelatedInformation;
4948

0 commit comments

Comments
 (0)