跳到正文

代码智能与语言服务器 ​

补全、跳转、悬停文档这些能力不属于编辑器,属于编辑器背后那台语言服务器。

LSP 是什么 ​

Language Server Protocol 规定编辑器与语言服务之间的消息格式:请求、响应、通知,全部用 JSON-RPC 编码,默认走标准输入输出,也可以走 TCP socket。编辑器启动时拉起一个 server 进程,双方交换能力清单,之后按需发问。

JSON RPC解析诊断通知编辑器语言服务器项目文件与依赖

这套协议的价值在于解耦。同一个 gopls 可以同时服务 VS Code、Neovim、Emacs,编辑器不必为每种语言实现一套解析器。

能力清单 ​

能力典型方法
补全textDocument/completion
悬停文档textDocument/hover
跳转定义textDocument/definition
查找引用textDocument/references
重命名符号textDocument/rename
整理 importtextDocument/codeAction
格式化textDocument/formatting
实时诊断textDocument/publishDiagnostics

诊断是 server 主动推送的通知,不是编辑器去问。所以你会看到「刚打开文件就有红线」,那是 server 解析完整个项目的结果,也解释了为什么大仓库第一次打开会卡几秒。

装哪个 server ​

语言server备注
PythonPylance 或 pyrightVS Code 里由 Python 扩展带
Gogopls官方维护
Rustrust-analyzer读 Cargo.toml
C/C++clangd依赖 compile_commands.json
TypeScripttypescript-language-server基于 tsserver
Lualua-language-serverNeovim 配置常用

有些语言装完扩展就能用,有些要额外告诉 server 项目在哪。C/C++ 是最典型的例子:没有 compile_commands.json,clangd 只能瞎猜头文件路径,跳转就时灵时不灵。

让它看见你的环境 ​

Python 是最容易出错的一类。系统里同时有 /usr/bin/python3、pyenv 的版本、项目的 .venv,server 默认可能选中了错的那个,于是导入全是红线、补全只剩关键字。

json
{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
  "python.analysis.typeCheckingMode": "basic"
}

在 VS Code 里也可以打开命令面板(Cmd-Shift-P)执行 Python: Select Interpreter,选中 .venv。Neovim 0.11 起用 vim.lsp.config 传参数、vim.lsp.enable 启用 server,配置里同样要写清 venvPath 与 venv,否则它还是看不见依赖。

:checkhealth 能看到 server 有没有启动、根目录识别成了哪里。多数「LSP 不工作」的问题出在根目录选错,而不是 server 装错。

与独立工具的分工 ​

格式化、lint、类型检查都能脱离编辑器单独跑。CI 里跑的是命令行,编辑器里跑的是同一个程序的 LSP 封装,两边规则不一致就会吵架。

工具职责常用命令
rufflint 加格式化ruff check --fix .
ruff format只做格式化ruff format .
mypy静态类型检查mypy src
gopls语言服务,也带 checkgopls check main.go

LSP 管语言智能,调试走另一个协议 DAP。编辑器同时接两个 server 很常见:一个给补全,一个给断点。