neovim入门指南(四):LSP配置(下)
neovim入门指南(三):LSP配置 上 中说了 lsp 是什么如何配置和启动。那么接下来就完成 lsp 的其他配置。本章节主要介绍下面几个方面的介绍:代码高亮,文件格式化,lsp 相关的 UI 美化。
⚠️错误警告提示
在有了 lsp 之后,当我们编写代码发生错误的时候,就会有相应的提醒。如图下提示
目前的错误还是字母,例如警告是W
。不太美观。对于这个来说,vim 开放了相关的接口,可以通过接口进行设置, neovim-diagnostic。
仍旧在 lsp 的文件夹下建立 ui.lua 目录。
-- lsp/ui.lua
-- 对错误警告的图标
vim.diagnostic.config({
virtual_text = true,
signs = true,
-- 在输入模式下也更新提示,设置为 true 也许会影响性能
update_in_insert = true,
})
local signs = { Error = "", Info = "", Hint = "", Warn = "" }
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
其中 vim.diagnostic.config
是在配置提示文本,virtual_text
为错误信息提示.
🔅 代码高亮
目前的设置中,对于代码的高亮并不完美,需要采用一个插件了完成。tree-sitter
是一个用 rust 编写的高性能代码高亮的渲染工具,很多编辑器会采用它作为高亮功能的实现,比如说 Zed 。基于 tree sitter ,可以让我们的 neovim 的高亮更加完美。
这是来源于 nvim-treesitter 的一张图,图中左侧为未启用 treesitter 的代码高亮,右侧为启用后的效果。启用后的效果还是很明显的。
安装 tree-sitter 后,可以通过 TSInstall
来安装具体的语言高亮,例如 Rust 的高亮,可以直接使用 TSInstall rust
命令,或者使用 TSUpdate rust
命令进行更新。整体安装和配置还是比较简单的,这里不过多的解释。
📃 格式化
代码格式化是一个很重要的功能,也是我们使用频率很高的功能。针对 Neovim 的代码格式化有很多种方式。这里主要介绍 null-ls。不幸的是,null-ls 已经归档来,不再进行维护,万幸的是,它的 fork 项目 none-ls 重新维护起来,而且目前还兼容 null-ls 的配置,如果你之前使用的是 null-ls,那么只需要将依赖地址由 jose-elias-alvarez/null-ls.nvim
改为 nvimtools/none-ls.nvim
即可。
安装好 none-ls,后可以通过 Mason 安装相关的 formatter,例如安装 lua 的 formatter。通过命令 :Mason
打开安装界面。
选择 stylua,进行安装。安装完成后就可以进行配置,在 lua/lsp
下新建文件,命名为 nonels.lua
。
-- lsp/nonels.lua
-- 即使是采用了 none-ls, 这里也是获取 null-ls
local status, null_ls = pcall(require, "null-ls")
if not status then
vim.notify("没有找到 null-ls")
return
end
local formatters = null.builtins.format
null_ls.setup({
sources = {
-- Stylua
formatters.stylua,
-- 其他 formatter 方式
},
})
这样在我们进行编写代码的时候,进行相关格式化。在上一文中也进行了介绍,对快捷键进行了绑定。使用 <Leader>=
进行格式化。
🎨 自动补全美化
关于前面,介绍了通过 cmp 插件进行了自动补全,通过 cmp 可以补充不同来源的代码。
我们使用一些 IDE 或者编辑器的时候,在补全的选项中是会展示一些图标,用来标识补全项的类型,例如变量、类名、方法或是接口等。
RustRover 自动补充样式。
VS Code 自动补全样式。
通过配置,也可以让 neovim 的提示实现上图效果。
当前自动补全的效果如图,前面为补全的字段,后面通过文字来标识补全的类型。
有一个插件叫做 lspkind ,可以通过安装该插件结合我们的 cmp 完成上述的样式。
在 lsp 下新建文件 kind.lua,配置 kind,这个可以在 lspkind,找到相关配置。
-- lsp/kind.lua
local lspkind = require("lspkind")
lspkind.init({
mode = "symbol_text",
preset = "codicons",
symbol_map = {
Text = "",
Method = "",
Function = "",
Constructor = "",
Field = "",
Variable = "",
Class = "",
Interface = "",
Module = "",
Property = "",
Unit = "",
Value = "",
Enum = "",
Keyword = "",
Snippet = "",
Color = "",
File = "",
Reference = "",
Folder = "",
EnumMember = "",
Constant = "",
Struct = "",
Event = "",
Operator = "",
TypeParameter = ""
},
})
这里可以配置每个类别的图标,配置完成后在 cmp 中进行配置。主要是修改提示的样式。这里主要参考了 Github 上的一个样式,。在 formatting 中进行配置。
-- cmp.lua
cmp.setup({
-- 省略其他代码
formatting = {
completion = { border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, scrollbar = "║" },
documentation = {
border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" },
scrollbar = "║",
},
format = lspkind.cmp_format({
mode = "symbol",
maxwidth = 20,
ellipsis_char = "...",
before = function(entry, vim_item)
-- Get the full snippet (and only keep first line)
local word = entry:get_insert_text()
if entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then
word = vim.lsp.util.parse_snippet(word)
end
word = str.oneline(word)
if
entry.completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet
and string.sub(vim_item.abbr, -1, -1) == "~"
then
word = word .. "~"
end
vim_item.abbr = word
return vim_item
end,
}),
}
-- 省略其他代码
})
完成后的样式如图,基本和 VS Code 一样。
lspsage
lspsage 可以极大的提高 nvim lsp 的体验。lspsage 的功能基本都是在增强和美化原有的 lsp 。具体的文档可以查看 nvimdev。
lspsage 主要功能:
Finder: 用于高级 LSP 符号搜索的 UI
Diagnostic: 在诊断之间跳转并在漂亮的浮动窗口中显示它们
Peek Definition / Type Definition:查看定义/类型定义
悬停: 更漂亮的悬停操作
重命名: LSP 重命名和异步项目搜索和替换
调用层次传入/传出调用
Code Action: 具有实时预览的漂亮代码操作 UI
LightBulb: 类似 VSCode 的灯泡,指示可能的代码操作
面包屑: 类似于 WinBar 上的 IDE 符号纲要
大纲: 类似于 IDE 的符号纲要 实现: 轻松查看实现数量并快速跳转到它们
浮动终端: 一个简单的浮动终端
杂项: 适用于所有模块的选项
上面来自于官方文档的介绍。
Finder
Finder 的功能是一个类似 VS Code 的变量/函数 查看的界面,可以在界面上看到这个变量/函数的定义和调用地方。
-- keybindings.lua
-- 其他代码
pluginKeys.mapLSP = function(mapbuf) {
-- 其他代码
mapbuf("n", "gf", ":Lspsaga lsp_finder<CR>", opt) -- 新增
-- 其他代码
}
这样在 normal 情况下按下 gf
就会出现上面的 finder 窗口。
Code Action
Code Action 是一个非常重要的功能,可以根据代码上下文给出相关的提示或者代码改进。例如这块代码,Code Action 提醒我们可以直接转换为字面量的拼接。
Code Action 并不是 lspsaga 提供的,但是 lspsaga 给提供了一个漂亮的界面。在有 Code Action 的地方,会有一个黄色灯泡 💡 的提示。
下面绑定我们的快捷键。
-- keybindings.lua
pluginKeys.lspKeybinding = function(mapbuf)
-- 省略其他代码
-- code action
-- mapbuf("n", "<leader>ca", ":lua vim.lsp.buf.code_action()<CR>", opt) -- 原有的
mapbuf("n", "<leader>ca", ":Lspsaga code_action<CR>", opt) -- 替换为这个
end
Float Terminal
lspsaga 提供了一个浮动终端窗口,可以在终端上执行任何命令。可以在 keybindings 中绑定这个快捷键,或者直接使用默认的快捷键 t
,来进行终端的打开和关闭。
lspsaga 还提供了很多功能,基本每个功能对我们都有帮助,这里就不做过多介绍了,大家可以看官方文档。
这里基本介绍完了 lsp 的常见功能和配置,剩下的大家可以通过需要进行安装和配置。
这里是我的配置 youngxhui/nvim 大家可以适当参考。
小结
vim/neovim 使用的时候,的确是有一个较高的上手成本,尤其是方向键的习惯,当完全习惯了 h
,j
,k
和 l
进行光标移动的时候,其实就离入门 vim/neovim 不远了。
当习惯了 vim 这一套风格之后,就会尝试把手头的编辑器/IDE 的快捷键都采用 vim ,而且在熟悉 vim 的快捷键后,真正的感觉到了手指在键盘上飞舞。
无论是 neovim 还是相关插件,更新迭代是很快的,也许当你看到这篇文章的时候,上述的很多配置都已经失效,或者相关插件已经停止维护,文章只是抛砖引玉,我相信你会找到合适自己的 nvim 配置。
我相信喜欢 vim/neovim 的人都是有一颗专研,喜欢折腾的心。正是这样的心才陪伴这个你我一步一步前进。
写到这里有感而发,下一篇我们将会介绍 DAP 。
相关内容
如果你觉得这篇文章对你有所帮助,欢迎赞赏~
赞赏