您的位置:首页 > 科技 > 能源 > Neovim 配置全面解析(下)

Neovim 配置全面解析(下)

2024/12/23 10:53:02 来源:https://blog.csdn.net/m0_69824302/article/details/139302401  浏览:    关键词:Neovim 配置全面解析(下)

Neovim 配置全面解析(下)

原文:Neovim 配置全面解析(下) - 知乎 (zhihu.com)

环境:Ubuntu 20.04

宿主机:windows (windows terminal)WSL 2

NVIM:v 0.10.0-dev

配置 Neovim 需要保证流畅的 github 环境(以便于快速拉取插件),可以使用代理或是配置 Github SSH key

本篇博客是学习掘金小册的学习笔记,有兴趣的朋友可以直接点击下文链接了解详情

小册链接: https://s.juejin.cn/ds/iFGpuLW6/

因为文章字数超出平台限制,所以教程分上下两章节

Neovim 配置全面解析(上) - 知乎 (zhihu.com)

Neovim 配置全面解析(下) - 知乎 (zhihu.com)

基于 LSP 代码补全及自定义代码段

相关插件:hrsh7th/nvim-cmp: A completion plugin for neovim coded in Lua. (github.com)

相关概念:

  1. 补全引擎

    补全引擎就是为 Neovim 提供代码补全核心功能的插件,比如 nvim-cmp
     

  1. 补全源

    补全源就是补全引擎需要的数据来源,最常见的来源是来自 Language Server 提供的数据,它会知道某个类有哪些属性和方法等。
     

  1. snippet 引擎

    snippet 引擎就是自定义代码段的引擎,常见的有 vsnipluasnip 等
     

添加插件

    -- 补全引擎use ("hrsh 7 th/nvim-cmp")-- snippet 引擎use ("hrsh 7 th/vim-vsnip")-- 补全源use ("hrsh 7 th/cmp-vsnip")use ("hrsh 7 th/cmp-nvim-lsp") -- { name = nvim_lsp }use ("hrsh 7 th/cmp-buffer") -- { name = 'buffer' },use ("hrsh 7 th/cmp-path") -- { name = 'path' }use ("hrsh 7 th/cmp-cmdline") -- { name = 'cmdline' }-- 常见编程语言代码段use ("rafamadriz/friendly-snippets")

注意:只有  hrsh 7 th/nvim-cmp 是补全引擎插件本身,其他  cmp-xxx 基本都是插件补全来源,也就是说当你输入一个变量的时候,可以从多个来源显示补全的内容。

像 hrsh 7 th/cmp-nvim-lsp 就是 Neovim 内置 LSP 提供的补全内容,hrsh 7 th/cmp-buffer 补全当前 buffer 的内容, hrsh 7 th/cmp-cmdline 是命令行的补全,hrsh 7 th/cmp-path 则是用来补全路径,如果配置了这个,当输入一个路径的时候会补全路径

创建lua/lsp/cmp. lua

local cmp = require ("cmp")cmp.setup ({-- 指定 snippet 引擎snippet = {expand = function (args)-- For `vsnip` users.vim. fn ["vsnip#anonymous"](args.body)-- For `luasnip` users.-- require ('luasnip'). lsp_expand (args. body)-- For `ultisnips` users.-- vim. fn ["UltiSnips#Anon"](args.body)-- For `snippy` users.-- require'snippy'. expand_snippet (args. body)end,},-- 补全源sources = cmp.config.sources ({{ name = "nvim_lsp" },-- For vsnip users.{ name = "vsnip" },-- For luasnip users.-- { name = 'luasnip' },--For ultisnips users.-- { name = 'ultisnips' },-- -- For snippy users.-- { name = 'snippy' },}, { { name = "buffer" }, { name = "path" } }),-- 快捷键设置mapping = require ("keybindings"). cmp (cmp),
})-- / 查找模式使用 buffer 源
cmp.setup.cmdline ("/", {mapping = cmp.mapping.preset.cmdline (),sources = {{ name = "buffer" },},
})-- : 命令行模式中使用 path 和 cmdline 源.
cmp.setup.cmdline (": ", {mapping = cmp.mapping.preset.cmdline (),sources = cmp.config.sources ({{ name = "path" },}, {{ name = "cmdline" },}),
})

lua/keybindings. lua添加

-- nvim-cmp 自动补全
pluginKeys. cmp = function (cmp)return {-- 出现补全["<A-.>"] = cmp.mapping (cmp.mapping.complete (), {"i", "c"}),-- 取消补全["<A-,>"] = cmp.mapping ({i = cmp.mapping.abort (),c = cmp.mapping.close ()}),-- 上一个["<C-k>"] = cmp. mapping. select_prev_item (),-- 下一个["<C-j>"] = cmp. mapping. select_next_item (),-- 确认["<CR>"] = cmp.mapping.confirm ({select = true,behavior = cmp. ConfirmBehavior. Replace}),-- 如果窗口内容太多,可以滚动["<C-u>"] = cmp.mapping (cmp. mapping. scroll_docs (-4), {"i", "c"}),["<C-d>"] = cmp.mapping (cmp. mapping. scroll_docs (4), {"i", "c"}),}
end

init. lua

require ("lsp. cmp") --  (新增)

LSP 功能增强

UI 插件,同时 lspage 还可以自定义快捷键,对于我自己而言我认为有些地方文字更加直观,如果有些朋友需要美化可自行查找

弹窗显示错误

当一行代码很长的时候,右侧的提示文字就会显示不全

之前配置过 gp 快捷键使用弹窗显示错误,可以有效解决

功能增强

相关插件:kkharji/lspsaga.nvim: The neovim language-server-client UI (github.com)

添加插件

    use ("tami 5/lspsaga. nvim" )

创建lua/lsp/ui. lua

local lspsaga = require 'lspsaga'
lspsaga. setup { -- defaults ...debug = false,use_saga_diagnostic_sign = true,-- diagnostic signerror_sign = "",warn_sign = "",hint_sign = "",infor_sign = "",diagnostic_header_icon = "   ",-- code action title iconcode_action_icon = " ",code_action_prompt = {enable = true,sign = true,sign_priority = 40,virtual_text = true,},finder_definition_icon = "  ",finder_reference_icon = "  ",max_preview_lines = 10,finder_action_keys = {-- open = "o",open = "<CR>",vsplit = "s",split = "i",-- quit = "q",quit = "<ESC>",scroll_down = "<C-f>",scroll_up = "<C-b>",},code_action_keys = {-- quit = "q",quit = "<ESC>",exec = "<CR>",},rename_action_keys = {-- quit = "<C-c>",quit = "<ESC>",exec = "<CR>",},definition_preview_icon = "  ",border_style = "single",rename_prompt_prefix = "➤",rename_output_qflist = {enable = false,auto_open_qflist = false,},server_filetype_map = {},diagnostic_prefix_format = "%d. ",diagnostic_message_format = "%m %c",highlight_prefix = false,
}

lua/keybindings. lua中的 mapLSP 函数替换为

-- lsp 回调函数快捷键设置
pluginKeys. mapLSP = function (mapbuf)-- rename--[[Lspsaga 替换 rnmapbuf ("n", "<leader>rn", "<cmd>lua vim.lsp.buf.rename ()<CR>", opt)--]]mapbuf ("n", "<leader>rn", "<cmd>Lspsaga rename<CR>", opt)-- code action--[[Lspsaga 替换 camapbuf ("n", "<leader>ca", "<cmd>lua vim. lsp. buf. code_action ()<CR>", opt)--]]mapbuf ("n", "<leader>ca", "<cmd>Lspsaga code_action<CR>", opt)-- go xx--[[mapbuf ('n', 'gd', '<cmd>Lspsaga preview_definition<CR>', opt)--]]mapbuf ("n", "gd", "<cmd>lua vim.lsp.buf.definition ()<CR>", opt)--[[Lspsaga 替换 ghmapbuf ("n", "gh", "<cmd>lua vim.lsp.buf.hover ()<CR>", opt)--]]mapbuf ("n", "gh", "<cmd>Lspsaga hover_doc<cr>", opt)--[[Lspsaga 替换 grmapbuf ("n", "gr", "<cmd>lua vim.lsp.buf.references ()<CR>", opt)--]]mapbuf ("n", "gr", "<cmd>Lspsaga lsp_finder<CR>", opt)--[[Lspsaga 替换 gp, gj, gkmapbuf ("n", "gp", "<cmd>lua vim. diagnostic. open_float ()<CR>", opt)mapbuf ("n", "gj", "<cmd>lua vim. diagnostic. goto_next ()<CR>", opt)mapbuf ("n", "gk", "<cmd>lua vim. diagnostic. goto_prev ()<CR>", opt)--]]-- diagnosticmapbuf ("n", "gp", "<cmd>Lspsaga show_line_diagnostics<CR>", opt)mapbuf ("n", "gj", "<cmd>Lspsaga diagnostic_jump_next<cr>", opt)mapbuf ("n", "gk", "<cmd>Lspsaga diagnostic_jump_prev<cr>", opt)mapbuf ("n", "<leader>f", "<cmd>lua vim.lsp.buf.format ({ bufnr = bufnr })<CR>", opt)-- 未用-- mapbuf ("n", "gD", "<cmd>lua vim.lsp.buf.declaration ()<CR>", opt)-- mapbuf ("n", "gi", "<cmd>lua vim.lsp.buf.implementation ()<CR>", opt)-- mapbuf ('n', '<leader>q', '<cmd>lua vim.diagnostic.setloclist ()<CR>', opt)-- mapbuf ("n", "<C-k>", "<cmd>lua vim. lsp. buf. signature_help ()<CR>", opt)-- mapbuf ('n', '<space>wa', '<cmd>lua vim. lsp. buf. add_workspace_folder ()<CR>', opt)-- mapbuf ('n', '<space>wr', '<cmd>lua vim. lsp. buf. remove_workspace_folder ()<CR>', opt)-- mapbuf ('n', '<space>wl', '<cmd>lua print (vim.inspect (vim. lsp. buf. list_workspace_folders ()))<CR>', opt)-- mapbuf ('n', '<space>D', '<cmd>lua vim. lsp. buf. type_definition ()<CR>', opt)
end

init. lua

require ("lsp. ui")

代码格式化

之前lua/keybindings. lua定义过格式化快捷键

mapbuf ("n", "<leader>f", "<cmd>lua vim.lsp.buf.format ({ bufnr = bufnr })<CR>", opt)

但是你会发现格式化不起作用,这是因为使用的 Lua Language Server 并没有实现格式化功能。

格式化方案有如下两种:

  • 第一种是使用专门的格式化插件;

  • 第二种是给 Language Server 注入格式化功能。

这里只讲解第二种

相关插件:jose-elias-alvarez/null-ls.nvim: Use Neovim as a language server to inject LSP diagnostics, code actions, and more via Lua. (github.com)

添加插件

    -- 代码格式化use ({ "jose-elias-alvarez/null-ls. nvim", requires = "nvim-lua/plenary. nvim" })

添加配置文件 lua/lsp/null-ls. lua

local status, null_ls = pcall (require, "null-ls")
if not status thenvim.notify ("没有找到 null-ls")return
endlocal formatting = null_ls. builtins. formattingnull_ls.setup ({debug = false,sources = {-- Formatting -----------------------  brew install shfmtformatting. shfmt,-- StyLuaformatting. stylua,-- frontendformatting.prettier.with ({ -- 只比默认配置少了 markdownfiletypes = {"javascript","javascriptreact","typescript","typescriptreact","vue","css","scss","less","html","json","yaml","graphql",},prefer_local = "node_modules/. bin",}),-- formatting. fixjson,-- formatting.black.with ({ extra_args = { "--fast" } }),},-- 保存自动格式化on_attach = function (client, bufnr)if client. supports_method ("textDocument/formatting") thenvim. api. nvim_clear_autocmds ({ group = augroup, buffer = bufnr })vim. api. nvim_create_autocmd ("BufWritePre", {group = augroup,buffer = bufnr,callback = function ()-- on 0.8, you should use vim.lsp.buf.format ({ bufnr = bufnr }) insteadvim.lsp.buf.format ({ bufnr = bufnr })-- vim. lsp. buf. formatting_sync ()end,})endend,
})

init. lua

require ("lsp. null-ls")

安装之后可以运行:LspInfo查看绑定的 Language Server

然后我们可以看到有两个 LSP 了,null-ls 作为通用 LSP,可以在任何 filetypes 中运行。

然后执行:NullLsInfo查看源的激活情况

之后的话即可使用: lua vim.lsp.buf.format ()命令或是直接使用快捷键<leader>f进行格式化

但是我们会发现包如下错误,这是因为相应语言应该配置相应的 Code Formatter,显示报错就是缺少 Lua 语言的 StyLua,其它语言可以自行配置相应的 Formatter

下面展示如何配置 stylua

配置环境

stylua 需要配置 rust 环境,rust 官网:安装 Rust - Rust 程序设计语言 (rust-lang.org)

因为我是使用 WSL,因此直接执行如下命令即可

curl --proto '=https' --tlsv 1.2 -sSf https://sh.rustup.rs | sh

执行source "$HOME/. cargo/env"

执行rustc --version看是否成功,失败则看是否添加~/. cargo/bin路径到环境变量中

安装步骤

执行

cargo install stylua

输出stylua -V看是否成功

出现问题

格式化之后里面的空格就都变成了"^I", 原本应该是“·”的

直接将basic. lua文件中设置vim. o. listchars = "space:·, tab:··"或是设置vim. o. list = false

前端开发必要配置

配置语法高亮

执行: TSInstall css scss json html vue javascript typescript

执行:TSInstallInfo查看安装情况

配置 LSP

lua/lsp/setup. lua

mason_config.setup ({ensure_installed = {"lua_ls", "html", "cssls"}
})
...
local servers = {lua_ls = require ("lsp. config. lua"),-- 新增html = require ("lsp. config. html"),cssls = require ("lsp. config. css")
}

创建lsp/common-config. lua

local M = {}M.keyAttach = function (bufnr)local function buf_set_keymap (mode, lhs, rhs)vim.keymap.set (mode, lhs, rhs, { noremap = true, silent = true, buffer = bufnr })end-- 绑定快捷键require ("keybindings"). mapLSP (buf_set_keymap)
end-- 禁用格式化功能,交给专门插件插件处理
M.disableFormat = function (client)if vim.fn.has ("nvim-0.8") == 1 thenclient. server_capabilities. documentFormattingProvider = falseclient. server_capabilities. documentRangeFormattingProvider = falseelseclient. resolved_capabilities. document_formatting = falseclient. resolved_capabilities. document_range_formatting = falseend
end-- M.capabilities = require ("cmp_nvim_lsp"). update_capabilities (vim. lsp. protocol. make_client_capabilities ())
M.capabilities = require ("cmp_nvim_lsp"). default_capabilities ()M.flags = {debounce_text_changes = 150,
}return M

创建lsp/config/html. lua

local common = require ("lsp. common-config")
local opts = {capabilities = common. capabilities,flags = common. flags,on_attach = function (client, bufnr)-- 禁用本身语言格式化common.disableFormat (client)common.keyAttach (bufnr)end,
}
return {on_setup = function (server)server.setup (opts)end,
}

创建lsp/config/css. lua

local common = require ("lsp. common-config")
local opts = {capabilities = common. capabilities,flags = common. flags,on_attach = function (client, bufnr)common.disableFormat (client)common.keyAttach (bufnr)end,settings = {css = {validate = true,-- tailwindcsslint = {unknownAtRules = "ignore",},},less = {validate = true,lint = {unknownAtRules = "ignore",},},scss = {validate = true,lint = {unknownAtRules = "ignore",},},},
}return {on_setup = function (server)server.setup (opts)end,
}

上面不禁用的话也是可以的,只不过会和默认的 null-ls 中的 prettier 格式化冲突,每次格式化都需要选择

注意 html、css 文件均是需要项目根目录有package. json文件和 prettier 依赖

# 创建 package. json 并安装 prettier 依赖,顺便把 eslint 也配置上
npm init -y && npm i -D prettier eslint

Emmet LSP 配置

使用 emmet 可是使用简单的语法可以快速打出 HTML 结构标签

创建lua/lsp/config/emmet. lua

local opts = {filetypes = { "html", "typescriptreact", "javascriptreact", "css", "sass", "scss", "less" },
}
return {on_setup = function (server)server.setup (opts)end,
}

lua/lsp/setup. lua修改

mason_config.setup ({ensure_installed = {"lua_ls", "html", "cssls", "emmet_ls"}
})
...
local servers = {lua_ls = require ("lsp. config. lua"),html = require ("lsp. config. html"),cssls = require ("lsp. config. css"),-- 新增emmet_ls = require ("lsp. config. emmet")
}

配置 jsonls

JSON Schema Store 插件,即 JSON 增强包

plugins. lua添加插件

-- JSON 增强
use ("b 0 o/schemastore. nvim")

新建lua/lsp/config/json. lua

local common = require ("lsp. common-config")
local opts = {capabilities = common. capabilities,flags = common. flags,on_attach = function (client, bufnr)-- use fixjson to format-- https://github.com/rhysd/fixjsoncommon.disableFormat (client)common.keyAttach (bufnr)end,settings = {json = {schemas = require ("schemastore"). json.schemas (),},},
}return {on_setup = function (server)server.setup (opts)end,
}

lsp/config/setup. lua修改

mason_config.setup ({ensure_installed = {"lua_ls", "html", "cssls", "emmet_ls","jsonls"}
})local servers = {lua_ls = require ("lsp. config. lua"),html = require ("lsp. config. html"),cssls = require ("lsp. config. css"),emmet_ls = require ("lsp. config. emmet"),-- 新增jsonls = require ("lsp. config. json")
}

配置 tssserver

添加 TS 增强包插件

use ({ "jose-elias-alvarez/nvim-lsp-ts-utils", requires = "nvim-lua/plenary. nvim" })

创建lsp/config/ts. lua

local common = require ("lsp. common-config")
local keybindings = require ("keybindings")
local ts_utils = require ("nvim-lsp-ts-utils")
local opts = {flags = common. flags,capabilities = common. capabilities,-- https://github.com/jose-elias-alvarez/nvim-lsp-ts-utils/blob/main/lua/nvim-lsp-ts-utils/utils.lua-- 传入 tsserver 初始化参数-- make inlay hints workinit_options = {hostInfo = "neovim",preferences = {includeInlayParameterNameHints = "all",includeInlayParameterNameHintsWhenArgumentMatchesName = true,includeInlayFunctionParameterTypeHints = true,includeInlayVariableTypeHints = true,includeInlayPropertyDeclarationTypeHints = true,includeInlayFunctionLikeReturnTypeHints = true,includeInlayEnumMemberValueHints = true,},},on_attach = function (client, bufnr)common.disableFormat (client)common.keyAttach (bufnr)-- defaultsts_utils.setup ({debug = false,disable_commands = false,enable_import_on_completion = false,-- import allimport_all_timeout = 5000, -- ms-- lower numbers = higher priorityimport_all_priorities = {same_file = 1, -- add to existing import statementlocal_files = 2, -- git files or files with relative path markersbuffer_content = 3, -- loaded buffer contentbuffers = 4, -- loaded buffer names},import_all_scan_buffers = 100,import_all_select_source = false,-- if false will avoid organizing importsalways_organize_imports = true,-- filter diagnosticsfilter_out_diagnostics_by_severity = {},-- https://github.com/microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.jsonfilter_out_diagnostics_by_code = {80001,},-- inlay hintsauto_inlay_hints = true,inlay_hints_highlight = "Comment",inlay_hints_priority = 200, -- priority of the hint extmarksinlay_hints_throttle = 150, -- throttle the inlay hint requestinlay_hints_format = { -- format options for individual hint kindType = {},Parameter = {},Enum = {},-- Example format customization for `Type` kind:-- Type = {--     highlight = "Comment",--     text = function (text)--         return "->" .. text: sub (2)--     end,-- },},-- update imports on file moveupdate_imports_on_move = false,require_confirmation_on_move = false,watch_dir = nil,})-- required to fix code action ranges and filter diagnosticsts_utils. setup_client (client)-- no default maps, so you may want to define some herekeybindings.mapTsLSP (bufnr)end,
}return {on_setup = function (server)server.setup (opts)end,
}

同样setup. lua修改

mason_config.setup ({ensure_installed = {"lua_ls", "html", "cssls", "emmet_ls", "jsonls", "tsserver"}
})-- 安装列表
-- { key: 服务器名, value: 配置文件 }
-- key 必须为下列网址列出的 server name,不可以随便写
-- https://github.com/williamboman/nvim-lsp-installer#available-lsps
local servers = {lua_ls = require ("lsp. config. lua"),html = require ("lsp. config. html"),cssls = require ("lsp. config. css"),emmet_ls = require ("lsp. config. emmet"),jsonls = require ("lsp. config. json"),-- 新增tsserver = require ("lsp. config. ts")
}

添加快捷键lua/keybindings. lua

-- typescript 快捷键
pluginKeys. mapTsLSP = function (mapbuf)mapbuf ("n", "gs", ":TSLspOrganize<CR>", opt)mapbuf ("n", "gr", ":TSLspRenameFile<CR>", opt)mapbuf ("n", "gi", ":TSLspImportAll<CR>", opt)
end

  • gs 删除不用的 import 语句并重新排序。

  • gr 用于改变文件名,同时其他文件中引用该文件的文件名也会被修改。

  • gi 导入当前文件的所有依赖,并且会自动排序

ESLint 和 Prettier 配置

null-ls 中除了格式化 Formatting,还有 Diagnostics(红字错误提示) 和 Code Actions(代码触发的行为)

lsp/null-ls. lua修改为

local status, null_ls = pcall (require, "null-ls")
if not status thenvim.notify ("没有找到 null-ls")return
endlocal formatting = null_ls. builtins. formatting
local diagnostics = null_ls. builtins. diagnostics
local code_actions = null_ls. builtins. code_actionsnull_ls.setup ({debug = false,sources = { -- Formatting -----------------------  brew install shfmtformatting. shfmt, -- StyLuaformatting. stylua, -- frontendformatting.prettier.with ({ -- 只比默认配置少了 markdownfiletypes = {"javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "css", "scss", "less","html", "json", "yaml", "graphql"},prefer_local = "node_modules/. bin"}), -- Diagnostics  ---------------------diagnostics.eslint.with ({prefer_local = "node_modules/. bin"}), -- code actions ---------------------code_actions. gitsigns, code_actions.eslint.with ({prefer_local = "node_modules/. bin"})},-- #{m}: message-- #{s}: source name (defaults to null-ls if not specified)-- #{c}: code (if available)diagnostics_format = "[#{s}] #{m}",-- 保存自动格式化on_attach = function (client, bufnr)if client. supports_method ("textDocument/formatting") thenvim. api. nvim_clear_autocmds ({group = augroup,buffer = bufnr})vim. api. nvim_create_autocmd ("BufWritePre", {group = augroup,buffer = bufnr,callback = function ()-- on 0.8, you should use vim.lsp.buf.format ({ bufnr = bufnr }) insteadvim.lsp.buf.format ({bufnr = bufnr})-- vim. lsp. buf. formatting_sync ()end})endend
})

code_actions. gitsigns 没有安装可以注释掉

使用<leader>ca调用 Code Action 自动修复快捷键

Rust 开发配置

前文已安装 rust 环境,此处不赘述

语法高亮

plugin-config/nvim-treesitter. lua中的 ensure_installed 中添加"rust"

或是执行: TSInstall rust

代码提示

lsp/setup. lua

mason_config.setup ({ensure_installed = {"lua_ls", "html", "cssls", "emmet_ls", "jsonls", "rust_analyzer"}
})
...
local servers = {-- 新增rust_analyzer = require ("lsp. config. rust"),
}

lsp/config/rust. lua

local common = require ("lsp. common-config")
local opts = {capabilities = common. capabilities,flags = common. flags,on_attach = function (client, bufnr)common.disableFormat (client)common.keyAttach (bufnr)end,settings = {-- to enable rust-analyzer settings visit:-- https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/generated_config.adoc["rust-analyzer"] = {-- enable clippy on savecheckOnSave = {command = "clippy",},},},
}return {on_setup = function (server)local ok_rt, rust_tools = pcall (require, "rust-tools")if not ok_rt thenprint ("Failed to load rust tools, will set up `rust_analyzer` without `rust-tools`.")server.setup (opts)else-- We don't want to call lspconfig. rust_analyzer.setup () when using rust-toolsrust_tools.setup ({server = opts,-- dap = require ("dap. nvim-dap. config. rust"),})endend,
}

添加 Rust 增强包插件

-- Rust 增强
use ("simrat 39/rust-tools. nvim")

代码格式化

安装相应 Formtter

rustup component add rustfmt

null-ls. lua

source 中添加

-- rustfmt
formatting. rustfmt,

filetypes 中添加"rust"

配置 C/C++开发环境

熟悉上面的流程,这个就简单讲了

相关插件:p00f/clangd_extensions.nvim: Clangd's off-spec features for neovim's LSP client. Use https://sr.ht/~p00f/clangd_extensions.nvim instead (github.com)

setup. lua

servers 添加 “c”和“cpp”

安装格式化插件:apt-get install -y clang-format

plugin-config/nvim-treesitter. lua

ensure_installed 添加 “cpp” "c"

null-ls. lua

                formatting.prettier.with ({filetypes = {"c","cpp"}}),-- clang-formatformatting. clang_format,

lsp/config/clangd. lua

local common = require ("lsp. common-config")
local opts = {capabilities = common. capabilities,flags = common. flags,on_attach = function (client, bufnr)common.disableFormat (client)common.keyAttach (bufnr)end,
}return {on_setup = function (server)local ok_rt, clangd_extensions = pcall (require, "clangd_extensions")if not ok_rt thenserver.setup (opts)elseclangd_extensions.setup ({server = opts,extensions = {-- defaults:-- Automatically set inlay hints (type hints)autoSetHints = true,-- These apply to the default ClangdSetInlayHints commandinlay_hints = {-- Only show inlay hints for the current lineonly_current_line = false,-- Event which triggers a refersh of the inlay hints.-- You can make this "CursorMoved" or "CursorMoved, CursorMovedI" but-- not that this may cause  higher CPU usage.-- This option is only respected when only_current_line and-- autoSetHints both are true.only_current_line_autocmd = "CursorHold",-- whether to show parameter hints with the inlay hints or notshow_parameter_hints = true,-- prefix for parameter hintsparameter_hints_prefix = "<- ",-- prefix for all the other hints (type, chaining)other_hints_prefix = "=> ",-- whether to align to the length of the longest line in the filemax_len_align = false,-- padding from the left if max_len_align is truemax_len_align_padding = 1,-- whether to align to the extreme right or notright_align = false,-- padding from the right if right_align is trueright_align_padding = 7,-- The color of the hintshighlight = "Comment",-- The highlight group priority for extmarkpriority = 100,},ast = {-- These are unicode, should be available in any fontrole_icons = {type = " ",declaration = " ",expression = " ",statement = ";",specifier = " ",["template argument"] = " ",},kind_icons = {Compound = " ",Recovery = " ",TranslationUnit = " ",PackExpansion = " ",TemplateTypeParm = " ",TemplateTemplateParm = " ",TemplateParamObject = " ",},--[[ These require codicons ( https://github.com/microsoft/vscode-codicons )role_icons = {type = "",declaration = "",expression = "",specifier = "",statement = "",["template argument"] = "",},kind_icons = {Compound = "",Recovery = "",TranslationUnit = "",PackExpansion = "",TemplateTypeParm = "",TemplateTemplateParm = "",TemplateParamObject = "",}, ]]highlights = {detail = "Comment",},},memory_usage = {border = "none",},symbol_info = {border = "none",},},})endend,
}

代码运行器

相关插件:CRAG666/code_runner.nvim: Neovim plugin.The best code runner you could have, it is like the one in vscode but with super powers, it manages projects like in intellij but without being slow (github.com)

添加插件:

use 'CRAG 666/code_runner. nvim'

配置插件plugin-config/code-runner. lua

local status, code_runner = pcall (require, "code_runner")
if not status thenvim.notify ("没有找到 code_runner")return
endcode_runner.setup ({-- choose default mode (valid term, tab, float, toggle)mode = "term",-- Focus on runner window (only works on toggle, term and tab mode)focus = true,-- startinsert (see ': h inserting-ex')startinsert = false,term = {--  Position to open the terminal, this option is ignored if mode is tabposition = "bot",-- window size, this option is ignored if tab is truesize = 8,},float = {-- Key that close the code_runner floating windowclose_key = "<ESC>",-- Window border (see ': h nvim_open_win')border = "none",-- Num from `0 - 1` for measurementsheight = 0.8,width = 0.8,x = 0.5,y = 0.5,-- Highlight group for floating window/border (see ': h winhl')border_hl = "FloatBorder",float_hl = "Normal",-- Transparency (see ': h winblend')blend = 0,},filetype_path = "", -- No default path definedbefore_run_filetype = function ()vim.cmd (": w")end,filetype = {javascript = "node",java = {"cd $dir &&","javac $fileName &&","java $fileNameWithoutExt",},c = {"cd $dir &&","gcc $fileName","-o $fileNameWithoutExt &&","$dir/$fileNameWithoutExt",},cpp = {"cd $dir &&","g++ $fileName","-o $fileNameWithoutExt &&","$dir/$fileNameWithoutExt",},python = "python -u",sh = "bash",rust = {"cd $dir &&","rustc $fileName &&","$dir/$fileNameWithoutExt",},},project_path = "", -- No default path definedproject = {},
})

之后 init. lua 中添加插件,最后添加快捷键,使用空格加r即可运行代码

-- 代码运行器
map ('n', '<leader>r', ':RunCode<CR>', { noremap = true, silent = false })

其他配置

自动补全括号

插件仓库:windwp/nvim-autopairs: autopairs for neovim written by lua (github.com)

引入插件

use ("windwp/nvim-autopairs")

创建lua/plugin-config/nvim-autopairs. lua

-- https://github.com/windwp/nvim-autopairs
local status, autopairs = pcall (require, "nvim-autopairs")
if not status thenvim.notify ("没有找到 nvim-autopairs")return
end
autopairs.setup ({check_ts = true,ts_config = {lua = { "string" }, -- it will not add a pair on that treesitter nodejavascript = { "template_string" },java = false, -- don't check treesitter on java},
})
-- If you want insert `(` after select function or method item
local cmp_autopairs = require ("nvim-autopairs. completion. cmp")
local cmp = require ("cmp")
cmp.event: on ("confirm_done", cmp_autopairs. on_confirm_done ({ map_char = { tex = "" } }))

init. lua

快速注释插件

插件仓库:numToStr/Comment.nvim: // Smart and powerful comment plugin for neovim. Supports treesitter, dot repeat, left-right/up-down motions, hooks, and more (github.com)

添加插件

use ("numToStr/Comment. nvim")

创建lua/plugin-config/comment. lua

local status, comment = pcall (require, "Comment")
if not status thenvim.notify ("没有找到 Comment")return
endlocal default_opts = {---Add a space b/w comment and the line---@type boolean|fun ():booleanpadding = true,---Whether the cursor should stay at its position---NOTE: This only affects NORMAL mode mappings and doesn't work with dot-repeat---@type booleansticky = true,---Lines to be ignored while comment/uncomment.---Could be a regex string or a function that returns a regex string.---Example: Use '^$' to ignore empty lines---@type string|fun ():stringignore = nil,---LHS of toggle mappings in NORMAL + VISUAL mode---@type tabletoggler = {---Line-comment toggle keymapline = "gcc",---Block-comment toggle keymapblock = "gbc",},---LHS of operator-pending mappings in NORMAL + VISUAL mode---@type tableopleader = {---Line-comment keymapline = "gc",---Block-comment keymapblock = "gb",},---LHS of extra mappings---@type tableextra = {---Add comment on the line aboveabove = "gcO",---Add comment on the line belowbelow = "gco",---Add comment at the end of lineeol = "gcA",},---Create basic (operator-pending) and extended mappings for NORMAL + VISUAL mode---NOTE: If `mappings = false` then the plugin won't create any mappings---@type boolean|tablemappings = {---Operator-pending mapping---Includes `gcc`, `gbc`, `gc[count]{motion}` and `gb[count]{motion}`---NOTE: These mappings can be changed individually by `opleader` and `toggler` configbasic = true,---Extra mapping---Includes `gco`, `gcO`, `gcA`extra = false,---Extended mapping---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`extended = false,},---Pre-hook, called before commenting the line---@type fun (ctx: Ctx):stringpre_hook = nil,---Post-hook, called after commenting is done---@type fun (ctx: Ctx)post_hook = nil,
}-- 关闭了 extra 快捷键,只用 keybindings 里定义的基础快捷键
comment.setup (vim. tbl_deep_extend ("force", default_opts, require ("keybindings"). comment))

定义快捷键 keybindings. lua gcc 快捷键作为行注释,gbc 快捷键作为块注释

-- 代码注释插件
-- see ./lua/plugin-config/comment. lua
pluginKeys. comment = {-- Normal 模式快捷键toggler = {line = "gcc", -- 行注释block = "gbc", -- 块注释},-- Visual 模式opleader = {line = "gc",bock = "gb",},
}

init. lua中引入

require ("plugin-config. comment")

Surround 配置

引入插件

    -- surrounduse ("ur 4 ltz/surround. nvim")

lua/plugin-config/surround. lua

local status, surround = pcall (require, "surround")
if not status thenvim.notify ("没有找到 surround")return
endsurround.setup ({mappings_style = "surround",
})

init. lua

surround 官方快捷键如下

Normal Mode - Sandwich Mode
Provides key mapping to add surrounding characters. ( visually select then press s<char> or press sa{motion}{char})
Provides key mapping to replace surrounding characters. ( sr<from><to> )
Provides key mapping to delete surrounding characters. ( sd<char> )
ss repeats last surround command.
Normal Mode - Surround Mode
Provides key mapping to add surrounding characters. ( visually select then press s<char> or press ys{motion}{char})
Provides key mapping to replace surrounding characters. ( cs<from><to> )
Provides key mapping to delete surrounding characters. ( ds<char> )
Insert Mode
<c-s><char> will insert both pairs in insert mode.
<c-s><char><space> will insert both pairs in insert mode with surrounding whitespace.
<c-s><char><c-s> will insert both pairs on newlines insert mode.

常用快捷键

  • ds<char>

  • cs<from><to>

  • ys{motion}{char}

其他问题

我在推送仓库时频繁遇到GnuTLS recv error (-110)

解决链接:git - GnuTLS recv error (-110)

#!/bin/bash
set -e
sudo apt-get install build-essential fakeroot dpkg-dev -y
sudo apt-get build-dep git -y
sudo apt-get install libcurl 4-openssl-dev -y
cd ~
mkdir source-git
cd source-git/
apt-get source git
cd git-2.*.*/
sed -i -- 's/libcurl 4-gnutls-dev/libcurl 4-openssl-dev/' ./debian/control
sed -i -- '/TEST\s*=\s*test/d' ./debian/rules
dpkg-buildpackage -rfakeroot -b -uc -us
sudo dpkg -i ../git_*ubuntu*. deb

直接运行这个脚本即可

之后推送遇到remote: Support for password authentication was removed on August 13, 2021问题,虽然我不太清楚我配了 SSH key,为什么还是走的密码验证,但是我还是按照他的提示来做获取token,直接 github 首页中 Setting->Developer settings->Personal access tokens 生成 token

执行

git remote set-url origin https://<your_token>@github. com/<USERNAME>/<REPO>.git

最后即可免密推送

备忘记录

学习 vim 快捷键网站:Vim Cheat Sheet (rtorr.com)

使用: h clipboard查看复制粘贴命令

文档推荐使用set clipboard=unnamedplus,或是执行set clipboard^=unnamed, unnamedplus就可以连通 vim 剪切板和系统剪切板,但是这个命令只是暂时性的,只能当前页面生效,为了永久生效,可以在basic. lua中添加

-- 复制粘贴联通系统粘贴板
vim. o. clipboard = "unnamedplus"

全选复制文件:%y或是ggyG

只是删除而不将删除的部分复制到剪切板中"_dd(本质上是将剪切的内容放到_寄存器中,以便于和+寄存器区分)

结语

对我自己而言,配置的这些功能虽然少,但是暂时够用,如果追求更多的功能,可以直接用小册作者的仓库,或是其他优秀仓库

其实我觉得其实作为个人使用来说,没有特殊需求的情况下不是很推荐自己配置,只需要看懂本篇博客,然后可以做到更改别人写好的配置即可

还有就是切忌盲目复制粘贴,一定要看官方文档

本篇博客示例配置仓库:ReturnTmp/rettmp-nvim

掘金小册作者仓库: https://github.com/nshen/learn-neovim-lua

注意:v 2 分支是 neovim 8.0+适用

或是直接使用作者的新仓库:nshen/InsisVim: An out-of-the-box Neovim IDE solution that setup development environment in an incredibly simple way. (github.com)

除了小册作者的配置仓库,这里再推荐一个优秀 Neovim 配置仓库: ayamir/nvimdots: A well configured and structured Neovim. (github.com)

至此 Neovim 配置学习就结束了:smile:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com