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' ;
76import { KeyCode , KeyMod } from 'vs/base/common/keyCodes' ;
8- import { dispose , IDisposable } from 'vs/base/common/lifecycle' ;
97import { escapeRegExpCharacters } from 'vs/base/common/strings' ;
108import { ICodeEditor } from 'vs/editor/browser/editorBrowser' ;
119import { 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' ;
1410import { EditorContextKeys } from 'vs/editor/common/editorContextKeys' ;
15- import { CodeAction } from 'vs/editor/common/modes' ;
1611import { MessageController } from 'vs/editor/contrib/message/messageController' ;
1712import * 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' ;
2814import { 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
3119function 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-
16325function 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 }
0 commit comments