vscode代码补全由语言服务器(lsp)实时分析提供,未保存文件、lsp索引延迟、目录扫描干扰、completionitem的kind与inserttextformat设置不当、isincomplete未处理、sorttext缺失或triggercharacters不匹配,均会导致补全不更新或不显示。

VSCode 的代码补全不是编辑器自己猜的,而是由语言服务器(LSP)实时分析源码结构后返回的候选列表;关掉 LSP,IntelliSense 基本就只剩关键字和变量名回显。
为什么改了代码但补全不更新?
常见现象:新增一个 class 或导出函数后,其他文件里按 Ctrl+Space 仍看不到它。这不是 VSCode 卡了,而是语言服务器还没完成增量索引或缓存未失效。
- 多数 LSP(如
tsserver、pylsp、rust-analyzer)依赖文件系统事件(inotify/FileSystemWatcher)触发重分析,保存(Ctrl+S)是关键触发点,仅编辑不保存常被忽略 - 某些语言服务器禁用自动保存时会跳过增量更新,需手动检查设置中是否启用了
"files.autoSave": "onFocusChange"或类似选项 -
node_modules或__pycache__目录若被 LSP 错误纳入扫描范围,会导致分析阻塞——可通过"files.exclude"或语言专属配置(如"typescript.preferences.includePackageJsonAutoImports")限制
completionItem 的 kind 和 insertTextFormat 怎么影响实际补全行为?
补全项最终怎么插进代码,不只看文本,更取决于这两个字段。VSCode 渲染图标、决定是否展开括号、是否覆盖光标后内容,全靠它们。
-
kind是语义分类:12表示Method,7是Function,13是Constructor——不同kind触发不同默认insertText模板(比如方法自动加(),字段不加) -
insertTextFormat: 2(即Snippet)允许插入带 tabstop 的片段,例如console.log(${1:msg})$0;若设为1(PlainText),哪怕写成console.log()也会原样插入,无法跳转参数位 - 注意:部分客户端(如旧版 VSCode 或远程开发插件)对
Snippet支持不一致,调试时可临时把insertTextFormat改成1看是否恢复基础补全
自定义补全建议被拦截或不显示?查这三处
你写了 provideCompletionItems,也返回了数组,但用户就是看不到你的项——大概率卡在过滤或优先级环节。
- LSP 层返回的
CompletionList若含isIncomplete: true,VSCode 会等后续resolveCompletionItem调用才渲染,而很多轻量 LSP 实现直接忽略该流程,导致补全框空白 - VSCode 默认按
sortText排序,若所有项都未设该字段,排序逻辑退化为随机,你的补全可能被挤到页尾甚至不可见;建议至少设简单前缀(如a_、b_)控制位置 - 触发字符(
triggerCharacters)必须精确匹配输入末尾字符,比如注册了['.'],但用户输的是obj?.,问号后那个点不会触发——需额外注册['?', '.']或在doComplete中主动检测上下文
真正难调的从来不是“怎么返回补全项”,而是“为什么这个项没出现在第一屏”——sortText 权重、filterText 匹配逻辑、客户端对 isIncomplete 的处理差异,这些细节没有文档会逐条提醒你。











