跳到主要内容

语言服务器协议

语言服务器协议(Language Server Protocol,LSP)规定语言工具和编辑器怎么对话。语言服务器放在自己的进程里,用 JSON-RPC 收发请求。编辑器只实现一次客户端,就能接许多语言;一种语言服务器也能接到多个支持 LSP 的编辑器。

重计算离开扩展宿主后,不会把宿主的单线程堵住。服务器可以用任意语言编写。

在 VS Code 里的两半​

  • 语言客户端:一个普通扩展,跑在扩展宿主里,依赖 vscode-languageclient。激活后拉起服务器进程。
  • 语言服务器:独立进程,实现补全、诊断、定义等。常用 vscode-languageserver。

用户悬停时,VS Code 通知客户端,客户端向服务器发 Hover 请求,再把结果交回编辑器显示。

直接用 languages.registerXxxProvider 适合轻量功能。语法分析、跨文件索引、类型检查更适合 LSP。

和扩展 API 的对应关系​

官方文档把两侧对齐,例如:

扩展 API协议
registerHoverProviderHover
registerCompletionItemProviderCompletion、Completion Resolve
registerDefinitionProviderDefinition
registerReferencesProviderReferences
registerCodeActionsProviderCode Action
createDiagnosticCollection诊断的发布或按文档拉取
registerRenameProviderRename、Prepare Rename
registerDocumentFormattingEditProviderFormatting

文档同步与诊断方向​

打开的文档要同步给服务器。全量同步每次把整个文本送过去,实现简单。增量同步只送变更范围,大文件更合适,服务器要自己把补丁打上。

诊断有两种方向:

  • 推:服务器发 textDocument/publishDiagnostics。
  • 拉:服务器声明诊断提供器,客户端发 textDocument/diagnostic 来要。

生命周期要点​

服务器有启动、初始化、处理请求、关闭这几个阶段。请求应带取消令牌:用户继续输入时,过期的补全不该再占用服务器。服务器崩溃或扩展重载时,客户端要关掉旧进程、丢掉旧诊断,避免问题面板里留下上一轮的结果。

参考​