diff --git a/clients/vscode/src/Commands.ts b/clients/vscode/src/Commands.ts index 64f55c5f8309..1cab196d7b11 100644 --- a/clients/vscode/src/Commands.ts +++ b/clients/vscode/src/Commands.ts @@ -13,6 +13,8 @@ import { QuickPickItem, ViewColumn, Range, + CodeAction, + CodeActionKind, } from "vscode"; import os from "os"; import path from "path"; @@ -225,8 +227,20 @@ export class Commands { "inlineCompletion.trigger": () => { commands.executeCommand("editor.action.inlineSuggest.trigger"); }, - "inlineCompletion.accept": () => { - commands.executeCommand("editor.action.inlineSuggest.commit"); + "inlineCompletion.accept": async () => { + const editor = window.activeTextEditor; + if (!editor) { + return; + } + + const uri = editor.document.uri; + const range = this.inlineCompletionProvider.calcEditedRangeAfterAccept(); + + await commands.executeCommand("editor.action.inlineSuggest.commit"); + + if (range) { + applyQuickFixes(uri, range); + } }, "inlineCompletion.acceptNextWord": () => { this.inlineCompletionProvider.handleEvent("accept_word"); @@ -455,3 +469,23 @@ export class Commands { }, }; } + +async function applyQuickFixes(uri: Uri, range: Range): Promise { + const codeActions = await commands.executeCommand("vscode.executeCodeActionProvider", uri, range); + const quickFixActions = codeActions.filter( + (action) => + action.kind && action.kind.contains(CodeActionKind.QuickFix) && action.title.toLowerCase().includes("import"), + ); + quickFixActions.forEach(async (action) => { + try { + if (action.edit) { + await workspace.applyEdit(action.edit); + } + if (action.command) { + await commands.executeCommand(action.command.command, action.command.arguments); + } + } catch (error) { + // ignore errors + } + }); +} diff --git a/clients/vscode/src/InlineCompletionProvider.ts b/clients/vscode/src/InlineCompletionProvider.ts index 9b2bd7ecf259..a4d1970fc8d2 100644 --- a/clients/vscode/src/InlineCompletionProvider.ts +++ b/clients/vscode/src/InlineCompletionProvider.ts @@ -211,4 +211,27 @@ export class InlineCompletionProvider extends EventEmitter implements InlineComp // await not required this.client.telemetry.postEvent(params); } + + /** + * Calculate the edited range in the modified document as if the current completion item has been accepted. + * @return {Range | undefined} - The range with the current completion item + */ + public calcEditedRangeAfterAccept(): Range | undefined { + const item = this.displayedCompletion?.completions.items[this.displayedCompletion.index]; + const range = item?.range; + if (!range) { + // FIXME: If the item has a null range, we can use current position and text length to calculate the result range + return undefined; + } + if (!item) { + return undefined; + } + const length = (item.insertText as string).split("\n").length - 1; //remove current line count; + const completionRange = new Range( + new Position(range.start.line, range.start.character), + new Position(range.end.line + length + 1, 0), + ); + this.logger.debug("Calculate edited range for displayed completion item:", completionRange); + return completionRange; + } }