Neovim:语言服务、补全与格式化

本页目录

“代码有颜色”“能补全”“能跳到定义”和“能运行测试”来自不同组件。只有明确每一层负责什么,才能在某个功能失效时检查正确位置。

一次打开文件触发了什么

组件输入与职责不负责什么
文件类型检测根据文件识别 rust、lua 等类型不保证对应工具已安装
Treesitter parser解析语法结构,服务高亮、选区等功能不等于项目类型检查
LSP 客户端与服务器同步文档,提供定义、引用、诊断、重命名不自动执行全部测试
补全界面聚合并展示 LSP、片段等候选不产生所有语言语义
格式化器按规则重排文本不证明行为正确
DAP 客户端与 adapter协调断点、变量和运行控制不替代 SDK、可执行文件与调试符号

LazyVim 的语言 extra 连接这些组件中的一部分。标为 optional 的插件只有在安装后才会获得对应配置,外部运行时与项目依赖也要单独准备。LazyVim extras

先从一个语言开始

以 Rust 为例,先在终端确认项目能够通过 cargo check,再在 :LazyExtras 中启用 Rust 支持。若命令行本身无法找到工具链、解析依赖或编译项目,先解决这些问题,避免把所有错误归到编辑器。

打开 Cargo.toml 所在项目中的 .rs 文件,检查:

:set filetype?
:pwd
:lua print(vim.inspect(vim.lsp.get_clients({ bufnr = 0 })))

预期文件类型为 rust,当前 buffer 有相应语言客户端。:pwd 只是编辑器工作目录;LSP 根目录还应检查客户端的配置,二者不一定相同。Neovim LSP

大型 workspace 中,服务器可能以外层工作区作为根。只打开一个从项目中复制出来的文件,则可能缺少依赖和模块上下文。

验证语言能力

将光标放在项目中的函数调用处,依次检查定义、引用、悬浮文档和重命名。LazyVim 提供对应键位,但调试时也可以直接调用 API:

:lua vim.lsp.buf.definition()
:lua vim.lsp.buf.references()
:lua vim.lsp.buf.hover()

没有跳转结果不一定是客户端未启动:目标可能是关键字、不可解析的依赖或未索引的文件。先用一个已知存在的本地函数确认基本路径。

重命名会改动多个位置。操作后查看受影响 buffer,保存需要保留的修改,再通过 git diff 审阅。不要把候选框关闭或重命名请求返回成功当作最终正确性检查。

谁来格式化

LazyVim 常用 Conform 管理格式化。执行 :ConformInfo 可以查看当前文件配置了哪些 formatter、是否可执行及日志位置。

学习阶段可在 lua/config/options.lua 关闭保存时格式化:

vim.g.autoformat = false

需要时通过 LazyVim 的格式化动作触发,再检查 diff。项目提交了 .editorconfig、.clang-format、rustfmt.toml 等规则时,应优先遵循项目约定。

对 Lua 增加 StyLua 的插件覆盖示例,保存为 lua/plugins/formatting.lua:

return {
  {
    "stevearc/conform.nvim",
    opts = function(_, opts)
      opts.formatters_by_ft = opts.formatters_by_ft or {}
      opts.formatters_by_ft.lua = { "stylua" }
    end,
  },
}

它配置“使用哪个程序”,不代替 StyLua 的安装。不要再添加另一套保存自动命令同时调用 LSP 格式化,否则一次保存可能重复格式化或发生规则冲突。

诊断与测试不是同一层验证

LSP 可以指出语法、类型或静态分析问题,但边界条件和业务行为需要测试。编辑器没有红线并不证明程序符合需求。项目工作流用一个能正常编译、却在边界值上失败的函数演示这个区别。

调试则还需要可启动的目标、正确工作目录、参数和 adapter。先让相同目标在命令行运行,再配置 DAP;Rust、Go、C# 和 Java 使用不同的调试后端,不能只安装 nvim-dap 就期待所有语言都可调试。

排错顺序

  1. 文件类型⁠::set filetype? 是否符合实际文件?
  2. 项目上下文⁠:是否从正确项目打开,配置文件和依赖是否完整?
  3. 可执行文件⁠::lua print(vim.fn.exepath("rust-analyzer")) 是否有结果?某些插件使用自己指定的路径,应继续检查其配置。
  4. 客户端附着⁠:当前 buffer 是否有服务器,日志是否报告启动失败?
  5. 具体功能⁠:服务器是否支持该请求,问题是否仅发生在某个文件或依赖?
  6. 格式化与调试⁠:分别查 Conform、DAP 的工具和日志,不重复安装 LSP 碰运气。

每次只改变一个条件。能用日志和最小项目解释结果,再将修复合回日常配置。