自定义VSCode扩展中IntelliSense失效问题求助
VSCode LSP补全:对象成员补全不显示的解决方案
问题核心:当输入Record.触发补全时,服务端返回的成员名补全项(如test_id)被VSCode的过滤逻辑排除了——VSCode默认会用当前输入的前缀(Record.)匹配补全项的label,而成员名本身不包含该前缀,因此无法显示。
不需要给label硬加Record.前缀,正确的做法是利用LSP协议的filterText和textEdit字段来实现:
修改服务端补全逻辑代码
connection.onCompletion( (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] | undefined => { const document = documents.get(_textDocumentPosition.textDocument.uri); const linePrefix = document?.getText({ start: { line: _textDocumentPosition.position.line, character: 0 }, end: _textDocumentPosition.position, }); if(!linePrefix?.startsWith('Record.')){ const yamlComplete: CompletionItem[] = getCompletionFromYaml(); console.log(yamlComplete); return yamlComplete; } const recordPrefix = 'Record.'; // 计算Record.之后的起始位置,用于精准替换 const afterDotPosition = { line: _textDocumentPosition.position.line, character: linePrefix.indexOf(recordPrefix) + recordPrefix.length }; const output: CompletionItem[] = []; let i = 1; for(const currKey of tableData){ const keys = Object.keys(currKey); const fieldName = keys[0]; output.push({ label: fieldName, kind: CompletionItemKind.Field, data: i, documentation: 'test', // 让VSCode用包含Record.的文本进行过滤,确保补全能被匹配到 filterText: `${recordPrefix}${fieldName}`, // 精准替换Record.之后到光标位置的内容,避免重复插入前缀 textEdit: { range: { start: afterDotPosition, end: _textDocumentPosition.position }, newText: fieldName } }); i++; } console.log(output); return output; } );
关键字段说明
- filterText:指定VSCode用于过滤补全项的文本,这里设置为
Record.${fieldName},让VSCode能将用户输入的Record.与补全项匹配,从而显示结果。 - textEdit:定义插入补全项时的文本替换范围,精准替换
Record.之后到光标位置的内容,确保只插入成员名,不会重复添加Record.前缀。
如果不需要处理用户在Record.后输入部分字符的场景(比如Record.t),也可以只设置filterText字段,VSCode会默认插入label对应的文本,同样能解决问题。
内容的提问来源于stack exchange,提问作者Tumba
相关产品推荐
相关产品推荐

