Neovim 配置全面解析(下)

news2024/10/6 14:36:46

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:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

是如何学习 Java 的?

我曾在携程旅行网做 Java 开发&#xff0c;也曾拿过阿里 P7 offer 和饿了么、美团等公司的 offer&#xff0c;这是职位都是 Java 开发岗&#xff0c;也做过 Java 面试官面试过不少同学。下面我就和大家分享一下我学习 Java的经验。 我将从 Java 基础知识、Java 框架、计算机基…

Java设计模式 _行为型模式_备忘录模式

一、备忘录模式 1、备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型模式。通过保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。 2、实现思路 &#xff08;1&#xff09;、定义记录数据的格式规范。 &#xff08;2&#xff09;、编…

计算机算法中的数字表示法——原码、反码、补码

目录 1.前言2.研究数字表示法的意义3.数字表示法3.1 无符号整数3.2 有符号数值3.3 二进制补码(Twos Complement, 2C)3.4 二进制反码(也称作 1 的补码, Ones Complement, 1C)3.5 减 1 表示法(Diminished one System, D1)3.6 原码、反码、补码总结 1.前言 昨天有粉丝让我讲解下定…

SRE视角下的DevOps构建之道

引言&#xff1a; 随着数字化时代的飞速发展&#xff0c;软件成为了企业竞争力的核心。为了更高效地交付高质量的软件&#xff0c;DevOps&#xff08;Development和Operations的组合&#xff09;作为一种文化、实践和工具集的集合&#xff0c;逐渐成为了行业内的热门话题。然而…

怎样快速查找网页代码中存在的错误?

计算机很机械&#xff0c;代码中存在微小的错误&#xff0c;计算机就得不到正确的运行结果。比如&#xff0c;一个字母的大小写、比如&#xff0c;个别地方丢掉了一个符号、、、如此等等。这就要求程序员和计算机是心灵相通的&#xff0c;不能有任何的“隔阂”。 但是&#xf…

汇智知了堂实力展示:四川农业大学Python爬虫实训圆满结束

近日&#xff0c;汇智知了堂在四川农业大学举办的为期五天的校内综合项目实训活动已圆满结束。本次实训聚焦Python爬虫技术&#xff0c;旨在提升学生的编程能力和数据分析能力&#xff0c;为学生未来的职业发展打下坚实的基础。 作为一家在IT教育行业享有盛誉的机构&#xff…

【ArcGISPro】3.1.5下载和安装教程

下载教程 arcgis下载地址&#xff1a;Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本&#xff0c;它引入了一些新的特性和功能&#xff0c;以提高用户的工作效率和数据分析能力。以下是ArcGIS…

基于Udp(收发信息使用同一个socket)网络通信编程

想要实现网络通信那么就要有一个客户端一个服务器 客户端发送数据&#xff0c;服务器接收数据并返回数据 网络通信就是进程通信 所以我们用两个程序来分别编写客户端和服务器 服务器 1&#xff0c;设置端口号&#xff0c; 2、ip可以固定位127.0.0.1来用于本地测试&#xff0c…

dbserver 软件 展示 全部模式库

目录 1 问题2 实现 1 问题 dbserver 软件 展示 全部模式库 2 实现 以上就可以了

基于文本来推荐相似酒店

基于文本来推荐相似酒店 查看数据集基本信息 import pandas as pd import numpy as np from nltk.corpus import stopwords from sklearn.metrics.pairwise import linear_kernel from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extrac…

扩散模型--论文分享篇

定义&#xff1a;输入文本与图像&#xff0c;生成对图像的描述。 所采用的方法&#xff1a;对比学习、基于跨注意力机制的多模态融合 基于扩散模型的方法&#xff1a;主要介绍的扩散的原理 图像生成任务介绍 GAN VAE 扩散模型 基于GAN的图像生成&#xff0c;一个生成器与判别…

非量表题如何进行信效度分析

效度是指设计的题确实在测量某个东西&#xff0c;一般问卷中使用到。如果是量表类的数据&#xff0c;其一般是用因子分析这种方法去验证效度水平&#xff0c;其可通过因子分析探究各测量量表的内部结构情况&#xff0c;分析因子分析得到的内部结构与自己预期的内部结构进行对比…

子网划分案例

4.2子网划分 “有类编址”的地址划分过于死板&#xff0c;划分的颗粒度太大&#xff0c;会有大量的主机号不能被充分利用&#xff0c;从而造成了大量的IP地址资源浪费。因此可以利用子网划分来减少地址浪费&#xff0c;即VLSM (Variable Length Subnet Mask)&#xff0c;可变长…

Java实现对象存储的4种方式(本地对象存储、MINIO、阿里云OSS、FastDFS)

文章目录 Java实现对象存储的3中方式1、概述2、本地对象存储2.1 配置本地文件相关信息2.2 通用映射配置 ResourcesConfig2.3 文件上传业务 LocalSysFileServiceImpl2.4 上传接口2.5 演示 3、MINIO3.1 依赖3.2 配置3.3 配置连接信息3.4. MINIO文件上传业务3.5 文件上传下载接口3…

高考前很焦虑?看看罗永浩提的三个建议!罗永浩推荐的随身WiFi居然蕴含这样的商机?2024普通人如何翻身?

你能相信现如今身家过亿的老罗罗永浩高中就辍学了吗&#xff1f;相信很多人都不敢置信吧。罗永浩无论是表现出来的口才、情商还是智商&#xff0c;无论如何都无法让人把他和高中辍学联系起来。 而这一点似乎也是老罗人生中的一个遗憾&#xff0c;于是又在一年高考季的时候&…

【AREngine BUG 解决方法】无法获取有效的相机图像尺寸

近期拿了一台 华为mate20 Pro的手机&#xff0c;在运行AR示例的过程中出现了黑屏。 问题排查 SDK版本&#xff1a;com.huawei.hms:arenginesdk:3.7.0.3 定位 经排查&#xff0c;发现(ARCamera对象的相机内参) getImageDimensions()返回的图像尺寸的width和height都为0。 这…

【AI大模型】如何让大模型变得更聪明?基于时代背景的思考

【AI大模型】如何让大模型变得更聪明 前言 在以前&#xff0c;AI和大模型实际上界限较为清晰。但是随着人工智能技术的不断发展&#xff0c;基于大规模预训练模型的应用在基于AI人工智能的技术支持和帮助上&#xff0c;多个领域展现出了前所未有的能力。无论是自然语言处理、…

Dinky MySQLCDC 整库同步到 Doris

资源&#xff1a;flink 1.17.0、dinky 1.0.2、doris-2.0.1-rc04 问题&#xff1a;Cannot deserialize value of type int from String &#xff0c;detailMessageunknowndatabases &#xff0c;not a valid int value 2024-05-29 16:52:20.136 ERROR org.apache.doris.flink.…

电脑录屏怎么录?7个电脑录屏软件免费版强势来袭,赶快收藏!

电脑录屏怎么录&#xff1f;相信很多小伙伴们都不知道怎么在Windows电脑上录屏吧&#xff1f;在当今社会&#xff0c;随着互联网的快速发展&#xff0c;越来越多的小伙伴们开始通过制作视频内容来分享知识、展示技能或者记录生活。电脑录屏成为了一种简单高效的方式&#xff0c…

C语言-----指针数组 \ 数组指针

一 指针数组 用来存放指针的数组 int arr[10]; //整型数组 char ch[5]; //字符数组 int * arr[6]; //存放整型指针的数组 char * arr[5]; //存放字符指针的数组 // 指针数组的应用 int main() {int arr1[] { 1,2,3,4,5 };int arr2[] { 2,3,4,5,6 };int arr3[] { 3,4,…