跳到主要内容

为什么要有语言服务器协议?

结论​

语言服务器协议把「懂语言」和「懂编辑器」拆开。语言逻辑放在独立进程,编辑器只做客户端。一种语言写一次服务器,就能接到多个编辑器;编辑器也不必为每种语言内置一套插件内核。

展开​

没有这层协议时,TypeScript 的补全、跳转、诊断都要直接写进某个编辑器的插件 API。换一个编辑器就重写一遍,编辑器进程还得承担编译和类型检查。

有协议之后:

  • 服务器可以用任何语言实现,只要会 JSON-RPC。
  • VS Code 用 vscode-languageclient 当客户端,负责起进程、同步文档、把协议结果转成补全项和诊断。
  • 服务器崩溃可以单独重启。
  • 重计算离开扩展宿主,界面还能响应。

协议是语言无关的。方法名像 textDocument/completion、textDocument/definition,参数是文档 URI 和位置,不是 VS Code 的 TextDocument 对象。所以服务器不能调用 vscode.window。凡是弹窗、树、Webview,都留在客户端。

这和调试适配器协议是同一类想法:编辑器提供通用 UI,具体语言或调试器通过协议接入。

容易讲错的点​

  • 协议不负责语法着色的 TextMate 语法。着色表仍然是编辑器贡献点。
  • 服务器不是「把扩展宿主换个进程照写」。坐标、差异编辑、能力协商都要按协议来。
  • 一个扩展可以同时包着客户端和服务器,用户安装的仍是一个插件。协议边界在进程之间,不在市场列表上。