VS Code扩展开发如何获取hover位置自定义匹配文本的range范围
问题原因
- 原有正则存在缺陷:
\w+\s{0,}\(.{0,}\s{0,}\)中的.{0,}会贪婪匹配到行尾任意字符,无法精准匹配到右括号为止的区间。 document.getWordRangeAtPosition的底层逻辑依赖VS Code默认分词规则,当hover位置落在空格、括号等默认非单词字符上时,会判定当前位置不属于任何“单词”区间,直接返回undefined。
解决方案
放弃依赖getWordRangeAtPosition接口,改为主动遍历当前行所有符合规则的匹配片段,计算每个片段的Range后,判断hover位置是否落在某个片段范围内,命中则直接返回对应Range即可。
修复后代码示例
const vscode = require('vscode'); // 正则提前全局定义,避免重复初始化提升性能 // 规则:匹配 函数名 + 任意空格 + 左括号 + 任意非右括号字符 + 右括号 const FUNCTION_PATTERN = /\w+\s*\([^)]*\)/g; vscode.languages.registerHoverProvider('.mylanguage', { provideHover(document, position, token) { let hoverRange; const currentLine = document.lineAt(position.line); const lineText = currentLine.text; const lineIndex = position.line; let matchResult; // 遍历当前行所有符合规则的匹配项 while ((matchResult = FUNCTION_PATTERN.exec(lineText)) !== null) { // 计算当前匹配项的起止位置 const start = new vscode.Position(lineIndex, matchResult.index); const end = new vscode.Position(lineIndex, matchResult.index + matchResult[0].length); const currentRange = new vscode.Range(start, end); // 判断hover位置是否在当前匹配区间内 if (currentRange.contains(position)) { hoverRange = currentRange; break; } } console.log(hoverRange); // 其余业务逻辑,如需返回hover内容可参考下方代码 // if (hoverRange) { // return new vscode.Hover('自定义hover提示内容', hoverRange); // } } });
注意事项
- 上述正则仅适用于无括号嵌套的场景,如果需要支持
myFunc(innerFunc())这类嵌套括号的匹配,需要自己实现简单的括号层数计数逻辑,正则无法处理嵌套结构。 - 如果需要调整匹配规则,只需修改
FUNCTION_PATTERN的正则表达式即可。
内容的提问来源于stack exchange,提问作者notexactly
相关产品推荐
相关产品推荐

