Neovim中LSP补全项不显示问题排查(自定义TS语言服务)
排查LSP补全未显示的问题
核心排查方向
1. LSP初始化时未声明补全能力
编辑器只会向明确声明支持textDocument/completion的服务器发送补全请求。如果你的服务器在初始化响应中没有配置completionProvider,编辑器根本不会触发补全请求——这是最常见的原因。
修复方式:在服务器的initialize处理函数中,添加补全能力声明:
export function initialize(): InitializeResult { return { capabilities: { hoverProvider: true, // 你已有的hover能力 completionProvider: { // 声明触发补全的字符,比如输入`-`(CSS变量的开头)或字母时触发 triggerCharacters: ['-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'], // 可选:如果需要延迟加载补全项,设置resolveProvider: true } } }; }
2. CompletionItem的配置不符合编辑器预期
你的补全项配置存在几个可能导致过滤失败的点:
- Kind类型错误:使用
CompletionItemKind.Snippet不合适,CSS变量属于变量类型,应该用CompletionItemKind.Variable。部分编辑器会根据kind过滤补全项,Snippet类型可能被默认隐藏。 - 缺少filterText字段:编辑器通常用
filterText来匹配用户输入,你当前仅靠label(无横杠的变量名),但有些编辑器的默认匹配逻辑可能依赖明确的filterText。 - Label显示与输入匹配问题:如果用户输入的是无横杠的字符串,你可以保留
filterText为无横杠值,同时让label显示原始带横杠的变量名,兼顾可读性和匹配性。
修复后的补全项映射代码:
.map(token => ({ label: `--${token.name}`, // 显示原始带横杠的变量名,更符合CSS习惯 filterText: token.name.replaceAll('-', ''), // 明确指定匹配用的无横杠文本,匹配用户输入 kind: CompletionItemKind.Variable, // 修正为正确的类型 insertText: `var(--${token.name})$0`, documentation: token.$description && { value: getTokenMarkdown(token), kind: MarkupKind.Markdown, }, }) satisfies CompletionItem);
3. 输入词获取或令牌加载异常
- 验证
getCSSWordAtPosition函数是否正确获取了光标位置的输入词:比如当输入rhcolorblue10时,是否返回了完整的字符串,而非空或截断的内容。可以在completion函数中添加日志打印word的值。 - 确认
getAllTokens()是否正确加载了所有设计令牌,比如包含rh-color-blue-10等目标项。
4. 查看LSP日志验证请求/响应流程
通过编辑器的LSP日志确认:
- Neovim中执行
:LspLog,查看日志文件中是否有textDocument/completion的请求记录。如果没有请求,说明服务器未声明补全能力;如果有请求但无响应或响应异常,再针对性排查响应结构。 - VSCodium/Zed中可以开启LSP日志,查看补全请求的发送和接收情况。
内容的提问来源于stack exchange,提问作者Benny Powers
相关产品推荐
相关产品推荐

