使用VSCode API开发补全功能时如何移除前置触发字符
VSCode扩展补全自动移除前置触发字符实现方案
核心原理:调整补全项的替换范围range,将前置触发字符纳入待替换区间,选中补全项时编辑器会将整个区间的内容(包含触发字符)替换为目标补全文本,即可实现不保留触发字符的效果。
修改要点
- 区分补全触发场景:仅当通过触发字符唤起补全时,调整替换范围覆盖前置触发字符;手动触发补全(如快捷键唤起)时保持原有替换逻辑,避免误删用户输入内容
- 单字符触发场景下,替换范围起始位置为当前光标位置向前偏移1位(刚好覆盖触发字符本身),结束位置为当前光标位置
- 若使用多字符触发符,将偏移量修改为触发符的字符长度即可
修改后可直接运行的代码
注意:需要提前从vscode依赖包中导入
CompletionTriggerKind类
import { CompletionTriggerKind } from 'vscode'; context.subscriptions.push(languages.registerCompletionItemProvider ( { language: 'json', scheme: 'file' }, { provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) { const createCompletionItem = (text: string) => { const item = new CompletionItem(text, CompletionItemKind.Text); // 默认替换范围:当前光标位置,适配手动触发补全场景 let replaceRange = new Range(position, position); // 触发字符唤起补全时,扩大替换范围覆盖前置触发字符 if (context.triggerKind === CompletionTriggerKind.TriggerCharacter) { const triggerStartPos = position.translate(0, -1); replaceRange = new Range(triggerStartPos, position); } item.range = replaceRange; return item; }; const linePrefix = document.lineAt(position).text.substring(0, position.character); if (linePrefix.match(/name/g)) { return [ createCompletionItem('log'), createCompletionItem('warn'), createCompletionItem('error'), ]; } return undefined; } }, '.' // 配置触发字符,此处按需求设为'.' ));
内容的提问来源于stack exchange,提问作者Witaek
相关产品推荐
相关产品推荐

