neovim入门指南(三):LSP配置(上)
🧩 什么是 LSP
对于一个编辑器来说,如果要完成例如自动补全,查找相关定义等功能是需要进行大量的开发的。不同的编辑器为了不同的语言都需要进行开发,而 LSP 的存在就是将这个过程检化。LSP 的全称为 Language Server Protocol,定义了编辑器和语言服务之间使用的协议。只要相关语言支持 LSP,那么编辑器只要符合相关要求实现即可完成例如自动补全等功能,而且不同的编辑器使用的体验是一致的。
目前支持 LSP 的编辑器有很多,例如大名鼎鼎的 Vscode。当然 vim 8 以后版本和 neovim 也都支持,具体支持的编辑器/IDE 列表可以看 LSP 的官方网站,同时支持 LSP 的语言也可以找到 支持语言。
neovim 已经是支持 LSP 了,具体可以在相关的配置文档看到,该文档详细的描述了如何配置一个 LSP。相对来说,配置过程比较繁琐,所以官方又提供了另一个库 nvim-lspconfig。接下来我们就通过这个插件来配置 neovim 的 lsp。
nvim-lspconfig
与安装其他插件是一样的,只需要我们在 plugins_config.lua 中添加相关配置即可,这里不进行赘述了。安装完成后其实进行配置就可以启用 LSP 了,就是这么简单。例如支持 rust 的 LSP,只需要进行简单的配置。
|
|
但是,nvim 只是 lsp 的客户端,那么就存在 lsp 的服务端。上面配置的 rust_analyzer
就是 rust 语言的服务端,就需要我们进行服务端的安装。rust_analyzer
的服务端地址是 rust-lang/rust-analyzer,需要将服务端下载并且安装好,这样每次编写rust的时候就会享受 lsp 的服务加成了。
但是这样做有几个问题,当然也不能算问题,只是不太方便。
- 对于多语言使用者来说,需要手动安装多个 lsp 服务端,目前 lsp 的服务端应该是没有统一的下载安装地址,需要手动寻找;
- 每次服务端进行更新,都需要重新下载安装;
- 新换设备之后,无法开箱即用,需要重复上述的方式重新开始一次。
面对上面的不方便,你可能已经想到很多解决方法,例如写个脚本进行一键安装和更新常用的 lsp 服务端。这样基本解决了上面说的所有问题。正如你想的那样,今天的第二位主角 williamboman/mason.nvim。
🗃️ mason.nvim
mason 是一个可以方便的管理 LSP 服务端,DAP 服务端,Linter 和 格式化工具的插件。安装它之后,上面所说的问题将不是问题。
为了让 mason 和 nvim-lspconfig 更好的配合,这里还需要安装另一个插件 williamboman/mason-lspconfig.nvim
同样的安装这里不多赘述,主要是进行相关的配置。这里为了区别其他的插件,我们在 lua 目录下建立新的文件夹 lsp,用来专门存放 lsp 的配置。
配置 mason
首先还是加载我们的插件。在 lsp 文件夹中新建 mason.lua 文件,在文件中新增下面的配置。配置主要是在加载插件。
|
|
📤 安装 lsp 服务端
配置完成后,重新启动 nvim,此时就可以采用 mason 进行 LSP 的服务端进行管理了。只需要按下 :Mason
即可。你将会看到如下的界面。
通过界面上的帮助可以看到如何使用,通过数字可以选择不同的服务端项目,2 为 LSP , 3 为 DSP 等。今天只是使用 LSP,可以直接按 2,选择到 LSP 界面,进行 LSP 安装。仍旧是通过 j
和 k
进行滑动。第一个安装的 lsp 服务端为 lua 语言的服务端:lua-language-server。这个是 lua 语言的语言服务,有 lsp 之后,我们之后无论是配置 nvim 还是编写 lua 都会有 lsp 服务的加持。按下 i
进行安装。
稍等片刻,安装完成。接下来就是配置,让 nvim 知道我们的 lsp 已经安装,在合适的时候进行启动。
|
|
这样 lua 的 lsp 就配置成功了,当我们编写 lua 脚本的时候,如果发生错误就会有相关提醒。当然这只是 lsp 最基础的功能,例如代码跳转,代码补全等需要我们进行配置。
基本所有的 lsp 的配置都可以在 server_configurations.md 中找到,当然 lua_ls 也不例外,上面的配置就是直接从文档中复制的 😄。
当前的 LSP 配置已经支持代码跳转,code action 等功能。例如查看当前变量或者函数的文档,可以使用这个命令 :lua vim.lsp.buf.hover()
。
相关的命令还有其他
功能 | 命令 |
---|---|
文档显示 | :lua vim.lsp.buf.hover() |
查看定义 | :lua vim.lsp.buf.definition() |
重命名 | :lua vim.lsp.buf.rename() |
查询实现 | :lua vim.lsp.buf.implementation() |
查询引用 | :lua vim.lsp.buf.refreences() |
查询声明 | :lua vim.lsp.buf.declaration() |
格式化 | :lua vim.lsp.buf.format() |
Code action | :lua vim.lsp.buf.code_action() |
对于这些基础功能来说,每次需要的时候都在命令模式下敲一堆,速度的确是很慢的。所以,可以将上述的命令定义为快捷键,这样每次只需要进行快捷键进行完成上述功能。
⌨️ 快捷键绑定
打开我们之前设置快捷键的配置文件 keybinding.lua,新增上述功能的配置。
|
|
完成快捷键的配置,那么就可以将快捷键绑定到刚刚配置的 lsp 服务端了。
|
|
接下来可以完成快捷键的绑定。
|
|
这样就完成了 lua 的 lsp 的配置,在编写 lua 的时候就可以使用文档查看,code Action 等功能。
目前这些 lsp 的服务都要手动下载,对于一些日常使用的服务,我们可以通过配置,在第一次加载配置的时候,当机器上没有相关的服务的时候,自动下载,这样来说,基本实现了我们上述提出的问题。
|
|
这样配置,如果我们本地没有安装 lua 和 rust 的 lsp,会自动进行下载安装。
自动补全
直到目前,在 lsp 的加持下,其实编辑体验已经变得非常棒了,而且开发速率也会大幅提升,虽然 lsp 是支持自动补全功能的,但是上面其实一直没有提及。主要是单单靠 neovim 的功能还不够强大,需要插件的配置。
hrsh7th/nvim-cmp 是一个采用 lua 编写的补全引擎,通过 cmp 及 cmp 的相关插件,会将 neovim 的自动补全达到一个新的高度。
这里除了 nvim-cmp,再推荐几个 cmp 的相关插件。更多的相关插件可以在 wiki 中找到
- hrsh7th/cmp-nvim-lsp 对 lsp 提供的补全信息进行提示;
- hrsh7th/cmp-path 对文件内的路径进行补全;
- hrsh7th/cmp-vsnip 常见的代码 snip 片段。
配置补全
同样不赘述安装。在 lsp 文件夹中新建 cmp.lua 文件夹。
|
|
剩下了就可以将之前的补全源进行配置。这里贴出我的补全源。
|
|
此时当我们进行输入的时候就可以看到自动补全的提示了。对于自动补全的提示,上下选择并且上屏,我们可以设置快捷键,来满足我们的使用习惯。
和之前设置快捷键一样,在 keybindings.lua 中添加相关配置。
|
|
最后在 cmp.lua 中使用这些快捷键即可。
|
|
这样便可以完成自动补全的配置了。
小结
目前为止,已经完成 nvim 的 lsp 的相关配置,并且添加了自动补全。篇幅限制,剩下如何美化 lsp 提示,美化自动补全等我们下篇再说。
我的 neovim 相关配置,可以提供大家进行参考 youngxhui/nvim。