Skip to content

Commit c8d64b1

Browse files
committed
Add code actions contributon point
For microsoft#82718 Fixes microsoft#52846 This adds a newly proposed codeActions contribution point. For details, see microsoft#82718 This change also makes the intellisense for the `editor.codeActionsOnSave` property dynamic by using the new contribution point
1 parent 5ed6a46 commit c8d64b1

8 files changed

Lines changed: 228 additions & 24 deletions

File tree

build/lib/i18n.resources.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
"name": "vs/workbench/contrib/callHierarchy",
4343
"project": "vscode-workbench"
4444
},
45+
{
46+
"name": "vs/workbench/contrib/codeActions",
47+
"project": "vscode-workbench"
48+
},
4549
{
4650
"name": "vs/workbench/contrib/comments",
4751
"project": "vscode-workbench"

extensions/typescript-language-features/package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,44 @@
866866
}
867867
}
868868
}
869+
],
870+
"codeActions": [
871+
{
872+
"kind": "refactor.extract.constant",
873+
"title": "%codeActions.refactor.extract.constant%",
874+
"selector": [
875+
{
876+
"language": "javascript"
877+
},
878+
{
879+
"language": "javascriptreact"
880+
},
881+
{
882+
"language": "typescript"
883+
},
884+
{
885+
"language": "typescriptreact"
886+
}
887+
]
888+
},
889+
{
890+
"kind": "source.organizeImports",
891+
"title": "%codeActions.source.organizeImports%",
892+
"selector": [
893+
{
894+
"language": "javascript"
895+
},
896+
{
897+
"language": "javascriptreact"
898+
},
899+
{
900+
"language": "typescript"
901+
},
902+
{
903+
"language": "typescriptreact"
904+
}
905+
]
906+
}
869907
]
870908
}
871909
}

extensions/typescript-language-features/package.nls.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,7 @@
7575
"typescript.suggest.enabled": "Enabled/disable autocomplete suggestions.",
7676
"configuration.surveys.enabled": "Enabled/disable occasional surveys that help us improve VS Code's JavaScript and TypeScript support.",
7777
"configuration.suggest.completeJSDocs": "Enable/disable suggestion to complete JSDoc comments.",
78-
"typescript.preferences.renameShorthandProperties": "Enable/disable introducing aliases for object shorthand properties during renames. Requires using TypeScript 3.4 or newer in the workspace."
78+
"typescript.preferences.renameShorthandProperties": "Enable/disable introducing aliases for object shorthand properties during renames. Requires using TypeScript 3.4 or newer in the workspace.",
79+
"codeActions.refactor.extract.constant": "Extract constant",
80+
"codeActions.source.organizeImports": "Organize imports"
7981
}

src/vs/editor/common/config/commonEditorConfig.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -477,29 +477,6 @@ const editorConfiguration: IConfigurationNode = {
477477
default: 20_000,
478478
description: nls.localize('maxTokenizationLineLength', "Lines above this length will not be tokenized for performance reasons")
479479
},
480-
'editor.codeActionsOnSave': {
481-
type: 'object',
482-
properties: {
483-
'source.organizeImports': {
484-
type: 'boolean',
485-
description: nls.localize('codeActionsOnSave.organizeImports', "Controls whether organize imports action should be run on file save.")
486-
},
487-
'source.fixAll': {
488-
type: 'boolean',
489-
description: nls.localize('codeActionsOnSave.fixAll', "Controls whether auto fix action should be run on file save.")
490-
}
491-
},
492-
'additionalProperties': {
493-
type: 'boolean'
494-
},
495-
default: {},
496-
description: nls.localize('codeActionsOnSave', "Code action kinds to be run on save.")
497-
},
498-
'editor.codeActionsOnSaveTimeout': {
499-
type: 'number',
500-
default: 750,
501-
description: nls.localize('codeActionsOnSaveTimeout', "Timeout in milliseconds after which the code actions that are run on save are cancelled.")
502-
},
503480
'diffEditor.maxComputationTime': {
504481
type: 'number',
505482
default: 5000,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
6+
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
7+
import { Registry } from 'vs/platform/registry/common/platform';
8+
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
9+
import { CodeActionConfigurationManager, editorConfiguration } from 'vs/workbench/contrib/codeActions/common/configuration';
10+
import { CodeActionsExtensionPoint, codeActionsExtensionPointDescriptor } from 'vs/workbench/contrib/codeActions/common/extensionPoint';
11+
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
12+
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
13+
14+
const codeActionsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<CodeActionsExtensionPoint[]>(codeActionsExtensionPointDescriptor);
15+
16+
Registry.as<IConfigurationRegistry>(Extensions.Configuration)
17+
.registerConfiguration(editorConfiguration);
18+
19+
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
20+
.registerWorkbenchContribution(
21+
class {
22+
constructor() {
23+
// tslint:disable-next-line: no-unused-expression
24+
new CodeActionConfigurationManager(codeActionsExtensionPoint);
25+
}
26+
},
27+
LifecyclePhase.Eventually);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
6+
import { flatten } from 'vs/base/common/arrays';
7+
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
8+
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
9+
import * as nls from 'vs/nls';
10+
import { Extensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
11+
import { Registry } from 'vs/platform/registry/common/platform';
12+
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
13+
import { CodeActionExtensionPointFields, CodeActionsExtensionPoint } from 'vs/workbench/contrib/codeActions/common/extensionPoint';
14+
import { IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
15+
16+
const codeActionsOnSaveDefaultProperties = Object.freeze<IJSONSchemaMap>({
17+
'source.fixAll': {
18+
type: 'boolean',
19+
description: nls.localize('codeActionsOnSave.fixAll', "Controls whether auto fix action should be run on file save.")
20+
}
21+
});
22+
23+
const codeActionsOnSaveSchema: IJSONSchema = {
24+
type: 'object',
25+
properties: codeActionsOnSaveDefaultProperties,
26+
'additionalProperties': {
27+
type: 'boolean'
28+
},
29+
default: {},
30+
description: nls.localize('codeActionsOnSave', "Code action kinds to be run on save.")
31+
};
32+
33+
export const editorConfiguration = Object.freeze<IConfigurationNode>({
34+
id: 'editor',
35+
order: 5,
36+
type: 'object',
37+
title: nls.localize('editorConfigurationTitle', "Editor"),
38+
overridable: true,
39+
properties: {
40+
'editor.codeActionsOnSave': codeActionsOnSaveSchema,
41+
'editor.codeActionsOnSaveTimeout': {
42+
type: 'number',
43+
default: 750,
44+
description: nls.localize('codeActionsOnSaveTimeout', "Timeout in milliseconds after which the code actions that are run on save are cancelled.")
45+
},
46+
}
47+
});
48+
49+
export class CodeActionConfigurationManager implements IWorkbenchContribution {
50+
constructor(
51+
codeActionsExtensionPoint: IExtensionPoint<CodeActionsExtensionPoint[]>
52+
) {
53+
codeActionsExtensionPoint.setHandler(extensionPoints => {
54+
const newProperties: IJSONSchemaMap = { ...codeActionsOnSaveDefaultProperties };
55+
for (const [sourceAction, props] of this.getSourceActions(extensionPoints)) {
56+
newProperties[sourceAction] = {
57+
type: 'boolean',
58+
description: nls.localize(
59+
'codeActionsOnSave.generic',
60+
"Controls whether '{0}' actions should be run on file save.",
61+
props.title)
62+
};
63+
}
64+
codeActionsOnSaveSchema.properties = newProperties;
65+
66+
Registry.as<IConfigurationRegistry>(Extensions.Configuration)
67+
.notifyConfigurationSchemaUpdated(editorConfiguration);
68+
});
69+
}
70+
71+
private getSourceActions(extensionPoints: readonly IExtensionPointUser<CodeActionsExtensionPoint[]>[]) {
72+
const sourceActions = new Map<string, { readonly title: string }>();
73+
for (const contribution of flatten(extensionPoints.map(x => x.value))) {
74+
const kind = new CodeActionKind(contribution[CodeActionExtensionPointFields.kind]);
75+
const defaultKinds = Object.keys(codeActionsOnSaveDefaultProperties).map(value => new CodeActionKind(value));
76+
if (CodeActionKind.Source.contains(kind)
77+
// Exclude any we already included by default
78+
&& !defaultKinds.some(defaultKind => defaultKind.contains(kind))
79+
) {
80+
sourceActions.set(kind.value, contribution);
81+
}
82+
}
83+
return sourceActions;
84+
}
85+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
6+
import * as nls from 'vs/nls';
7+
import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
8+
import { languagesExtPoint } from 'vs/workbench/services/mode/common/workbenchModeService';
9+
10+
export enum CodeActionExtensionPointFields {
11+
kind = 'kind',
12+
title = 'title',
13+
selector = 'selector',
14+
selectorLanguage = 'language',
15+
selectorScheme = 'scheme',
16+
}
17+
18+
export interface CodeActionsExtensionPoint {
19+
readonly [CodeActionExtensionPointFields.kind]: string;
20+
readonly [CodeActionExtensionPointFields.title]: string;
21+
readonly [CodeActionExtensionPointFields.selector]: {
22+
readonly [CodeActionExtensionPointFields.selectorLanguage]: string;
23+
readonly [CodeActionExtensionPointFields.selectorScheme]: string;
24+
};
25+
}
26+
27+
const codeActionsExtensionPointSchema: IConfigurationPropertySchema = {
28+
type: 'array',
29+
markdownDescription: nls.localize('contributes.codeActions', "Configure which editor to use for a resource."),
30+
items: {
31+
type: 'object',
32+
required: [CodeActionExtensionPointFields.kind, CodeActionExtensionPointFields.title, CodeActionExtensionPointFields.selector],
33+
properties: {
34+
[CodeActionExtensionPointFields.kind]: {
35+
type: 'string',
36+
markdownDescription: nls.localize('contributes.codeActions.kind', "`CodeActionKind` of the contributed code action."),
37+
},
38+
[CodeActionExtensionPointFields.title]: {
39+
type: 'string',
40+
description: nls.localize('contributes.codeActions.title', "Human readable name for the code action."),
41+
},
42+
[CodeActionExtensionPointFields.selector]: {
43+
type: 'array',
44+
description: nls.localize('contributes.codeActions.selector', "Files that the code actions are enabled for."),
45+
items: {
46+
type: 'object',
47+
required: [CodeActionExtensionPointFields.selectorLanguage],
48+
properties: {
49+
[CodeActionExtensionPointFields.selectorLanguage]: {
50+
type: 'string',
51+
description: nls.localize('contributes.codeActions.selector.language', "Language mode that the code action is enabled for."),
52+
},
53+
[CodeActionExtensionPointFields.selectorScheme]: {
54+
type: 'string',
55+
description: nls.localize('contributes.codeActions.selector.scheme', "File scheme that the code action is enabled for."),
56+
}
57+
},
58+
}
59+
},
60+
}
61+
}
62+
};
63+
64+
export const codeActionsExtensionPointDescriptor = {
65+
extensionPoint: 'codeActions',
66+
deps: [languagesExtPoint],
67+
jsonSchema: codeActionsExtensionPointSchema
68+
};

src/vs/workbench/workbench.common.main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,7 @@ import 'vs/workbench/contrib/feedback/browser/feedback.contribution';
253253
// User Data Sync
254254
import 'vs/workbench/contrib/userDataSync/browser/userDataSync.contribution';
255255

256+
// Code Actions
257+
import 'vs/workbench/contrib/codeActions/common/codeActions.contribution';
258+
256259
//#endregion

0 commit comments

Comments
 (0)