跳到主要内容
  1. Blogs/
  2. 博客/

Neovim 插件完善笔记

··2028 字·5 分钟·

在 Nvim 中使用 Lazynvim 配置和管理相关插件

插件管理器:lazy.nvim 💤 #


其特点就是懒加载,让 nvim 的启动与运行健步如飞。

🚪安装传送门

文件结构 #

~/.config
└── nvim
    ├── init.lua               //主要插件加载
    ├── lazy-lock.json
    └── lua
        ├── gatzai_cmp.lua     // cmp相关配置
        └── snippets
            ├── package.json
            └── xxx.json       //其他语言的snippet

小记 #

  • 修改了配置如何执行生效?

在目录 .config/nvim/init.lua 中,nvim中执行:so

  • lazy-lock.json 文件

方便插件回滚的文件,避免了某些插件更新导致整个 neovim 无法工作。

我的插件配置 #


按键管理:which-key.nvim ✅ #

默认按 g 打开菜单

🚪插件传送门

文件树:neo-tree.nvim ✅ #

先配置一个超级方便的打开文件树快捷键

一个参考配置

🚪插件传送门

状态条:lualine.nvim ✅ #

好看的状态条

🚪插件传送门

自动加括号,autopair 插件 ✅ #

🚪插件传送门

模糊搜索:telescope.nvim ✅ #

能够按照文件名,目录,以及文本内容进行模糊搜索。

❗ 若需要文本内容搜索,那么需要 linux 安装 ripgrep

🚪插件传送门

{
	cmd = "Telescope",
	keys = {
		{}, -- todo,做一个 t 的按键映射
	},
	'nvim-telescope/telescope.nvim', tag = '0.1.2',
	dependencies = { 'nvim-lua/plenary.nvim' }
}

-- 使用 cmd 懒加载(用的时候再加载相关插件,而不是在 nvim 一打开加载。
-- 使用 keys 修改相关键位映射

Git插件 ❓ #

lazygit

一些讨论

其实也许你并不需要这种插件,把编辑器放在后台,然后再执行相关 git 操作也行。 又或者使用 :!git status 这种格式也可以进行 git 操作

Git 编辑状态,gitsigns.nvim ✅ #

在编辑器中实时显示 git 的状态,以及 git blame 等信息。

🚪插件传送门

参考Git-Integration In Neovim

标签tab插件,buffline ✅ #

方便显示多标签页面

🚪插件传送门

缩进可视化插件,indent-blankline.nvim ✅ #

🚪插件传送门

对齐插件,indent-blankline ✅ #

显示对齐线

[🚪插件传送门][https://github.com/lukas-reineke/indent-blankline.nvim]

补全插件,nvim-cmp 插件 ✅ #

其实此插件并不具备语法补全能力,其主要是根据各种源搜集补全的文本片段。比如路径补全,文本内关键字补全等。

🚪插件传送门

-- 相关插件
{
	event = "VeryLazy",
	"hrsh7th/nvim-cmp",
	dependencies = {
		"hrsh7th/cmp-buffer",
		"hrsh7th/cmp-path",
		"hrsh7th/cmp-cmdline",
		"saadparwaiz1/cmp_luasnip",
		"L3MON4D3/LuaSnip",
	},
},
-- 配置
local luasnip = require("luasnip")
local cmp = require("cmp")

local has_words_before = function()
	unpack = unpack or table.unpack
	local line, col = unpack(vim.api.nvim_win_get_cursor(0))
	return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end

cmp.setup({
	snippet = {
		-- REQUIRED - you must specify a snippet engine
		expand = function(args)
			require("luasnip").lsp_expand(args.body) -- For `luasnip` users.
			-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
			-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
		end,
	},
	window = {
		-- completion = cmp.config.window.bordered(),
		-- documentation = cmp.config.window.bordered(),
	},
	mapping = cmp.mapping.preset.insert({
		["<Tab>"] = cmp.mapping(function(fallback)
			if cmp.visible() then
				cmp.select_next_item()
				-- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
				-- the way you will only jump inside the snippet region
			elseif luasnip.expand_or_jumpable() then
				luasnip.expand_or_jump()
			elseif has_words_before() then
				cmp.complete()
			else
				fallback()
			end
		end, { "i", "s" }),

		["<S-Tab>"] = cmp.mapping(function(fallback)
			if cmp.visible() then
				cmp.select_prev_item()
			elseif luasnip.jumpable(-1) then
				luasnip.jump(-1)
			else
				fallback()
			end
		end, { "i", "s" }),
		["<C-b>"] = cmp.mapping.scroll_docs(-4),
		["<C-f>"] = cmp.mapping.scroll_docs(4),
		["<C-Space>"] = cmp.mapping.complete(),
		["<C-c>"] = cmp.mapping.abort(),
		["<CR>"] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
	}),
	sources = cmp.config.sources({
		{ name = "nvim_lsp" },
		{ name = "luasnip" }, -- For luasnip users.
		-- { name = 'ultisnips' }, -- For ultisnips users.
		-- { name = 'snippy' }, -- For snippy users.
	}, {
		{ name = "buffer" },
	}),
})

-- Set configuration for specific filetype.
cmp.setup.filetype("gitcommit", {
	sources = cmp.config.sources({
		{ name = "cmp_git" }, -- You can specify the `cmp_git` source if you were installed it.
	}, {
		{ name = "buffer" },
	}),
})

-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({ "/", "?" }, {
	mapping = cmp.mapping.preset.cmdline(),
	sources = {
		{ name = "buffer" },
	},
})

-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(":", {
	mapping = cmp.mapping.preset.cmdline(),
	sources = cmp.config.sources({
		{ name = "path" },
	}, {
		{ name = "cmdline" },
	}),
})

自定义代码片段,luasnip ✅ #

  1. 创建路径配置文件:~/.config/nvim/lua/snippets/package.json
{
	"name":"gatzai-snippets",
	"engines":{
			"vscode":"^1.11.0"
	},
	"contributes":{
		"snippets":[
				{
						"language":["all"],
						"path":"./global.json"
				},
				{
						"language":["python"],
						"path":"./python.json"
				},
				{
						"language":["lua"],
						"path":"./lua.json"
				}
		]
	}
}
  1. 为不同的语言创建自定义的 snippets:~/.config/nvim/lua/snippets/global.json
{
	"greeting":
	{
		"prefix":"hi",
		"body":[
				"hi world"
		],
		"description": "say hi"
	}
}
  1. 引用配置
local luasnip_loader = require("luasnip.loaders.from_vscode")
luasnip_loader.lazy_load()
luasnip_loader.lazy_load({ paths = {"~/.config/nvim/lua/snippets"}})

luasnip.config.setup({
	region_check_events = "CursorHold, InsertLeave, InsertEnter",
	delete_check_events = "TextChanged, InsertEnter",
})

LuaSnip 和 cmp_luasnip 插件的区别:前者提供 snippets 的功能,后者可以显示 popup menu。

保留上次编辑状态, persistence.nvim ✅ #

或者 lastplace 插件也行

🚪插件传送门

高亮显示语法,treesitter 🚧 #

🚪插件传送门

语法管理插件,Mason ✅ #

管理LSP服务,DAP服务,linters和格式化程序

{
	event = "VeryLazy",
	"williamboman/mason.nvim",
	build = ":MasonUpdate"
}
{
	event = "VeryLazy",
	"neovim/nvim-lspconfig",
	dependencies = { "williamboman/mason-lspconfig.nvim" },
},
-- verylazy: UI 显示才会做加载,减少了加载时间

require("mason").setup()
require("mason-lspconfig").setup()

🚪插件传送门

像官网所说的

  • LSP 推荐安装 lspconfig 和 mason-lspconfig.nvim

    lspconfig 是 LSP 客户端不同语言的一些配置

    mason-lspconfig 这是 LSP Server

  • DAP 推荐安装 nvim-dap 和 nvim-dap-ui

  • Linters 推荐安装 null-ls.nvim 或 nvim-lint

  • Formatters 推荐安装 null-ls.nvim 或 formatter.nvim

讨论: Mason 为什么有这么多包

LSP 🚧 #

简单来说就是一个提供自动补全,跳转,提示等代码功能的工具。

LSP 是微软为开发工具提出的一个协议, 它将编程工具解耦成了Language Server 与Language Client 两部分。Client 专注于页面样式实现, Server 负责提供语言支持,包括常见的自动补全,跳转到定义,查找引用,悬停文档提示等功能。如下:

flowchart LR
subgraph Client
vscode[VSCode]
nv[Neovim]
end
lsp[LSP -- Language Server Protocol]

vscode --> lsp
nv --> lsp

subgraph Server
lua
python
typescript
rust
other[...]
end

lsp --> lua
lsp --> python
lsp -->typescript
lsp --> rust
lsp --> other

安装 python 的 lsp:pyright,需要npm?不理解,不想装!

LSP体系

DAP 🚧 #

简单来说就是一个代码调试器,直接在 nvim 中编译运行,调试代码。

通过 mason 进行管理 LSP 和 DAP,并安装对应语言的 server

太复杂了!他娘的一个上午都没搞定 python 的 DAP。

其他插件 #

black: python格式化插件

linter:补全?

ruff:用 rust 写的 python linter 工具

最后 #


本配置已经放在个人的 Linux 系统配置中:我的 Linux 的💻配置

其他参考 #

neovim + lazynvim 配置

Nvim插件大全