IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    neovim入门指南(四):LSP配置(下)

    youngxhui发表于 2024-03-01 16:06:25
    love 0

    neovim入门指南(三):LSP配置 上 中说了 lsp 是什么如何配置和启动。那么接下来就完成 lsp 的其他配置。本章节主要介绍下面几个方面的介绍:代码高亮,文件格式化,lsp 相关的 UI 美化。

    ⚠️错误警告提示

    在有了 lsp 之后,当我们编写代码发生错误的时候,就会有相应的提醒。如图下提示

    目前的错误还是字母,例如警告是W 。不太美观。对于这个来说,vim 开放了相关的接口,可以通过接口进行设置, neovim-diagnostic。

    仍旧在 lsp 的文件夹下建立 ui.lua 目录。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    -- 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。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    -- 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,找到相关配置。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    -- 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 中进行配置。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    -- 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 的变量/函数 查看的界面,可以在界面上看到这个变量/函数的定义和调用地方。

    1
    2
    3
    4
    5
    6
    7
    
    -- 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 的地方,会有一个黄色灯泡 💡 的提示。

    下面绑定我们的快捷键。

    1
    2
    3
    4
    5
    6
    7
    
    -- 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 。



沪ICP备19023445号-2号
友情链接