VSCode语言扩展开发:冒号开头token补全出现重复冒号如何解决
VSCode冒号开头Token补全重复冒号解决方案
问题原因
VSCode默认的补全替换范围仅识别光标前的纯单词字符,会把冒号判定为单词分隔符,所以输入:f时,默认补全范围仅包含f,你返回的补全项:foo会追加在原有的冒号后,最终出现::foo的问题。
解决方案
方案1:手动指定补全项替换范围(推荐)
构造CompletionItem时主动计算需要替换的完整前缀范围,覆盖已经输入的冒号和后续字符,示例代码如下:
import * as vscode from 'vscode'; // 构建补全项逻辑示例 function provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { const completions: vscode.CompletionItem[] = []; // 计算光标前最近的冒号开头的前缀范围 const textBeforeCursor = document.getText(new vscode.Range(position.with(undefined, 0), position)); const colonPrefixMatch = textBeforeCursor.match(/:[^\s:]*$/); if (!colonPrefixMatch) { return completions; } const replaceRange = new vscode.Range( position.line, position.character - colonPrefixMatch[0].length, position.line, position.character ); // 构造补全项 const fooItem = new vscode.CompletionItem(':foo', vscode.CompletionItemKind.Constant); // 绑定替换范围,触发补全时会替换整个前缀 fooItem.range = replaceRange; completions.push(fooItem); return completions; }
该方案灵活性高,仅针对冒号开头的补全项生效,不会影响其他场景的补全逻辑。
方案2:修改语言单词匹配规则
如果你的语言中所有标识符均以冒号开头,可以直接在扩展的package.json中修改语言的wordPattern配置,将冒号从单词分隔符中移除,VSCode会自动将:f识别为完整单词,默认替换整个前缀:
{ "contributes": { "languages": [ { "id": "你的语言唯一ID", // 该正则已移除冒号作为分隔符,可根据你的语言规则调整 "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\'\\\"\\,\\<\\>\\/\\?\\s]+)" } ] } }
该方案无需在补全逻辑中额外处理范围,适合冒号是标识符通用前缀的场景。
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

