VSCode扩展开发:如何检测IntelliSense建议项是否被点击?
捕获VSCode扩展补全建议的点击事件
要捕获用户点击你提供的补全建议的事件,有两种靠谱的方式:
方法1:给补全项绑定专属命令
这是最精准的方式,直接给每个补全项绑定触发命令,用户选中该选项时就会执行对应的逻辑。
实现步骤:
- 先注册一个自定义命令,用来处理补全项被选中后的操作
- 创建
CompletionItem时,把命令绑定到它的command属性上
修改后的完整代码:
export function activate(context: vscode.ExtensionContext) { // 注册自定义命令,处理补全项选中事件 const completionCommand = vscode.commands.registerCommand('extension.onCompletionSelected', (itemName) => { // 这里写你要触发的逻辑,比如打印选中的补全项名称 console.log(`用户选中了补全项:${itemName}`); // 还可以做其他操作,比如弹出提示、修改文档等 vscode.window.showInformationMessage(`你选择了${itemName}`); }); const provider2 = vscode.languages.registerCompletionItemProvider( 'plaintext', { provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { const linePrefix = document.lineAt(position).text.substr(0, position.character); if (!linePrefix.endsWith('console.')) { return undefined; } // 给每个补全项绑定命令 const logItem = new vscode.CompletionItem('log', vscode.CompletionItemKind.Method); logItem.command = { command: 'extension.onCompletionSelected', title: 'Completion Selected', arguments: ['log'] // 传递补全项名称作为参数 }; const warnItem = new vscode.CompletionItem('warn', vscode.CompletionItemKind.Method); warnItem.command = { command: 'extension.onCompletionSelected', title: 'Completion Selected', arguments: ['warn'] }; const errorItem = new vscode.CompletionItem('error', vscode.CompletionItemKind.Method); errorItem.command = { command: 'extension.onCompletionSelected', title: 'Completion Selected', arguments: ['error'] }; return [logItem, warnItem, errorItem]; } }, '.' ); context.subscriptions.push(provider2, completionCommand); }
方法2:监听文档变更事件
如果需要监听所有补全插入的情况(不限于你的补全项),可以通过监听文档内容变化来判断是否插入了目标补全内容。
示例代码:
export function activate(context: vscode.ExtensionContext) { // 监听文档变更事件 const docChangeListener = vscode.workspace.onDidChangeTextDocument((event) => { // 只处理文本插入操作 if (event.contentChanges.length === 0) return; const change = event.contentChanges[0]; // 判断插入的内容是不是你的补全项 const targetItems = ['log', 'warn', 'error']; if (targetItems.includes(change.text)) { // 检查插入位置的前缀是不是console. const line = event.document.lineAt(change.range.start.line); const prefix = line.text.substr(0, change.range.start.character); if (prefix.endsWith('console.')) { console.log(`用户插入了补全项:${change.text}`); vscode.window.showInformationMessage(`插入了${change.text}`); } } }); const provider2 = vscode.languages.registerCompletionItemProvider( 'plaintext', { provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { const linePrefix = document.lineAt(position).text.substr(0, position.character); if (!linePrefix.endsWith('console.')) { return undefined; } return [ new vscode.CompletionItem('log', vscode.CompletionItemKind.Method), new vscode.CompletionItem('warn', vscode.CompletionItemKind.Method), new vscode.CompletionItem('error', vscode.CompletionItemKind.Method), ]; } }, '.' ); context.subscriptions.push(provider2, docChangeListener); }
两种方式对比:
- 方法1:精准针对你的补全项,不会误触发,逻辑更清晰
- 方法2:通用性强,但需要额外判断内容和前缀,适合需要监听所有类似插入的场景
内容的提问来源于stack exchange,提问作者IceCreamCode
相关产品推荐
相关产品推荐

