vscode.languages.registercompletionitemprovider是核心入口,因vscode仅通过此api注册补全逻辑,不扫描代码或配置;须指定正确language id(如"typescript"非"ts"),并实现providecompletionitems方法。

为什么 vscode.languages.registerCompletionItemProvider 是核心入口
所有自定义补全逻辑都必须通过这个 API 注册,VSCode 不会主动扫描你的代码或配置文件来发现补全规则。不调用它,写再多 JSON 或正则都没用。
常见错误是只在 activate 函数里写了逻辑但忘了注册,结果插件装了却没任何提示。注册时要明确指定语言标识(如 "javascript"、"python"),不是文件后缀名;比如 TypeScript 文件要用 "typescript",不是 "ts"。
- 必须返回一个实现了
provideCompletionItems方法的对象 - 第二个参数(
triggerCharacters)决定何时弹出提示:填[".", "(", "/"]表示输入这些字符时触发;留空则只响应Ctrl+Space - 若想全局生效(所有语言),得对每种语言单独注册,不能传
"*"
如何让补全项带图标和分类(kind 和 detail 的实际作用)
kind 决定 VSCode 显示什么图标(如 vscode.CompletionItemKind.Function 显示小齿轮),但它**不控制排序**;排序由 sortText 字段决定,不是字母顺序也不是 kind 优先级。
detail 是灰色小字,适合放类型签名或来源说明;documentation(可为字符串或 MarkdownString)才是鼠标悬停时显示的完整说明。很多人把文档写进 detail,结果被截断看不全。
- 图标不显示?检查是否用了合法的
vscode.CompletionItemKind枚举值,自定义字符串无效 - 想分组显示(如“React Hooks”“工具函数”)?靠
commitCharacters或insertTextRules无法实现,得用vscode.CompletionList的isIncomplete配合多次请求模拟,但代价高,一般不推荐 - 中文文档渲染异常?用
new vscode.MarkdownString("<pre class="brush:js;toolbar:false;"> xxx") 包一层,避免换行丢失
本地 JSON 配置补全 vs 动态生成补全,哪种更实用
静态 JSON(如读取 snippets.json)启动快、逻辑简单,适合固定模板(如组件脚手架、API 调用样板);但无法响应当前光标位置的上下文(比如只在 useEffect 内提示依赖数组相关项)。
动态生成需要解析当前文档 AST 或正则提取上下文,开销明显。例如判断光标前是否为 axios.,就得用 document.getText(new vscode.Range(pos.line, 0, pos.line, pos.character)) 取行内容再匹配,而不是直接读整行——否则跨行注释会干扰。
- 性能敏感场景(如每键触发):避免同步读文件,提前缓存 JSON 内容到内存
- 想根据变量类型补全?别自己写类型推导,用
vscode.languages.getFoldingRanges或vscode.languages.getDocumentSemanticTokens获取结构信息更可靠 - 正则匹配容易漏边界:比如匹配
api.时,要排除// api.xxx或const api = ...中的误触发,加(? 和 <code>(?!\w)等负向断言
调试补全不出现的三个关键检查点
插件已安装、激活、注册,但补全就是不弹——问题大概率卡在这三处。
- 检查
package.json的contributes.languages是否声明了对应语言;没声明,VSCode 根本不会把该语言交给你的插件处理 - 打开命令面板(
Ctrl+Shift+P),运行Developer: Toggle Developer Tools,在 Console 里搜completion或你的插件名,看是否有TypeError或Cannot read property 'provideCompletionItems' - 在
provideCompletionItems开头加console.log(document.languageId, position),确认函数确实被调用;如果没输出,说明触发条件不满足(比如语言 ID 对不上,或triggerCharacters没覆盖到当前输入)
最常被忽略的是语言 ID 和工作区设置冲突:比如用户用 Prettier 格式化后,VSCode 把 .js 文件识别成 typescriptreact,而你只注册了 javascript,自然失效。











