diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 880c8dc462b..9480d471455 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -10,7 +10,8 @@ "enabledApiProposals": [ "workspaceTrust", "multiDocumentHighlightProvider", - "mappedEditsProvider" + "mappedEditsProvider", + "codeActionAI" ], "capabilities": { "virtualWorkspaces": { @@ -147,59 +148,6 @@ "title": "%configuration.typescript%", "order": 20, "properties": { - "typescript.experimental.aiCodeActions": { - "type": "object", - "default": {}, - "description": "%typescript.experimental.aiCodeActions%", - "scope": "resource", - "properties": { - "classIncorrectlyImplementsInterface": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.classIncorrectlyImplementsInterface%" - }, - "classDoesntImplementInheritedAbstractMember": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.classDoesntImplementInheritedAbstractMember%" - }, - "missingFunctionDeclaration": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.missingFunctionDeclaration%" - }, - "inferAndAddTypes": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.inferAndAddTypes%" - }, - "addNameToNamelessParameter": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.addNameToNamelessParameter%" - }, - "extractConstant": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.extractConstant%" - }, - "extractFunction": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.extractFunction%" - }, - "extractType": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.extractType%" - }, - "extractInterface": { - "type": "boolean", - "default": false, - "description": "%typescript.experimental.aiCodeActions.extractInterface%" - } - } - }, "typescript.tsdk": { "type": "string", "markdownDescription": "%typescript.tsdk.desc%", diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 0bd09aa8d55..796b524a48c 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -8,16 +8,6 @@ "configuration.suggest.completeFunctionCalls": "Complete functions with their parameter signature.", "configuration.suggest.includeAutomaticOptionalChainCompletions": "Enable/disable showing completions on potentially undefined values that insert an optional chain call. Requires strict null checks to be enabled.", "configuration.suggest.includeCompletionsForImportStatements": "Enable/disable auto-import-style completions on partially-typed import statements.", - "typescript.experimental.aiCodeActions": "Enable/disable AI-assisted code actions. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.classIncorrectlyImplementsInterface": "Enable/disable AI assistance for Class Incorrectly Implements Interface quickfix. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.classDoesntImplementInheritedAbstractMember": "Enable/disable AI assistance for Class Doesn't Implement Inherited Abstract Member quickfix. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.missingFunctionDeclaration": "Enable/disable AI assistance for Missing Function Declaration quickfix. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.inferAndAddTypes": "Enable/disable AI assistance for Infer and Add Types refactor. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.addNameToNamelessParameter": "Enable/disable AI assistance for Add Name to Nameless Parameter quickfix. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.extractConstant": "Enable/disable AI assistance for Extract Constant refactor. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.extractFunction": "Enable/disable AI assistance for Extract Function refactor. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.extractType": "Enable/disable AI assistance for Extract Type refactor. Requires an extension providing AI chat functionality.", - "typescript.experimental.aiCodeActions.extractInterface": "Enable/disable AI assistance for Extract Interface refactor. Requires an extension providing AI chat functionality.", "typescript.tsdk.desc": "Specifies the folder path to the tsserver and `lib*.d.ts` files under a TypeScript install to use for IntelliSense, for example: `./node_modules/typescript/lib`.\n\n- When specified as a user setting, the TypeScript version from `typescript.tsdk` automatically replaces the built-in TypeScript version.\n- When specified as a workspace setting, `typescript.tsdk` allows you to switch to use that workspace version of TypeScript for IntelliSense with the `TypeScript: Select TypeScript version` command.\n\nSee the [TypeScript documentation](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions) for more detail about managing TypeScript versions.", "typescript.disableAutomaticTypeAcquisition": "Disables [automatic type acquisition](https://code.visualstudio.com/docs/nodejs/working-with-javascript#_typings-and-automatic-type-acquisition). Automatic type acquisition fetches `@types` packages from npm to improve IntelliSense for external libraries.", "typescript.enablePromptUseWorkspaceTsdk": "Enables prompting of users to use the TypeScript version configured in the workspace for Intellisense.", diff --git a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts index 9f82bc759e3..26a658d9116 100644 --- a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts +++ b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts @@ -147,12 +147,19 @@ class VsCodeFixAllCodeAction extends VsCodeCodeAction { class CodeActionSet { private readonly _actions = new Set(); private readonly _fixAllActions = new Map<{}, VsCodeCodeAction>(); + private readonly _aiActions = new Set(); - public get values(): Iterable { - return this._actions; + public *values(): Iterable { + yield* this._actions; + yield* this._aiActions; } public addAction(action: VsCodeCodeAction) { + if (action.isAI) { + // there are no separate fixAllActions for AI, and no duplicates, so return immediately + this._aiActions.add(action); + return; + } for (const existing of this._actions) { if (action.tsAction.fixName === existing.tsAction.fixName && equals(action.edit, existing.edit)) { this._actions.delete(existing); @@ -261,7 +268,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider change.textChanges.map(textChange => textChange.newText).join('')).join(''); title = 'Add meaningful parameter name with Copilot'; message = `Rename the parameter ${newText} with a more meaningful name.`; @@ -365,32 +384,33 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider vscode.Command) | undefined; - if (vscode.workspace.getConfiguration('typescript', null).get('experimental.aiCodeActions')) { - if (Extract_Constant.matches(action) && vscode.workspace.getConfiguration('typescript').get('experimental.aiCodeActions.extractConstant') - || Extract_Function.matches(action) && vscode.workspace.getConfiguration('typescript').get('experimental.aiCodeActions.extractFunction') - || Extract_Type.matches(action) && vscode.workspace.getConfiguration('typescript').get('experimental.aiCodeActions.extractType') - || Extract_Interface.matches(action) && vscode.workspace.getConfiguration('typescript').get('experimental.aiCodeActions.extractInterface') + codeActions.push(new InlinedCodeAction(this.client, document, refactor, action, rangeOrSelection, undefined)); + const copilot = vscode.extensions.getExtension('github.copilot-chat'); + if (copilot?.isActive) { + if (Extract_Constant.matches(action) + || Extract_Function.matches(action) + || Extract_Type.matches(action) + || Extract_Interface.matches(action) ) { const newName = Extract_Constant.matches(action) ? 'newLocal' : Extract_Function.matches(action) ? 'newFunction' : Extract_Type.matches(action) ? 'NewType' : Extract_Interface.matches(action) ? 'NewInterface' : ''; - copilotRename = info => ({ + const copilotRename: ((info: Proto.RefactorEditInfo) => vscode.Command) = info => ({ title: '', command: EditorChatFollowUp.ID, arguments: [{ @@ -658,14 +664,14 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider