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 sign
  error_sign = "",
  warn_sign = "",
  hint_sign = "",
  infor_sign = "",
  diagnostic_header_icon = "   ",
  -- code action title icon
  code_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 替换 rn
  mapbuf ("n", "<leader>rn", "<cmd>lua vim.lsp.buf.rename ()<CR>", opt)
  --]]
  mapbuf ("n", "<leader>rn", "<cmd>Lspsaga rename<CR>", opt)
  -- code action
  --[[
  Lspsaga 替换 ca
  mapbuf ("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 替换 gh
  mapbuf ("n", "gh", "<cmd>lua vim.lsp.buf.hover ()<CR>", opt)
  --]]
  mapbuf ("n", "gh", "<cmd>Lspsaga hover_doc<cr>", opt)
  --[[
  Lspsaga 替换 gr
  mapbuf ("n", "gr", "<cmd>lua vim.lsp.buf.references ()<CR>", opt)
  --]]
  mapbuf ("n", "gr", "<cmd>Lspsaga lsp_finder<CR>", opt)
  --[[
  Lspsaga 替换 gp, gj, gk
  mapbuf ("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)
  --]]
  -- diagnostic
  mapbuf ("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 then
  vim.notify ("没有找到 null-ls")
  return
end

       local formatting = null_ls. builtins. formatting


null_ls.setup ({
  debug = false,
  sources = {
    -- Formatting ---------------------
    --  brew install shfmt
    formatting. shfmt,
    -- StyLua
    formatting. stylua,
    -- frontend
    formatting.prettier.with ({ -- 只比默认配置少了 markdown
      filetypes = {
        "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") then
            vim. 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 }) instead
                    vim.lsp.buf.format ({ bufnr = bufnr })
                    -- vim. lsp. buf. formatting_sync ()
                end,
            })
        end
    end,
})

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 then
    client. server_capabilities. documentFormattingProvider = false
    client. server_capabilities. documentRangeFormattingProvider = false
  else
    client. resolved_capabilities. document_formatting = false
    client. resolved_capabilities. document_range_formatting = false
  end
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,
      -- tailwindcss
      lint = {
        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/fixjson
    common.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 work
  init_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)
    -- defaults
    ts_utils.setup ({
      debug = false,
      disable_commands = false,
      enable_import_on_completion = false,
      -- import all
      import_all_timeout = 5000, -- ms
      -- lower numbers = higher priority
      import_all_priorities = {
        same_file = 1, -- add to existing import statement
        local_files = 2, -- git files or files with relative path markers
        buffer_content = 3, -- loaded buffer content
        buffers = 4, -- loaded buffer names
      },
      import_all_scan_buffers = 100,
      import_all_select_source = false,
      -- if false will avoid organizing imports
      always_organize_imports = true,

      -- filter diagnostics
      filter_out_diagnostics_by_severity = {},
      -- https://github.com/microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json
      filter_out_diagnostics_by_code = {
        80001,
      },

      -- inlay hints
      auto_inlay_hints = true,
      inlay_hints_highlight = "Comment",
      inlay_hints_priority = 200, -- priority of the hint extmarks
      inlay_hints_throttle = 150, -- throttle the inlay hint request
      inlay_hints_format = { -- format options for individual hint kind
        Type = {},
        Parameter = {},
        Enum = {},
        -- Example format customization for `Type` kind:
        -- Type = {
        --     highlight = "Comment",
        --     text = function (text)
        --         return "->" .. text: sub (2)
        --     end,
        -- },
      },

      -- update imports on file move
      update_imports_on_move = false,
      require_confirmation_on_move = false,
      watch_dir = nil,
    })
    -- required to fix code action ranges and filter diagnostics
    ts_utils. setup_client (client)
    -- no default maps, so you may want to define some here
    keybindings.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 then
    vim.notify ("没有找到 null-ls")
    return
end

local formatting = null_ls. builtins. formatting
local diagnostics = null_ls. builtins. diagnostics
local code_actions = null_ls. builtins. code_actions

null_ls.setup ({
    debug = false,
    sources = { -- Formatting ---------------------
    --  brew install shfmt
    formatting. shfmt, -- StyLua
    formatting. stylua, -- frontend
    formatting.prettier.with ({ -- 只比默认配置少了 markdown
        filetypes = {"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") then
            vim. 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 }) instead
                    vim.lsp.buf.format ({
                        bufnr = bufnr
                    })
                    -- vim. lsp. buf. formatting_sync ()
                end
            })
        end
    end
})

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 save
                        checkOnSave = {
                                command = "clippy",
                        },
                },
        },
}

return {
        on_setup = function (server)
                local ok_rt, rust_tools = pcall (require, "rust-tools")
                if not ok_rt then
                        print ("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-tools
                        rust_tools.setup ({
                                server = opts,
                                -- dap = require ("dap. nvim-dap. config. rust"),
                        })
                end
        end,
}

添加 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-format
                formatting. 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 then
                        server.setup (opts)
                else
                        clangd_extensions.setup ({
                                server = opts,
                                extensions = {
                                        -- defaults:
                                        -- Automatically set inlay hints (type hints)
                                        autoSetHints = true,
                                        -- These apply to the default ClangdSetInlayHints command
                                        inlay_hints = {
                                                -- Only show inlay hints for the current line
                                                only_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 not
                                                show_parameter_hints = true,
                                                -- prefix for parameter hints
                                                parameter_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 file
                                                max_len_align = false,
                                                -- padding from the left if max_len_align is true
                                                max_len_align_padding = 1,
                                                -- whether to align to the extreme right or not
                                                right_align = false,
                                                -- padding from the right if right_align is true
                                                right_align_padding = 7,
                                                -- The color of the hints
                                                highlight = "Comment",
                                                -- The highlight group priority for extmark
                                                priority = 100,
                                        },
                                        ast = {
                                                -- These are unicode, should be available in any font
                                                role_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",
                                        },
                                },
                        })
                end
        end,
}

代码运行器

相关插件: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 then
    vim.notify ("没有找到 code_runner")
    return
end

code_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 tab
        position = "bot",
        -- window size, this option is ignored if tab is true
        size = 8,
    },
    float = {
        -- Key that close the code_runner floating window
        close_key = "<ESC>",
        -- Window border (see ': h nvim_open_win')
        border = "none",

        -- Num from `0 - 1` for measurements
        height = 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 defined
    before_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 defined
    project = {},
})

之后 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 then
  vim.notify ("没有找到 nvim-autopairs")
  return
end
autopairs.setup ({
  check_ts = true,
  ts_config = {
    lua = { "string" }, -- it will not add a pair on that treesitter node
    javascript = { "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 then
  vim.notify ("没有找到 Comment")
  return
end

local default_opts = {
  ---Add a space b/w comment and the line
  ---@type boolean|fun ():boolean
  padding = true,

  ---Whether the cursor should stay at its position
  ---NOTE: This only affects NORMAL mode mappings and doesn't work with dot-repeat
  ---@type boolean
  sticky = 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 ():string
  ignore = nil,

  ---LHS of toggle mappings in NORMAL + VISUAL mode
  ---@type table
  toggler = {
    ---Line-comment toggle keymap
    line = "gcc",
    ---Block-comment toggle keymap
    block = "gbc",
  },

  ---LHS of operator-pending mappings in NORMAL + VISUAL mode
  ---@type table
  opleader = {
    ---Line-comment keymap
    line = "gc",
    ---Block-comment keymap
    block = "gb",
  },

  ---LHS of extra mappings
  ---@type table
  extra = {
    ---Add comment on the line above
    above = "gcO",
    ---Add comment on the line below
    below = "gco",
    ---Add comment at the end of line
    eol = "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|table
  mappings = {
    ---Operator-pending mapping
    ---Includes `gcc`, `gbc`, `gc[count]{motion}` and `gb[count]{motion}`
    ---NOTE: These mappings can be changed individually by `opleader` and `toggler` config
    basic = 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):string
  pre_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 配置

引入插件

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

lua/plugin-config/surround. lua

local status, surround = pcall (require, "surround")
if not status then
  vim.notify ("没有找到 surround")
  return
end

surround.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:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/661941.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何解压忘记了密码的加密zip压缩包?这两个方法收藏好!

加密是一种保护信息不被未经授权访问的重要手段。ZIP压缩包作为一种常见的文件压缩格式&#xff0c;zip文件加密是很多人都回去做的一件事情&#xff0c;那么zip加密文件如何解密&#xff1f;有几种方法可以解密呢&#xff1f;今天介绍几种方法给大家。 一、尝试常用密码 我们…

【Python】解决Python报错:TypeError: ‘xxx‘ object does not support item assignment

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

【busybox记录】【shell指令】unlink

目录 内容来源&#xff1a; 【GUN】【unlink】指令介绍 【busybox】【unlink】指令介绍 【linux】【unlink】指令介绍 使用示例&#xff1a; 删除文件 - 默认 常用组合指令&#xff1a; 指令不常用/组合用法还需继续挖掘&#xff1a; 内容来源&#xff1a; GUN &#x…

xcode依赖包package已经安装,但是提示No such module ‘Alamofire‘解决办法

明明已经通过xcode自带的swift包管理器安装好了依赖包&#xff0c;但是却还是提示&#xff1a;No such module&#xff0c;这个坑爹的xcode&#xff0c;我也只能说服气&#xff0c;但是无奈&#xff0c;没办法攻打苹果总部&#xff0c;只能自己想解决办法了 No such module Ala…

ClickHouse 与其他数仓架构的对比——Clickhouse 架构篇(四)

文章目录 前言ClickHouse与Hive的对比计算引擎的差异ClickHouse比Hive查询速度快的原因 ClickHouse与HBase的对比HBase的存储系统与ClickHouse的异同HBase的适用场景及ClickHouse不适合的原因 ClickHouse与Kylin的对比Kylin的架构Kylin解决性能问题的思路Kylin方案的缺陷ClickH…

图片处理软件有哪些?这三款软件好用

图片处理软件有哪些&#xff1f;在当今这个数字化时代&#xff0c;图片处理软件成为了我们日常生活和工作中不可或缺的工具。无论是为了修饰个人照片&#xff0c;还是为了设计专业海报&#xff0c;这些软件都能帮助我们轻松实现创意和美化。那么&#xff0c;究竟有哪些热门的图…

CEEMDAN +组合预测模型(CNN-Transfromer + XGBoost)

注意&#xff1a;本模型继续加入 组合预测模型全家桶 中&#xff0c;之前购买的同学请及时更新下载! 往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;Transformer-BiGRU预测模…

read test

功能性语言: 在.sh脚本下&#xff0c;read -p ——答应 read -t 时间 ——时间完成限制 特别注意空格。 test -n测试是内容一定要加双引号。 test 变量1 -ne 变量2 即比较大小。

视频汇聚EasyCVR平台视图库GA/T 1400协议与GB/T 28181协议的区别

在公安和公共安全领域&#xff0c;视频图像信息的应用日益广泛&#xff0c;尤其是在监控、安防和应急指挥等方面。为了实现视频信息的有效传输、接收和处理&#xff0c;GA/T 1400和GB/T 28181这两个协议被广泛应用。虽然两者都服务于视频信息处理的目的&#xff0c;但它们在实际…

22net冒泡排序与插入排序

冒泡排序 观看视频 【python练习题】每日一练_第八天_冒泡排序_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1QT4y197pa/?spm_id_from333.337.search-card.all.click&vd_source498ae9e9c7a8a7d16da872c9d74cdc38PS&#xff1a;视频中用的了numpy库&#xff0c;大…

10W QPS高并发,如何防止重复下单?

小北说在前面 10wqps高并发&#xff0c;如何防止重复提交/支付订单&#xff1f; 10wqps高并发&#xff0c;如何防止重复下单&#xff1f; 10wqps高并发&#xff0c;如何防止重复支付&#xff1f; 10wqps高并发&#xff0c;如何解决重复操作问题&#xff1f; 最近有小伙伴在面试…

这有一封“数字赋能 强农兴村”的邀请函,请查收→

2024年6月5日至7日&#xff0c;以“数字赋能 强农兴村”为主题的2024中国&#xff08;南京&#xff09;数字乡村博览会暨第八届中国&#xff08;南京&#xff09;国际智慧农业博览会将在江苏南京举办。珈和科技在农业AI大数据展区的H16展位与您相约&#xff0c;共襄盛会。 私信…

iPhone用户推荐使用的藏汉翻译小助手:藏汉翻译通小程序,支持藏文OCR识别文字提取,卫藏语、安多语、康巴语学习背单词!

网上冲浪时&#xff0c;遇到不会的汉语词汇&#xff0c;可以复制到藏汉翻译通小程序中进行翻译。如果不会拼音&#xff0c;可以使用图片识别功能扫一扫文字&#xff0c;即可OCR识别提取文字。 此外&#xff0c;藏汉翻译通小程序现在还支持背单词和会话速成课程&#xff0c;支持…

java调用远程接口下载文件

在postman中这样下载文件 有时下载文件太大postman会闪退&#xff0c;可以通过代码下载&#xff0c;使用hutool的http包

HAL库使用FreeRTOS实时操作系统时配置时基源(TimeBase Source)

需要另外的定时器&#xff0c;用systic的时候生成项目会有警告 https://blog.51cto.com/u_16213579/10967728

java高级——Collection集合之List探索(包含ArrayList、LinkedList、Vector底层实现及区别,非常详细哦)

java高级——Collection集合之List探索 前情提要文章介绍提前了解的知识点1. 数组2. 单向链表3. 双向链表4. 为什么单向链表使用的较多5. 线程安全和线程不安全的概念 ArrayList介绍1. 继承结构解析1.1 三个标志性接口1.2 AbstractList和AbstractCollection 2. ArrayList底层代…

企业网站有必要进行软件测试吗?网站测试有哪些测试流程?

企业网站在现代商业中扮演着重要的角色&#xff0c;它不仅是企业形象的重要体现&#xff0c;也是与客户、合作伙伴进行沟通与交流的重要渠道。然而&#xff0c;由于企业网站的复杂性和关键性&#xff0c;其中可能存在各种潜在的问题和隐患。因此&#xff0c;对企业网站进行软件…

HTB-SherlocksDFIR

Sherlocks 中关于 DFIR 的一些内容&#xff0c;按照时间线整理&#xff0c;尚未完成&#xff0c;持续更新​ Brutus 和上一次做的 Recollection 机器一样&#xff0c;主要学习一下相关的知识&#xff0c;练习一下。按照机器描述&#xff0c;在学习完成后将熟悉 auth.log 和 wtm…

OpenHarmony面向万物智联的应用框架的思考与探索

应用框架&#xff0c;是操作系统连接开发者生态&#xff0c;实现用户体验的关键基础设施。业务的飞速发展促进了应用框架不断演进和变化。 01►业界应用框架的演进 应用是用户使用操作系统/设备的入口&#xff0c;应用框架则是应用开发和运行的基础设施。以移动端为例&#x…

利用EasyCVR视频智能监控技术,构建智慧化考场监管体系

随着科技的进步&#xff0c;视频监控在各个领域的应用越来越广泛&#xff0c;其中在考场中的应用尤为显著。视频监控不仅能够提高考场的监管水平&#xff0c;确保考试的公平、公正和公开&#xff0c;还能有效预防和打击作弊行为&#xff0c;为考生营造一个良好的考试环境。 传…