补全请求的参数里有什么?
结论
textDocument/completion 的核心参数是文档 URI、光标位置,以及触发上下文。服务器用位置在自己的文档副本里取词,用触发种类判断这是字符触发、手动唤起还是补全项未完成时的再次请求。
展开
参数结构可以记成:
textDocument.uri:哪一份文档position:line和character,从 0 开始,字符偏移按 UTF-16 代码单元,和 VS Code 的Position一致context.triggerKind:手动调用、触发字符,或重新触发context.triggerCharacter:例如.、:、<
服务器不应该向客户端要全文,全文已经在 didOpen 和 didChange 之后的副本里。用 URI 找到副本,用 position 取光标前的标识符。
返回值是 CompletionItem[] 或带 isIncomplete 的列表。isIncomplete: true 表示列表是截断的,用户再输入时客户端应重新请求,不要把这份残缺列表一直过滤到底。
触发字符要在服务器能力的 triggerCharacters 里声明,客户端才会在这些字符输入后发请求。
和 VS Code 补全项的对应:textEdit 或 insertText 是插入内容,additionalTextEdits 是附加编辑,command 是插入后的命令。协议字段和 vscode.CompletionItem 由语言客户端转换。
容易讲错的点
- 位置是 UTF-16,不是字节,也不是 Unicode 码点。表情或生僻字会让「按字符数切片」偏掉。
- 没有
context的旧客户端也要能补全,触发字符只能当优化。 - 补全请求是请求,算得慢就要认
cancel。过期结果不能再写回。