Hover不生效主因是documentSelector与languageId不匹配,需用命令面板查vscode.window.activeTextEditor?.document.languageId确认真实ID,注册时用[{language:'typescript'}]等精确selector,避免缩写,并注意MarkdownString转义、异步操作及保存触发更新。

Hover 提示不生效,八成是 documentSelector 和实际文件的 languageId 对不上——不是你写错了,而是 VSCode 根本没把当前文件当你要支持的语言处理。
怎么确认当前文件真实 languageId
别猜,直接查。打开命令面板(Ctrl+Shift+P),运行 Developer: Toggle Developer Tools,切到 Console 标签页,输入:
vscode.window.activeTextEditor?.document.languageId
回车后看到的值才是真实 languageId。常见陷阱:
-
.ts文件返回typescript,不是javascript -
.vue文件默认是vue,但启用<script setup></script>后可能需要vue-html或typescript双 selector -
package.json是json,不是jsonc(除非你手动改了语言模式)
注册 HoverProvider 时 documentSelector 怎么写才有效
vscode.languages.registerHoverProvider() 的第一个参数必须和 package.json 中的 activationEvents 和 contributes.languages 严格一致。错一个字符就静默失败。
- 单语言:用数组
[{ language: 'typescript' }] - 多语言:写成
[{ language: 'typescript' }, { language: 'javascript' }] - 限定文件类型:比如只对
package.json生效,用{ scheme: 'file', language: 'json', pattern: '**/package.json' } - 别写
js或ts——VSCode 不认这种缩写
Hover 内容为空或格式乱码怎么办
返回的 vscode.MarkdownString 不是普通字符串,它对特殊字符敏感。反引号、星号、下划线不转义就会解析失败,结果就是悬停框空白。
- 构造时传
true启用自动转义:new vscode.MarkdownString('`x * y`', true) - 避免用多行代码块
```——Hover 渲染器不支持,改用单行`inline code` - 链接只能是
https://或command:协议,./readme.md这种相对路径无效 - 图片只接受网络 URL 或 base64(不推荐),
file://路径被拦截
悬停卡顿或超时,问题出在 provideHover 是同步函数
provideHover 看似能返回 Thenable,但如果你在里面做 fs.readFileSync、遍历大数组、调外部 API,整个悬停就会卡住甚至无响应。
- I/O 操作必须异步:
fs.promises.readFile+return Promise.resolve(hover) - 高频查询结果要缓存,比如按
document.uri.toString() + position.line做 Map 键 - 加超时兜底:
Promise.race([fetchPromise, new Promise(r => setTimeout(r, 500))]) - 别在
provideHover里启动新进程或加载大文件——用户悬停是毫秒级交互,不是后台任务
最常被忽略的一点:Hover 内容不会随源码实时更新。改了 JSDoc 或重新生成 AST 后,必须保存文件,VSCode 才会重新触发 provideHover。调试时别盯着没变的旧提示反复试。











