33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6+ import { IAnchor } from 'vs/base/browser/ui/contextview/contextview' ;
7+ import { find } from 'vs/base/common/arrays' ;
68import { onUnexpectedError } from 'vs/base/common/errors' ;
9+ import { Lazy } from 'vs/base/common/lazy' ;
710import { Disposable , MutableDisposable } from 'vs/base/common/lifecycle' ;
811import { ICodeEditor } from 'vs/editor/browser/editorBrowser' ;
12+ import { IPosition } from 'vs/editor/common/core/position' ;
913import { CodeAction } from 'vs/editor/common/modes' ;
1014import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction' ;
1115import { MessageController } from 'vs/editor/contrib/message/messageController' ;
1216import { IContextMenuService } from 'vs/platform/contextview/browser/contextView' ;
1317import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
1418import { CodeActionsState } from './codeActionModel' ;
15- import { CodeActionAutoApply } from './types' ;
1619import { CodeActionWidget } from './codeActionWidget' ;
1720import { LightBulbWidget } from './lightBulbWidget' ;
18- import { IPosition } from 'vs/editor/common/core/position' ;
19- import { IAnchor } from 'vs/base/browser/ui/contextview/contextview' ;
20- import { Lazy } from 'vs/base/common/lazy' ;
21+ import { CodeActionAutoApply , CodeActionTrigger } from './types' ;
2122
2223export class CodeActionUi extends Disposable {
2324
@@ -68,26 +69,37 @@ export class CodeActionUi extends Disposable {
6869
6970 this . _lightBulbWidget . getValue ( ) . update ( actions , newState . position ) ;
7071
71- if ( ! actions . validActions . length && newState . trigger . context ) {
72+ if ( ! actions . allActions . length && newState . trigger . context ) {
7273 MessageController . get ( this . _editor ) . showMessage ( newState . trigger . context . notAvailableMessage , newState . trigger . context . position ) ;
7374 this . _activeCodeActions . value = actions ;
7475 return ;
7576 }
7677
7778 if ( newState . trigger . type === 'manual' ) {
7879 if ( newState . trigger . filter ?. include ) { // Triggered for specific scope
79- if ( actions . validActions . length > 0 ) {
80- // Apply if we only have one action or requested autoApply
81- if ( newState . trigger . autoApply === CodeActionAutoApply . First || ( newState . trigger . autoApply === CodeActionAutoApply . IfSingle && actions . validActions . length === 1 ) ) {
82- try {
83- await this . delegate . applyCodeAction ( actions . validActions [ 0 ] , false ) ;
84- } finally {
85- actions . dispose ( ) ;
86- }
80+ // Check to see if we want to auto apply.
81+
82+ const validActionToApply = this . tryGetValidActionToApply ( newState . trigger , actions ) ;
83+ if ( validActionToApply ) {
84+ try {
85+ await this . delegate . applyCodeAction ( validActionToApply , false ) ;
86+ } finally {
87+ actions . dispose ( ) ;
88+ }
89+ return ;
90+ }
91+
92+ // Check to see if there is an action that we would have applied were it not invalid
93+ if ( newState . trigger . context ) {
94+ const invalidAction = this . getInvalidActionThatWouldHaveBeenApplied ( newState . trigger , actions ) ;
95+ if ( invalidAction && invalidAction . disabled ) {
96+ MessageController . get ( this . _editor ) . showMessage ( invalidAction . disabled , newState . trigger . context . position ) ;
97+ actions . dispose ( ) ;
8798 return ;
8899 }
89100 }
90101 }
102+
91103 this . _activeCodeActions . value = actions ;
92104 this . _codeActionWidget . getValue ( ) . show ( actions , newState . position ) ;
93105 } else {
@@ -101,6 +113,34 @@ export class CodeActionUi extends Disposable {
101113 }
102114 }
103115
116+ private getInvalidActionThatWouldHaveBeenApplied ( trigger : CodeActionTrigger , actions : CodeActionSet ) : CodeAction | undefined {
117+ if ( ! actions . allActions . length ) {
118+ return undefined ;
119+ }
120+
121+ if ( ( trigger . autoApply === CodeActionAutoApply . First && actions . validActions . length === 0 )
122+ || ( trigger . autoApply === CodeActionAutoApply . IfSingle && actions . allActions . length === 1 )
123+ ) {
124+ return find ( actions . allActions , action => action . disabled ) ;
125+ }
126+
127+ return undefined ;
128+ }
129+
130+ private tryGetValidActionToApply ( trigger : CodeActionTrigger , actions : CodeActionSet ) : CodeAction | undefined {
131+ if ( ! actions . validActions . length ) {
132+ return undefined ;
133+ }
134+
135+ if ( ( trigger . autoApply === CodeActionAutoApply . First && actions . validActions . length > 0 )
136+ || ( trigger . autoApply === CodeActionAutoApply . IfSingle && actions . validActions . length === 1 )
137+ ) {
138+ return actions . validActions [ 0 ] ;
139+ }
140+
141+ return undefined ;
142+ }
143+
104144 public async showCodeActionList ( actions : CodeActionSet , at : IAnchor | IPosition ) : Promise < void > {
105145 this . _codeActionWidget . getValue ( ) . show ( actions , at ) ;
106146 }
0 commit comments