Change:
This would enable Microsoft/TypeScript. I am mostly describing changes to in the TypeScript repository here. we discussed this today. The returned in a code action request may include a list of commands. A code action may even have an empty list and consist of only a command. We could choose specify that must an of commands, although I'm not sure if that's worth bothering with. If the code action is accepted, the editor must send the commands back to the language service to actually be carried out. This means needing a new request type, "applyCodeFixCommand". This looks like: The contents of will just be what was sent to the editor. (Typically this will include a "type" field so the language service can dispatch on the type of action.) The language service should send a response when the action is complete. I'm thinking we can just reuse the field for error reporting and for a successful response. (Currently the field is documented to only be used if is false.) We could put that in the body, but then it seems redundant.
This proposed TS API changes seem good to me. I don't see any issues implementing this on our side. We'll just need to figure out how best to surface the success / failure messages to users Let me know when the TS part lands in a nightly build so that I can try prototyping this
If we put this in a nightly build, people will start seeing codefixes that don't work. Could you check out a branch instead?
Sure, sounds good
You can checkout and build the branch from the TypeScript repository. If you include in a file and it is an unused identifier, we'll give you a code fix that comes with a command to write a file . (It also replaces the file content so you can verify that at least that works.)
Thanks I'll open a PR on our side shortly. A few quick notes: Looks like is currently using instead of for the key. The name makes more sense to me Also, I get this error when I try to run the command:
Here's the PR:
I pushed a quick fix of those two issues -- changed the name from "action" to "command" and remembered to write to a file rather than to a directory.
Ok, the fix looks good. I see the d.ts file being created now
Any reason this couldn't land in nightly so I can experiment with it? Regular users won't see anything until we actually add something in TypeScript master that uses this.
We're getting ready for release currently but I can check this in once we branch off for the September release. This code in its current state won't compile until we pick up a new * file from TypeScript, but we can sprinkle in some casts to work around this until then

Discussion:
errorCodes: Array.from(supportedActions) }; const response = await this.client.execute('getCodeFixes', args, token); <del> return (response.body || []).map(action => this.getCommandForAction(action)); </del> <ins> return (response.body || []).map(action => this.getCommandForAction(action, file)); </ins> } private get supportedCodeActions(): Thenable<NumberSet> {

return this._supportedCodeActions; } <del> private getSupportedActionsForContext(context: CodeActionContext): Thenable<Set<number>> { return this.supportedCodeActions.then(supportedActions => new Set(context.diagnostics .map(diagnostic => +diagnostic.code) .filter(code => supportedActions[code]))); </del> <ins> private async getSupportedActionsForContext(context: CodeActionContext): Promise<Set<number>> { const supportedActions = await this.supportedCodeActions; return new Set(context.diagnostics .map(diagnostic => +diagnostic.code) .filter(code => supportedActions[code])); </ins> } <del> private getCommandForAction(action: Proto.CodeAction): Command { </del> <ins> private getCommandForAction(action: Proto.CodeAction, file: string): Command { </ins> return { title: action.description, command: this.commandId, <del> arguments: [action] </del> <ins> arguments: [action, file] </ins> }; } <del> private async onCodeAction(action: Proto.CodeAction): Promise<boolean> { const workspaceEdit = new WorkspaceEdit(); for (const change of action.changes) { for (const textChange of change.textChanges) { workspaceEdit.replace(this.client.asUrl(change.fileName), tsTextSpanToVsRange(textChange), textChange.newText); </del> <ins> private async onCodeAction(action: Proto.CodeAction, file: string): Promise<boolean> { if (action.changes && action.changes.length) { const workspaceEdit = new WorkspaceEdit(); for (const change of action.changes) { for (const textChange of change.textChanges) { workspaceEdit.replace(this.client.asUrl(change.fileName), tsTextSpanToVsRange(textChange), textChange.newText); } } if (!(await workspace.applyEdit(workspaceEdit))) { return false; </ins> } } <del> return workspace.applyEdit(workspaceEdit); </del> <ins> if (action.commands && action.commands.length) { for (const command of action.commands) { const response = await this.client.execute('applyCodeActionCommand', { file, command }); if (!response || !response.body) { return false; } } } return true; </ins> } }  No newline at end of file

const actions: Command[] = []; for (const info of response.body) { <ins> // Workaround for https://github.com/Microsoft/TypeScript/issues/19378 if (info.name.startsWith('Install missing ')) { continue; } </ins> if (info.inlineable === false) { actions.push({ title: info.description,

execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.DocCommandTemplateResponse>; execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: CancellationToken): Promise<Proto.GetApplicableRefactorsResponse>; execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: CancellationToken): Promise<Proto.GetEditsForRefactorResponse>; <ins> execute(command: 'applyCodeActionCommand', args: Proto.ApplyCodeActionCommandRequestArgs, token?: CancellationToken): Promise<Proto.ApplyCodeActionCommandResponse>; </ins> // execute(command: 'compileOnSaveAffectedFileList', args: Proto.CompileOnSaveEmitFileRequestArgs, token?: CancellationToken): Promise<Proto.CompileOnSaveAffectedFileListResponse>; // execute(command: 'compileOnSaveEmitFile', args: Proto.CompileOnSaveEmitFileRequestArgs, token?: CancellationToken): Promise<any>; execute(command: string, args: any, expectedResult: boolean | CancellationToken, token?: CancellationToken): Promise<any>;