@@ -8,6 +8,7 @@ import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
8
8
import { IJSONSchema , IJSONSchemaMap } from 'vs/base/common/jsonSchema' ;
9
9
import { Disposable } from 'vs/base/common/lifecycle' ;
10
10
import { editorConfigurationBaseNode } from 'vs/editor/common/config/editorConfigurationSchema' ;
11
+ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures' ;
11
12
import { codeActionCommandId , refactorCommandId , sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction' ;
12
13
import { CodeActionKind } from 'vs/editor/contrib/codeAction/common/types' ;
13
14
import * as nls from 'vs/nls' ;
@@ -34,15 +35,11 @@ const createCodeActionsAutoSave = (description: string): IJSONSchema => {
34
35
} ;
35
36
} ;
36
37
37
- const codeActionsOnSaveDefaultProperties = Object . freeze < IJSONSchemaMap > ( {
38
- 'source.fixAll' : createCodeActionsAutoSave ( nls . localize ( 'codeActionsOnSave.fixAll' , "Controls whether auto fix action should be run on file save." ) ) ,
39
- } ) ;
40
38
41
39
const codeActionsOnSaveSchema : IConfigurationPropertySchema = {
42
40
oneOf : [
43
41
{
44
42
type : 'object' ,
45
- properties : codeActionsOnSaveDefaultProperties ,
46
43
additionalProperties : {
47
44
type : 'string'
48
45
} ,
@@ -72,15 +69,24 @@ export const editorConfiguration = Object.freeze<IConfigurationNode>({
72
69
export class CodeActionsContribution extends Disposable implements IWorkbenchContribution {
73
70
74
71
private _contributedCodeActions : CodeActionsExtensionPoint [ ] = [ ] ;
72
+ private settings : Set < string > = new Set < string > ( ) ;
75
73
76
74
private readonly _onDidChangeContributions = this . _register ( new Emitter < void > ( ) ) ;
77
75
78
76
constructor (
79
77
codeActionsExtensionPoint : IExtensionPoint < CodeActionsExtensionPoint [ ] > ,
80
78
@IKeybindingService keybindingService : IKeybindingService ,
79
+ @ILanguageFeaturesService private readonly languageFeatures : ILanguageFeaturesService
81
80
) {
82
81
super ( ) ;
83
82
83
+ // TODO: @justschen caching of code actions based on extensions loaded: https://github.com/microsoft/vscode/issues/216019
84
+
85
+ languageFeatures . codeActionProvider . onDidChange ( ( ) => {
86
+ this . updateSettingsFromCodeActionProviders ( ) ;
87
+ this . updateConfigurationSchemaFromContribs ( ) ;
88
+ } , 2000 ) ;
89
+
84
90
codeActionsExtensionPoint . setHandler ( extensionPoints => {
85
91
this . _contributedCodeActions = extensionPoints . flatMap ( x => x . value ) . filter ( x => Array . isArray ( x . actions ) ) ;
86
92
this . updateConfigurationSchema ( this . _contributedCodeActions ) ;
@@ -93,26 +99,48 @@ export class CodeActionsContribution extends Disposable implements IWorkbenchCon
93
99
} ) ;
94
100
}
95
101
102
+ private updateSettingsFromCodeActionProviders ( ) : void {
103
+ const providers = this . languageFeatures . codeActionProvider . allNoModel ( ) ;
104
+ providers . forEach ( provider => {
105
+ if ( provider . providedCodeActionKinds ) {
106
+ provider . providedCodeActionKinds . forEach ( kind => {
107
+ if ( ! this . settings . has ( kind ) && CodeActionKind . Source . contains ( new HierarchicalKind ( kind ) ) ) {
108
+ this . settings . add ( kind ) ;
109
+ }
110
+ } ) ;
111
+ }
112
+ } ) ;
113
+ }
114
+
96
115
private updateConfigurationSchema ( codeActionContributions : readonly CodeActionsExtensionPoint [ ] ) {
97
- const newProperties : IJSONSchemaMap = { ... codeActionsOnSaveDefaultProperties } ;
116
+ const newProperties : IJSONSchemaMap = { } ;
98
117
for ( const [ sourceAction , props ] of this . getSourceActions ( codeActionContributions ) ) {
118
+ this . settings . add ( sourceAction ) ;
99
119
newProperties [ sourceAction ] = createCodeActionsAutoSave ( nls . localize ( 'codeActionsOnSave.generic' , "Controls whether '{0}' actions should be run on file save." , props . title ) ) ;
100
120
}
101
121
codeActionsOnSaveSchema . properties = newProperties ;
102
122
Registry . as < IConfigurationRegistry > ( Extensions . Configuration )
103
123
. notifyConfigurationSchemaUpdated ( editorConfiguration ) ;
104
124
}
105
125
126
+ private updateConfigurationSchemaFromContribs ( ) {
127
+ const properties : IJSONSchemaMap = { ...codeActionsOnSaveSchema . properties } ;
128
+ for ( const codeActionKind of this . settings ) {
129
+ if ( ! properties [ codeActionKind ] ) {
130
+ properties [ codeActionKind ] = createCodeActionsAutoSave ( nls . localize ( 'codeActionsOnSave.generic' , "Controls whether '{0}' actions should be run on file save." , codeActionKind ) ) ;
131
+ }
132
+ }
133
+ codeActionsOnSaveSchema . properties = properties ;
134
+ Registry . as < IConfigurationRegistry > ( Extensions . Configuration )
135
+ . notifyConfigurationSchemaUpdated ( editorConfiguration ) ;
136
+ }
137
+
106
138
private getSourceActions ( contributions : readonly CodeActionsExtensionPoint [ ] ) {
107
- const defaultKinds = Object . keys ( codeActionsOnSaveDefaultProperties ) . map ( value => new HierarchicalKind ( value ) ) ;
108
139
const sourceActions = new Map < string , { readonly title : string } > ( ) ;
109
140
for ( const contribution of contributions ) {
110
141
for ( const action of contribution . actions ) {
111
142
const kind = new HierarchicalKind ( action . kind ) ;
112
- if ( CodeActionKind . Source . contains ( kind )
113
- // Exclude any we already included by default
114
- && ! defaultKinds . some ( defaultKind => defaultKind . contains ( kind ) )
115
- ) {
143
+ if ( CodeActionKind . Source . contains ( kind ) ) {
116
144
sourceActions . set ( kind . value , action ) ;
117
145
}
118
146
}
0 commit comments