hover不显示主因是languageid不匹配,需确保registerhoverprovider、package.json和文件实际languageid三者一致;markdownstring需启用自动转义;providehover须异步且防超时;自定义hover应与原生提示合并而非覆盖。

registerHoverProvider 的 languageId 必须精确匹配
Hover 不显示,八成是 documentSelector 里写的 languageId 和当前文件实际 languageId 对不上。比如你注册了 { language: 'javascript' },但打开的是 .ts 文件——它的真实 languageId 是 typescript,不是 javascript。
实操建议:
- 按
Ctrl+Shift+P→ 输入Developer: Toggle Developer Tools→ 在 Console 里执行vscode.window.activeTextEditor?.document.languageId,直接看当前文件真实 ID -
package.json中activationEvents和contributes.languages要和注册时用的 ID 完全一致(比如都写typescript,别混用ts或js) - 注册 provider 时,优先用数组形式指定 selector:
[{ language: 'typescript' }],比模糊的{ scheme: 'file' }更可靠
provideHover 返回的 Hover 内容要防转义失效
返回空提示、格式错乱、链接不渲染,大概率是 Markdown 字符没转义。VSCode 的 MarkdownString 只支持有限内联语法,*、_、` 这些符号若未处理,整个内容会解析失败变成空白。
实操建议:
- 构造时务必传
true启用自动转义:new vscode.MarkdownString(text, true) - 避免用多行代码块
```—— Hover 里渲染异常,改用单行`const x = 1` - 链接只能是绝对 URL(如
https://example.com)或command:协议(如command:editor.action.formatDocument),./readme.md这类相对路径无效 - 图片不能用
file://,也不推荐 base64(体积大、加载慢)
provideHover 里不能做同步耗时操作
悬停卡顿、半天没反应、甚至提示“hover provider timed out”,基本是因为你在 provideHover 函数里干了同步重活:读文件、遍历 AST、调本地 HTTP 接口……这个函数必须快进快出。
实操建议:
- 所有 I/O 操作必须异步:用
fs.promises.readFile替代fs.readFileSync,并返回Promise.resolve(new vscode.Hover(...)) - 高频查询结果要缓存,比如按
document.uri.toString() + position.line做 key 存进Map - 加超时兜底:
Promise.race([fetchHover(), new Promise(r => setTimeout(r, 800))]),避免 hang 死整个 hover 流程
自定义 Hover 和原生提示共存需手动合并
注册自己的 HoverProvider 后,原生类型提示、JSDoc、变量值预览默认就没了——VSCode 不会自动叠加,你得自己拉取并拼接。
实操建议:
- 别直接 return 新
Hover,先调用vscode.languages.getHoverProvider()找到已注册的 provider(如果有),手动触发它获取原始内容 - 把原生内容(
Hover.contents)和你新增的 MarkdownString 合并进同一个Hover实例 - 注意顺序:把用户最关心的信息放前面,比如先显示翻译结果,再附带类型信息
- 如果只想要增强、不覆盖,返回
undefined表示“我不处理,交给下一个 provider”
真正难的不是写几行 registerHoverProvider,而是判断该不该介入、何时介入、以及怎么跟语言服务器和平共处。很多插件 hover 失效,根本不是代码问题,是没想清楚自己到底在补全语义,还是在覆盖语义。











