Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vscode): adding auto-import during accept inline completion item #3389

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions clients/vscode/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
QuickPickItem,
ViewColumn,
Range,
CodeAction,
CodeActionKind,
} from "vscode";
import os from "os";
import path from "path";
Expand Down Expand Up @@ -223,7 +225,19 @@ export class Commands {
commands.executeCommand("editor.action.inlineSuggest.trigger");
},
"inlineCompletion.accept": () => {
const editor = window.activeTextEditor;
if (!editor) {
return;
}

commands.executeCommand("editor.action.inlineSuggest.commit");

const uri = editor.document.uri;
const range = this.inlineCompletionProvider.getCurrentDisplayRange();
if (!range) {
return;
}
Copy link
Member

@icycodes icycodes Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
commands.executeCommand("editor.action.inlineSuggest.commit");
const uri = editor.document.uri;
const range = this.inlineCompletionProvider.getCurrentDisplayRange();
if (!range) {
return;
}
const range = this.inlineCompletionProvider.getCurrentDisplayRange();
await commands.executeCommand("editor.action.inlineSuggest.commit");
const uri = editor.document.uri;
if (!range) {
return;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it await the edit action of accept inline completion?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The await causes us to be unable to get the current display item because it is no longer available. I moved the part that retrieves the edited range before committing the inline suggestion. The range should always exist if a code prediction is present.

applyQuickFixes(uri, range);
},
"inlineCompletion.acceptNextWord": () => {
this.inlineCompletionProvider.handleEvent("accept_word");
Expand Down Expand Up @@ -452,3 +466,23 @@ export class Commands {
},
};
}

async function applyQuickFixes(uri: Uri, range: Range): Promise<void> {
const codeActions = await commands.executeCommand<CodeAction[]>("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
}
});
}
24 changes: 24 additions & 0 deletions clients/vscode/src/InlineCompletionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,28 @@ export class InlineCompletionProvider extends EventEmitter implements InlineComp
// await not required
this.client.telemetry.postEvent(params);
}

/**
* Get current display range with the current completion item
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
* @return {Range | undefined} - The range with the current completion item
*/
public getCurrentDisplayRange(): Range | undefined {
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
const item = this.displayedCompletion?.completions.items[this.displayedCompletion.index];
const range = item?.range;
if (!range) {
return undefined;
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
}
if (!item) {
return undefined;
}
const length = (item.insertText as string).split("\n").length - 1; //remove current line count;
const completionEnd = range.end.line + length;
const completionRange = new Range(
new Position(range.start.line, range.start.character),
new Position(completionEnd == 0 ? completionEnd : completionEnd + 1, 0),
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
);
this.logger.info("current range with displayed completion item:", completionRange);
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved

return completionRange;
}
}