refactor(nvim): 完整重写配置,支持 Go/Rust/Python/TypeScript 开发

- 架构重构:新增 plugins/lang/ 子目录,按语言拆分配置
- 补全引擎:nvim-cmp → blink.cmp + LuaSnip
- 文件浏览:新增 neo-tree(<Space>e)
- 语言支持:
  - Go: ray-x/go.nvim + dap-go + neotest-go
  - Rust: rustaceanvim + crates.nvim
  - Python: venv-selector + dap-python + neotest-python
  - TypeScript: typescript-tools.nvim(替换 ts_ls)
- LSP: lazydev + mason + mason-lspconfig + fidget + inc-rename
- 格式化: conform.nvim(lsp_format fallback,保存时自动格式化)
- Lint: nvim-lint(selene 替换 luacheck,Mason 可直接安装)
- UI: snacks.nvim(dashboard+notifier+picker)+ noice + lualine + bufferline
- 编辑增强: mini.ai + mini.surround + grug-far + flash + ufo + trouble v3
- 删除废弃文件: cmp/coding/null-ls/mason/lspconfig/go/python 等旧文件
- 修复: Neovim 0.12 treesitter query 校验报错(noice routes 过滤)
- 新增: NVIM_GUIDE.md 快捷键使用手册

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-07 16:55:07 +08:00
parent 2aa176dff5
commit 6fd5d96043
36 changed files with 2087 additions and 2814 deletions

View File

@@ -1,9 +1,8 @@
-- autocmds.lua - 自动命令配置
-- 创建自动命令组
local augroup = vim.api.nvim_create_augroup("MyCustomGroup", { clear = true })
-- 自动设置光标行
-- 插入模式进出切换光标行高亮
vim.api.nvim_create_autocmd({ "InsertLeave", "WinEnter" }, {
pattern = "*",
group = augroup,
@@ -33,20 +32,7 @@ vim.api.nvim_create_autocmd("TextYankPost", {
end,
})
-- 自动切换工作目录
vim.api.nvim_create_autocmd({ "BufEnter" }, {
pattern = "*",
group = augroup,
desc = "自动切换到文件所在目录",
callback = function()
local buftype = vim.bo.buftype
if buftype ~= "terminal" and buftype ~= "nofile" and buftype ~= "prompt" then
vim.cmd("silent! lcd %:p:h")
end
end,
})
-- 自动恢复光标位置
-- 恢复光标位置
vim.api.nvim_create_autocmd("BufReadPost", {
group = augroup,
desc = "恢复光标位置",
@@ -59,18 +45,12 @@ vim.api.nvim_create_autocmd("BufReadPost", {
end,
})
-- 自动关闭某些窗口的 q
-- 特定文件类型用 q 关闭
vim.api.nvim_create_autocmd("FileType", {
pattern = {
"qf",
"help",
"man",
"notify",
"lspinfo",
"startuptime",
"tsplayground",
"spectre_panel",
"PlenaryTestPopup",
"qf", "help", "man", "notify", "lspinfo", "startuptime",
"tsplayground", "spectre_panel", "PlenaryTestPopup",
"checkhealth", "neotest-output", "neotest-summary",
},
group = augroup,
callback = function(event)
@@ -79,28 +59,43 @@ vim.api.nvim_create_autocmd("FileType", {
end,
})
-- 保存时自动删除行尾空白字符
-- 保存时删除行尾空白markdown 使用尾部空格表示换行,需跳过)
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*",
group = augroup,
desc = "删除行尾空白字符",
desc = "删除行尾空白",
callback = function()
-- 保存当前位置
local ft = vim.bo.filetype
if ft == "markdown" or ft == "text" or ft == "diff" then return end
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- 保存搜索寄存器
local search = vim.fn.getreg("/")
-- 替换所有行尾空白字符
vim.cmd([[%s/\s\+$//e]])
-- 恢复搜索寄存器
vim.fn.setreg("/", search)
-- 恢复光标位置
vim.api.nvim_win_set_cursor(0, cursor_pos)
end,
})
-- 自动设置文件类型的选项
-- 在外部更改时自动重新加载文件
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, {
pattern = "*",
group = augroup,
callback = function()
if vim.fn.mode() ~= "c" and not vim.bo.readonly then
vim.cmd("checktime")
end
end,
})
vim.api.nvim_create_autocmd("FileChangedShellPost", {
pattern = "*",
group = augroup,
callback = function()
vim.notify("文件已被外部修改,缓冲区已重新加载", vim.log.levels.WARN)
end,
})
-- ========== 语言专用设置 ==========
vim.api.nvim_create_autocmd("FileType", {
pattern = "python",
group = augroup,
@@ -109,7 +104,7 @@ vim.api.nvim_create_autocmd("FileType", {
vim.opt_local.shiftwidth = 4
vim.opt_local.tabstop = 4
vim.opt_local.softtabstop = 4
vim.opt_local.textwidth = 88 -- 符合 black 格式化
vim.opt_local.textwidth = 88
vim.opt_local.colorcolumn = "88"
end,
})
@@ -121,11 +116,25 @@ vim.api.nvim_create_autocmd("FileType", {
vim.opt_local.expandtab = false
vim.opt_local.shiftwidth = 4
vim.opt_local.tabstop = 4
vim.opt_local.softtabstop = 4
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "javascript", "typescript", "javascriptreact", "typescriptreact", "json", "html", "css", "yaml", "markdown" },
pattern = "rust",
group = augroup,
callback = function()
vim.opt_local.expandtab = true
vim.opt_local.shiftwidth = 4
vim.opt_local.tabstop = 4
vim.opt_local.softtabstop = 4
vim.opt_local.textwidth = 100
vim.opt_local.colorcolumn = "100"
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "javascript", "typescript", "javascriptreact", "typescriptreact", "json", "jsonc", "html", "css", "scss", "yaml", "markdown" },
group = augroup,
callback = function()
vim.opt_local.expandtab = true
@@ -142,71 +151,3 @@ vim.api.nvim_create_autocmd("FileType", {
vim.opt_local.expandtab = false
end,
})
-- 为新文件创建模板
vim.api.nvim_create_autocmd("BufNewFile", {
pattern = "*.py",
group = augroup,
callback = function()
local lines = {
"#!/usr/bin/env python3",
"# -*- coding: utf-8 -*-",
"\"\"\"",
"Description: ",
"\"\"\"",
"",
"",
"def main():",
" pass",
"",
"",
"if __name__ == \"__main__\":",
" main()",
"",
}
vim.api.nvim_buf_set_lines(0, 0, 0, false, lines)
vim.api.nvim_win_set_cursor(0, { 4, 13 })
end,
})
vim.api.nvim_create_autocmd("BufNewFile", {
pattern = "*.go",
group = augroup,
callback = function()
local package_name = vim.fn.fnamemodify(vim.fn.expand("%:p:h:t"), ":r")
local lines = {
"package " .. package_name,
"",
"import (",
"\t\"fmt\"",
")",
"",
"// TODO: Add description here",
"",
"",
}
vim.api.nvim_buf_set_lines(0, 0, 0, false, lines)
vim.api.nvim_win_set_cursor(0, { 7, 27 })
end,
})
-- 在外部更改时自动重新加载文件
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, {
pattern = "*",
group = augroup,
callback = function()
if vim.fn.mode() ~= "c" and not vim.bo.readonly then
vim.cmd("checktime")
end
end,
})
-- 当 checktime 检测到文件已更改时通知
vim.api.nvim_create_autocmd("FileChangedShellPost", {
pattern = "*",
group = augroup,
callback = function()
vim.notify("File changed on disk. Buffer reloaded!", vim.log.levels.WARN)
end,
})

View File

@@ -1,24 +1,9 @@
-- keymaps.lua - 键位映射配置
-- 设置局部变量
local map = vim.keymap.set
local opts = { noremap = true, silent = true }
--[[
模式说明:
n: 普通模式
i: 插入模式
v: 可视模式
x: 可视块模式
t: 终端模式
c: 命令行模式
]]--
-----------------
-- 基础键位映射 --
-----------------
-- 使用 jk 从插入模式返回普通模式
-- 插入模式退出
map("i", "jk", "<ESC>", opts)
-- 保存和退出
@@ -29,89 +14,60 @@ map("n", "<leader>Q", "<cmd>qa<cr>", { desc = "退出全部" })
-- 清除搜索高亮
map("n", "<leader>h", "<cmd>nohlsearch<cr>", { desc = "清除搜索高亮" })
-- 更好的缩进
-- 缩进保持选中
map("v", "<", "<gv", opts)
map("v", ">", ">gv", opts)
-- 上下移动选中文本
map("v", "J", ":m '>+1<CR>gv=gv", { desc = "向下移动选中文本" })
map("v", "K", ":m '<-2<CR>gv=gv", { desc = "向上移动选中文本" })
-- 上下移动选中文本
map("v", "J", ":m '>+1<CR>gv=gv", { desc = "向下移动选中" })
map("v", "K", ":m '<-2<CR>gv=gv", { desc = "向上移动选中" })
-- 保持复制内容在粘贴后
-- 粘贴不覆盖寄存器
map("x", "p", [["_dP]], { desc = "粘贴不覆盖寄存器" })
-- 删除到黑洞寄存器
map({ "n", "v" }, "<leader>d", [["_d]], { desc = "删除到黑洞寄存器" })
-- 快速移动
map("n", "J", "mzJ`z", { desc = "连接行保持光标位置" })
map("n", "<C-d>", "<C-d>zz", { desc = "向下移动保持光标居中" })
map("n", "<C-u>", "<C-u>zz", { desc = "向上移动保持光标居中" })
map("n", "n", "nzzzv", { desc = "下一个搜索结果居中" })
map("n", "N", "Nzzzv", { desc = "上一个搜索结果居中" })
-- 快速移动(保持居中)
map("n", "J", "mzJ`z", { desc = "连接行" })
map("n", "<C-d>", "<C-d>zz", { desc = "向下翻页居中" })
map("n", "<C-u>", "<C-u>zz", { desc = "向上翻页居中" })
map("n", "n", "nzzzv", { desc = "下一个结果居中" })
map("n", "N", "Nzzzv", { desc = "上一个结果居中" })
-------------------------
-- 窗口和缓冲区管理 --
-------------------------
-- 窗口间导航
map("n", "<C-h>", "<C-w>h", { desc = "移动到左窗口" })
map("n", "<C-j>", "<C-w>j", { desc = "移动到下窗口" })
map("n", "<C-k>", "<C-w>k", { desc = "移动到上窗口" })
map("n", "<C-l>", "<C-w>l", { desc = "移动到右窗口" })
-- 缓冲区导航
map("n", "<S-h>", "<cmd>bprevious<cr>", { desc = "上一个缓冲区" })
map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "下一个缓冲区" })
map("n", "<leader>bd", "<cmd>bdelete<cr>", { desc = "关闭当前缓冲区" })
map("n", "<leader>ba", "<cmd>bufdo bd<cr>", { desc = "关闭所有缓冲区" })
-- 窗口导航
map("n", "<C-h>", "<C-w>h", { desc = "左窗口" })
map("n", "<C-j>", "<C-w>j", { desc = "下窗口" })
map("n", "<C-k>", "<C-w>k", { desc = "上窗口" })
map("n", "<C-l>", "<C-w>l", { desc = "右窗口" })
-- 窗口分割
map("n", "<leader>sv", "<cmd>vsplit<cr>", { desc = "垂直分割" })
map("n", "<leader>sh", "<cmd>split<cr>", { desc = "水平分割" })
map("n", "<leader>se", "<C-w>=", { desc = "使所有窗口等宽" })
map("n", "<leader>sx", "<cmd>close<cr>", { desc = "关闭当前窗口" })
map("n", "<leader>se", "<C-w>=", { desc = "均分窗口" })
map("n", "<leader>sx", "<cmd>close<cr>", { desc = "关闭窗口" })
-- 调整窗口大小
map("n", "<C-Up>", "<cmd>resize +2<cr>", { desc = "增加窗口高度" })
map("n", "<C-Down>", "<cmd>resize -2<cr>", { desc = "小窗口高度" })
map("n", "<C-Left>", "<cmd>vertical resize -2<cr>", { desc = "小窗口宽度" })
map("n", "<C-Right>", "<cmd>vertical resize +2<cr>", { desc = "增加窗口宽度" })
map("n", "<C-Up>", "<cmd>resize +2<cr>", { desc = "增加高度" })
map("n", "<C-Down>", "<cmd>resize -2<cr>", { desc = "高度" })
map("n", "<C-Left>", "<cmd>vertical resize -2<cr>", { desc = "宽度" })
map("n", "<C-Right>", "<cmd>vertical resize +2<cr>", { desc = "增加宽度" })
-------------------------
-- 终端模式映射 --
-------------------------
-- 退出终端模式
-- 终端模式
map("t", "<Esc>", "<C-\\><C-n>", { desc = "退出终端模式" })
map("t", "jk", "<C-\\><C-n>", { desc = "退出终端模式" })
map("t", "<C-h>", "<C-\\><C-n><C-w>h", opts)
map("t", "<C-j>", "<C-\\><C-n><C-w>j", opts)
map("t", "<C-k>", "<C-\\><C-n><C-w>k", opts)
map("t", "<C-l>", "<C-\\><C-n><C-w>l", opts)
-- 终端窗口导航
map("t", "<C-h>", "<C-\\><C-n><C-w>h", { desc = "终端模式下向左移动" })
map("t", "<C-j>", "<C-\\><C-n><C-w>j", { desc = "终端模式下向下移动" })
map("t", "<C-k>", "<C-\\><C-n><C-w>k", { desc = "终端模式下向上移动" })
map("t", "<C-l>", "<C-\\><C-n><C-w>l", { desc = "终端模式下向右移动" })
-------------------------
-- 实用功能 --
-------------------------
-- 全文快速替换当前单词
-- 实用工具
map("n", "<leader>r", [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], { desc = "替换当前单词" })
map("n", "<leader>x", "<cmd>!chmod +x %<CR>", { desc = "使文件可执行", silent = true })
-- 使当前文件可执行
map("n", "<leader>x", "<cmd>!chmod +x %<CR>", { desc = "使当前文件可执行", silent = true })
-- 打开一个新的终端
map("n", "<leader>t", "<cmd>terminal<cr>", { desc = "打开终端" })
-- 快速编辑配置文件
map("n", "<leader>ev", "<cmd>e $MYVIMRC<cr>", { desc = "编辑init.lua" })
map("n", "<leader>sv", "<cmd>source $MYVIMRC<cr>", { desc = "重新加载配置" })
-- 更简单的命令行历史导航
map("c", "<C-j>", "<Down>", { desc = "下一个命令历史" })
map("c", "<C-k>", "<Up>", { desc = "上一个命令历史" })
-- 命令行历史
map("c", "<C-j>", "<Down>", { desc = "下一条命令" })
map("c", "<C-k>", "<Up>", { desc = "上一条命令" })
-- 更好的搜索
map("n", "g/", "/\\<\\><Left><Left>", { desc = "搜索单词" })
map("n", "g/", "/\\<\\><Left><Left>", { desc = "搜索单词" })

View File

@@ -21,8 +21,8 @@ vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
-- 插件列表
spec = {
-- 导入插件模块
{ import = "plugins" },
{ import = "plugins.lang" },
},
-- 默认配置

View File

@@ -8,9 +8,7 @@ opt.termguicolors = true -- 使用终端真彩色
opt.number = true -- 显示行号
opt.relativenumber = true -- 相对行号
opt.cursorline = true -- 高亮当前行
opt.cursorcolumn = true -- 高亮当前列
opt.signcolumn = "auto:1" -- 显示标记列
opt.showmatch = true -- 高亮匹配的括号
opt.signcolumn = "yes" -- 始终显示标记列(避免每次出现符号时布局跳动)
opt.showmode = false -- 不显示模式,由状态栏插件替代
opt.laststatus = 3 -- 全局状态栏
opt.cmdheight = 1 -- 命令行高度
@@ -25,7 +23,6 @@ opt.listchars = { -- 设置不可见字符的显示方式
extends = "",
precedes = "",
nbsp = "",
eol = ""
}
opt.fillchars:append({ -- 分隔符符号设置
vert = "", -- 窗口分隔符
@@ -41,7 +38,6 @@ opt.shiftwidth = 4 -- 缩进宽度
opt.expandtab = true -- 使用空格替代Tab
opt.smartindent = true -- 智能缩进
opt.autoindent = true -- 自动缩进
opt.cindent = true -- C语言缩进规则
opt.textwidth = 120 -- 文本宽度
opt.formatoptions = "jcroqlnt" -- 格式化选项
opt.foldenable = false
@@ -56,7 +52,7 @@ opt.incsearch = true -- 增量搜索
-- 性能设置
opt.hidden = true -- 允许切换未保存的缓冲区
opt.history = 500 -- 历史记录数
opt.history = 1000 -- 历史记录数
opt.updatetime = 100 -- 更新时间ms
opt.timeout = true -- 启用超时
opt.timeoutlen = 300 -- 键映射超时时间ms
@@ -83,6 +79,8 @@ opt.completeopt = "menu,menuone,noselect" -- 补全选项
opt.pumheight = 10 -- 弹出菜单高度
opt.confirm = true -- 显示确认对话框
opt.autoread = true -- 自动重新加载文件
-- 减少消息噪音W=写入/I=intro/c=补全消息/C=扫描消息)
opt.shortmess:append("WIcC")
-- 加载 .nvimrc, .exrc 等本地配置
opt.exrc = true -- 启用 .exrc