如何在VS Code扩展中为CompletionItem动态设置insertText
我希望在用户从TriggerSuggest列表中选中特定CompletionItem时,为其动态设置insertText。现有VS Code扩展代码如下:
import * as vscode from "vscode"; export function activate(context: vscode.ExtensionContext) { const CompletionProvider = vscode.languages.registerCompletionItemProvider( "smallbasic", { provideCompletionItems( document: vscode.TextDocument, position: vscode.Position ) { const textCompletion = new vscode.CompletionItem("Text"); const wordCompletion = new vscode.CompletionItem("Word"); return [textCompletion, wordCompletion]; }, } ); context.subscriptions.push(CompletionProvider); } export function deactivate() {}
我尝试使用CompletionItemProvider的resolveCompletionItem方法,代码如下:
resolveCompletionItem(item: vscode.CompletionItem) { console.log("item : ", item); if (item) { // SmallBasic Snippet Generator const sbSnippetGenerator = new SbSnippetGenerator(); const snippet = sbSnippetGenerator.getSnippet(item); console.log("성공"); item.insertText = new vscode.SnippetString(snippet); } return item; },
但该方法仅在通过键盘(按键+回车)选中补全项时生效,鼠标点击选中时无效,无法实现从类中获取insertText并插入的需求,请问如何解决?
这个问题的核心是VS Code的补全项解析逻辑:鼠标点击选中补全项时,默认不会触发resolveCompletionItem方法,只有键盘导航选中并确认时才会触发。要让两种交互都生效,需要做以下调整:
为CompletionItem设置
resolveSupport属性
在创建CompletionItem时,明确指定需要解析的属性,告诉VS Code即使鼠标点击也要触发resolve逻辑。修改provideCompletionItems中的代码:provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { const textCompletion = new vscode.CompletionItem("Text"); // 添加resolve支持,指定需要动态处理的属性 textCompletion.resolveSupport = { properties: ["insertText"] }; const wordCompletion = new vscode.CompletionItem("Word"); wordCompletion.resolveSupport = { properties: ["insertText"] }; return [textCompletion, wordCompletion]; }确保resolveCompletionItem逻辑正确
保持你的resolveCompletionItem方法不变,但注意:如果SbSnippetGenerator.getSnippet是异步操作,需要把方法改成异步(返回Promise<vscode.CompletionItem>),同步逻辑则无需修改。验证注册Provider时的触发条件(可选)
如果你是通过特定触发字符激活补全,确保注册Provider时没有限制导致鼠标场景不触发。比如:// 示例:如果需要指定触发字符,确保覆盖所有场景 const CompletionProvider = vscode.languages.registerCompletionItemProvider( "smallbasic", { /* 你的provider逻辑 */ }, ".", // 触发字符,根据需要调整或移除 " " );
这样修改后,无论是键盘选中回车还是鼠标点击补全项,都会触发resolveCompletionItem方法,动态设置insertText。
内容的提问来源于stack exchange,提问作者Seokwoo Yang

