k0nnyaku @ k0nnyaku.me

lsp在内的Nvim0.12更小化基础配置

May 21

0

作为Year Of OOTB, Nvim0.12 提供了原生的插件管理器vim.pack()和lsp支持, 使得配置极大简化, 于是根据0.12新特性翻新了配置, 在这里做记录

完整配置见:Nvim 0.12 Config

目录

~/.config/nvim
├── init.lua
├── lua/
│   ├── core/
│   ├── plugins/
│   └── lsp/
├── after/
│   └── lsp/
├── UltiSnips/
└── undodir/
  • core/:基础选项、快捷键、自动命令、终端、运行器。
  • plugins/:插件声明和插件配置。
  • lsp/:诊断、补全、格式化
  • after/lsp/:覆盖单个 LSP server 配置。
  • UltiSnips/UltiSnips插件

入口

init.lua 只负责加载

require("core.options")
require("plugins")
require("plugins.ui")
require("plugins.editor")
require("plugins.lang")
require("plugins.notes")
require("core.keymaps")
require("lsp")
require("core.autocmds")
require("core.terminal")
require("core.runner")

基础选项

位置:lua/core/options.lua

节选:

vim.opt.number = true
vim.opt.relativenumber = true --相对行号
vim.opt.scrolloff = 15

undo:

local undodir = vim.fn.expand("~/.config/nvim/undodir")
if vim.fn.isdirectory(undodir) == 0 then
	vim.fn.mkdir(undodir, "p")
end

vim.opt.undodir = undodir
vim.opt.undofile = true

插件

使用 Neovim 0.12 提供的原生管理器 vim.pack(experiment)

插件声明:

vim.pack.add({
	"https://github.com/folke/flash.nvim",
	"https://github.com/nvim-lualine/lualine.nvim",
    --...
})

值得单独说明的插件:

更新:

:lua vim.pack.update()

代码补全

Treesitter vs LSP

两者处理不同层级。

组件输入主要用途
Treesitter本地 parser语法树、高亮、文本对象、折叠
LSP外部 language server诊断、跳转、补全、重命名、code action
efm外部 formatter/linter通过 LSP 接入格式化和 lint

Treesitter 不需要项目语义。LSP 需要 language server 和项目根目录。efm 本质上也是一个 LSP server,但它调用的是外部命令。

Mason

lsp等的管理器

Treesitter

位置:lua/plugins/lang.lua

Parser 列表:

local ensure_installed = {
	"vim",
	"vimdoc",
	"rust",
	"c",
	"cpp",
	"go",
	"html",
	"css",
	"javascript",
	"json",
	"lua",
	"markdown",
	"python",
	"typescript",
	"vue",
	"svelte",
	"bash",
}

按 filetype 启动:

vim.api.nvim_create_autocmd("FileType", {
	callback = function(args)
		local lang = vim.treesitter.language.get_lang(args.match)
		if vim.list_contains(treesitter.get_installed(), lang) then
			vim.treesitter.start(args.buf)
		end
	end,
})

折叠:

vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.opt.foldlevel = 99

LSP

Neovim 0.12 推荐使用:

vim.lsp.config()
vim.lsp.enable()

模块入口

入口:

require("lsp.diagnostic")
require("lsp.attach")
require("lsp.completion")
require("lsp.efm")
require("lsp.servers")

启用 server:

vim.lsp.enable({
	"lua_ls",
	"pyright",
	"bashls",
	"ts_ls",
	"gopls",
	"clangd",
	"efm",
})

Server 覆盖

after/lsp/ 用于覆盖单个 server 配置。

after/lsp/clangd.lua

return {
	cmd = {
		"clangd",
		"--header-insertion=never",
		"--limit-results=20",
		"--completion-style=detailed",
		"--background-index",
		"--clang-tidy",
	},
}

补全

lua/lsp/completion.lua 使用 blink.cmp

require("blink.cmp").setup({
	keymap = {
		preset = "none",
		["<C-y>"] = { "accept", "fallback" },
		["<C-j>"] = { "select_next", "fallback" },
		["<C-k>"] = { "select_prev", "fallback" },
		["<C-l>"] = { "snippet_forward", "fallback" },
		["<C-h>"] = { "snippet_backward", "fallback" },
	},
	completion = { menu = { auto_show = true } },
	sources = { default = { "lsp", "path", "buffer", "snippets" } },
})

Snippet 展开:

snippets = {
	expand = function(snippet)
		require("luasnip").lsp_expand(snippet)
	end,
}

efm

lua/lsp/efm.lua 把外部 formatter/linter 接入 LSP。

lua/core/autocmds.luaBufWritePre 中格式化。只使用 efm

pcall(vim.lsp.buf.format, {
	bufnr = args.buf,
	timeout_ms = 2000,
	filter = function(client)
		return client.name == "efm"
	end,
})

快捷键

分组:

前缀用途
<leader>f查找
<leader>bBuffer
<leader>wWindow
<leader>lLSP
<leader>x诊断
<leader>n笔记
<leader>r运行
<leader>t终端
<leader>y复制

完整表见 KEYMAPS.md

最小流程

  1. 复制配置文件
  2. 通过Mason安装需要的 lsp 和 formatter

参考


>