强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

LSP 开发指南 / 第 1 章:LSP 概述

1.1 历史背景

1.1.1 语言工具的碎片化时代

在 LSP 出现之前,每个编辑器都要为每种语言单独实现一套智能支持。下表展示了旧模式下的矩阵困境:

编辑器 \ 语言PythonJavaScriptGoRustJava
VS Code
Vim
Emacs
Sublime Text

如果有 M 个编辑器N 种语言,理论上需要实现 M × N 个集成。这导致了大量重复劳动,且每种实现的质量参差不齐。

1.1.2 LSP 的诞生

2016 年,微软联合 Red Hat、Codenvy 共同推出了 Language Server Protocol(LSP):

时间节点事件
2016 年 4 月LSP 0.1 发布,最初由微软为 VS Code 设计
2016 年 6 月LSP 1.0 正式发布,开源协议规范
2017 年LSP 2.0/3.0 发布,加入更多语言特性
2020 年LSP 3.16 成为主流稳定版本
2024 年LSP 3.17+ 持续演进

核心思想:将 M × N 问题降维为 M + N —— 每个编辑器实现一个通用 LSP 客户端,每种语言实现一个 Language Server。


1.2 设计动机

1.2.1 解耦语言智能与编辑器 UI

传统模式:
┌─────────────┐     ┌─────────────┐
│   VS Code    │────▶│  TypeScript  │  (紧耦合)
│   Extension  │◀────│  Language    │
└─────────────┘     └─────────────┘

LSP 模式:
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Editor     │────▶│  Language    │────▶│  Language    │
│   LSP Client │◀────│  Server      │◀────│  Analyzer    │
└─────────────┘     └─────────────┘     └─────────────┘
      通用协议           标准接口

1.2.2 设计原则

LSP 的设计遵循以下核心原则:

原则说明
协议标准化统一的消息格式(JSON-RPC 2.0)与语义定义
传输无关支持 stdio、TCP、WebSocket、pipe 等多种传输方式
能力协商客户端与服务端在初始化时交换支持的能力集合
渐进增强Server 可以逐步添加更多特性,无需一次性全部实现
语言无关Server 可以用任何语言编写(TypeScript、Python、Rust、Go…)

1.3 架构总览

1.3.1 整体架构

┌─────────────────────────────────────────────────────────┐
│                      编辑器 / IDE                         │
│  ┌──────────┐  ┌──────────────┐  ┌───────────────────┐  │
│  │ UI 渲染   │  │ LSP Client   │  │  用户交互层        │  │
│  │ 代码高亮  │  │ 消息收发      │  │  快捷键绑定        │  │
│  │ 弹窗显示  │  │ 能力映射      │  │  菜单项            │  │
│  └──────────┘  └──────┬───────┘  └───────────────────┘  │
│                       │ JSON-RPC over stdio/TCP/WS       │
└───────────────────────┼─────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────┐
│                   Language Server                         │
│  ┌──────────┐  ┌──────────────┐  ┌───────────────────┐  │
│  │ 协议层    │  │  语义分析     │  │  语言特性实现      │  │
│  │ 消息解析  │  │  AST 语法树   │  │  补全/跳转/诊断   │  │
│  │ 请求路由  │  │  类型系统     │  │  格式化/重构      │  │
│  └──────────┘  └──────────────┘  └───────────────────┘  │
└─────────────────────────────────────────────────────────┘

1.3.2 通信模型

LSP 使用 JSON-RPC 2.0 作为通信协议,支持三种消息类型:

// 1. Request(请求)— 需要对方响应
interface RequestMessage {
  jsonrpc: "2.0";
  id: number | string;    // 请求 ID,用于匹配响应
  method: string;          // 方法名,如 "textDocument/completion"
  params?: any;            // 参数
}

// 2. Response(响应)— 对请求的回复
interface ResponseMessage {
  jsonrpc: "2.0";
  id: number | string;    // 与请求的 ID 匹配
  result?: any;            // 成功时的结果
  error?: ResponseError;   // 失败时的错误
}

// 3. Notification(通知)— 单向消息,无需响应
interface NotificationMessage {
  jsonrpc: "2.0";
  method: string;          // 方法名,如 "textDocument/publishDiagnostics"
  params?: any;
}

1.4 生态现状

1.4.1 主流 Language Server

语言Server 名称维护方成熟度
TypeScript/JavaScripttypescript-language-server社区⭐⭐⭐⭐⭐
Pythonpylsp / pyright / ruff社区/微软⭐⭐⭐⭐⭐
GogoplsGo 官方⭐⭐⭐⭐⭐
Rustrust-analyzerRust 官方⭐⭐⭐⭐⭐
JavaEclipse JDT LSEclipse⭐⭐⭐⭐⭐
C/C++clangdLLVM⭐⭐⭐⭐⭐
Lualua-ls社区⭐⭐⭐⭐
Zigzls社区⭐⭐⭐⭐
CSS/SCSSvscode-css-languageserver微软⭐⭐⭐⭐

1.4.2 支持 LSP 的编辑器

编辑器LSP 客户端实现支持程度
VS Code内置完整支持
Neovim内置 (nvim-lspconfig)完整支持
Emacslsp-mode / eglot完整支持
Sublime TextLSP 插件完整支持
Helix内置完整支持
Zed内置完整支持
JetBrains IDE内置(自研为主)部分支持

1.4.3 LSP 与相关协议

LSP 并不是孤立的,它属于一个更大的工具协议生态:

协议全称用途
LSPLanguage Server Protocol编辑语言的智能功能
DAPDebug Adapter Protocol调试器适配协议
dapserver(非正式)代码审查服务
Tree-sitter增量语法解析(常与 LSP 配合使用)
┌─────────────────────────────────────────────┐
│                编辑器生态                     │
│                                             │
│  ┌───────────┐  ┌───────┐  ┌────────────┐  │
│  │    LSP    │  │  DAP  │  │ Tree-sitter│  │
│  │ 语言智能  │  │ 调试   │  │ 语法高亮   │  │
│  └───────────┘  └───────┘  └────────────┘  │
│       │              │            │         │
│       ▼              ▼            ▼         │
│  ┌──────────────────────────────────────┐   │
│  │         统一编辑器体验               │   │
│  └──────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

1.5 为什么现在学习 LSP?

  1. 行业标准:几乎所有新语言工具都优先支持 LSP
  2. 就业市场:IDE/编辑器岗位通常要求 LSP 经验
  3. 开源贡献:参与主流 Language Server 开发是高质量的开源贡献
  4. 架构启发:LSP 的"协议解耦"思想可以应用到更多场景

⚠️ 常见误区

误区事实
“LSP 只是 VS Code 的东西”LSP 是独立于 VS Code 的开放协议
“LSP 等于代码补全”补全只是 LSP 众多特性之一
“写 LSP Server 必须用 TypeScript”Server 可以用任何语言编写
“LSP 替代了编译器/解释器”LSP 建立在语言分析之上,不替代编译工具链

🔗 扩展阅读


下一章第 2 章:协议基础 — 深入了解 JSON-RPC 2.0、消息格式与传输层机制。