完美!我们按这个顺序来,先搞定 完整的通用插件配置。
📁 通用插件配置(完整版)
目录结构
~/.config/nvim/
├── chadrc.lua
└── lua/
└── core/
├── keymaps.lua
├── options.lua
└── plugins.lua
🔧 1. chadrc.lua(主配置)
-- ~/.config/nvim/chadrc.lua
local M = {}
M.ui = { theme = "catppuccin" }
M.options = {
configs = {
"core.options", -- 通用选项
"core.keymaps", -- 统一快捷键
}
}
-- 加载通用插件 + 环境插件
M.plugins = function()
local env_file = vim.fn.stdpath("config") .. "/.nvim-env"
local env = "writer" -- 默认环境
if vim.fn.filereadable(env_file) == 1 then
env = vim.fn.readfile(env_file)[1]
end
return {
"core.plugins", -- 通用插件(所有环境都加载)
"envs." .. env, -- 环境专用插件
}
end
return M⚙️ 2. lua/core/options.lua(通用选项)
-- ~/.config/nvim/lua/core/options.lua
local opt = vim.opt
-- 基础设置
opt.number = true
opt.relativenumber = true
opt.cursorline = true
opt.showmode = false
opt.hidden = true -- 允许切换缓冲区而不保存
opt.splitright = true -- 新窗口在右侧
opt.splitbelow = true -- 新窗口在下方
opt.mouse = "a" -- 启用鼠标
-- 缩进和制表符
opt.tabstop = 2
opt.softtabstop = 2
opt.shiftwidth = 2
opt.expandtab = true -- 使用空格代替制表符
opt.autoindent = true
opt.smartindent = true
-- 搜索
opt.ignorecase = true
opt.smartcase = true
opt.hlsearch = true
opt.incsearch = true
-- 折叠(基于 Tree-sitter)
opt.foldmethod = "expr"
opt.foldexpr = "nvim_treesitter#foldexpr()"
opt.foldlevel = 99 -- 默认展开所有
opt.foldlevelstart = 99
opt.foldenable = true
-- 其他
opt.termguicolors = true -- 真彩色支持
opt.updatetime = 300 -- 插件更新频率
opt timeoutlen = 400 -- 快捷键超时🔌 3. lua/core/plugins.lua(通用插件 - 完整版)
-- ~/.config/nvim/lua/core/plugins.lua
return {
-- 🌳 Tree-sitter(语法解析核心)
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = {
"python", "typescript", "tsx", "javascript", "rust",
"html", "css", "json", "yaml", "toml", "markdown", "bash", "lua"
},
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<CR>",
node_incremental = "<CR>",
scope_incremental = "<S-CR>",
node_decremental = "<BS>",
},
},
textobjects = {
select = {
enable = true,
lookahead = true,
keymaps = {
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = { ["]m"] = "@function.outer", ["]]"] = "@class.outer" },
goto_next_end = { ["]M"] = "@function.outer", ["]["] = "@class.outer" },
goto_previous_start = { ["[m"] = "@function.outer", ["[["] = "@class.outer" },
goto_previous_end = { ["[M"] = "@function.outer", ["[]"] = "@class.outer" },
},
},
})
end,
},
-- 🎯 Flash(快速定位)
{
"folke/flash.nvim",
dependencies = "nvim-treesitter/nvim-treesitter",
config = function()
require("flash").setup({
modes = {
char = { enabled = true, keys = { "f", "F", "t", "T" } },
},
labels = "abcdefghijklmnopqrstuvwxyz",
jump = { autojump = true },
highlight = {
groups = { match = { bg = "#3c3836", fg = "#fabd2f" } },
},
})
end,
},
-- 💬 智能注释
{
"numToStr/Comment.nvim",
config = function()
require("Comment").setup({
toggler = { line = "gcc", block = "gbc" },
opleader = { line = "gc", block = "gb" },
mappings = { basic = true, extra = true },
})
end,
},
-- 🧩 括号处理
{
"windwp/nvim-autopairs",
config = function()
require("nvim-autopairs").setup({
disable_filetype = { "TelescopePrompt", "vim" },
fast_wrap = {
map = "<M-e>",
chars = { "{", "[", "(", '"', "'" },
pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]], "%s+", ""),
end_key = "$",
keys = "qwertyuiopzxcvbnmasdfghjkl",
check_comma = true,
highlight = "PmenuSel",
highlight_grey = "LineNr",
},
})
end,
},
{
"HiPhish/rainbow-delimiters.nvim",
config = function()
require("rainbow-delimiters.setup").setup({
strategy = {
[""] = rainbow_delimiters.strategy["global"],
vim = rainbow_delimiters.strategy["local"],
},
})
end,
},
-- 🧩 代码片段
{
"L3MON4D3/LuaSnip",
dependencies = {
"saadparwaiz1/cmp_luasnip",
"rafamadriz/friendly-snippets",
},
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
require("luasnip").config.set_config({
history = true,
update_events = "TextChanged,TextChangedI",
})
end,
},
-- 🔍 文件导航
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
cmd = "Telescope",
config = function()
local actions = require("telescope.actions")
require("telescope").setup({
defaults = {
prompt_prefix = "🔍 ",
selection_caret = "➤ ",
path_display = { "truncate" },
sorting_strategy = "ascending",
layout_strategy = "horizontal",
layout_config = {
horizontal = { width = 0.9, height = 0.8 },
},
mappings = {
i = {
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
["<C-c>"] = actions.close,
},
},
},
})
end,
},
-- 📊 状态栏
{
"nvim-lualine/lualine.nvim",
config = function()
require("lualine").setup({
options = {
theme = "catppuccin",
section_separators = "",
component_separators = "",
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch" },
lualine_c = { "filename" },
lualine_x = { "encoding", "fileformat", "filetype" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
})
end,
},
-- 📁 项目管理
{
"ahmedkhalf/project.nvim",
config = function()
require("project_nvim").setup({
detection_methods = { "lsp", "pattern" },
patterns = { ".git", "package.json", "pyproject.toml", "Cargo.toml", "Makefile" },
manual_mode = false,
})
end,
},
-- 🖥️ 终端集成
{
"akinsho/toggleterm.nvim",
version = "*",
config = function()
require("toggleterm").setup({
size = 15,
open_mapping = [[<C-\>]],
hide_numbers = true,
shade_filetypes = {},
shade_terminals = false,
start_in_insert = true,
persist_size = true,
direction = "float",
close_on_exit = true,
})
end,
},
-- 📦 Git 集成
{
"lewis6991/gitsigns.nvim",
config = function()
require("gitsigns").setup({
signs = {
add = { text = "│" },
change = { text = "│" },
delete = { text = "_" },
topdelete = { text = "‾" },
changedelete = { text = "~" },
},
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
map('n', ']c', "&diff ? g] : ]c", { expr=true })
map('n', '[c', "&diff ? g[ : [c", { expr=true })
map('n', '<leader>hs', ':Gitsigns stage_hunk<CR>')
map('n', '<leader>hr', ':Gitsigns reset_hunk<CR>')
end
})
end,
},
}⌨️ 4. lua/core/keymaps.lua(统一快捷键 - 完整版)
-- ~/.config/nvim/lua/core/keymaps.lua
local map = vim.keymap.set
-- 🌐 全局通用
map("n", "<leader>w", "<cmd>w<cr>", { desc = "Save" })
map("n", "<leader>q", "<cmd>q<cr>", { desc = "Quit" })
map("n", "<leader>h", "<cmd>nohlsearch<cr>", { desc = "Clear highlights" })
-- 🔍 Telescope 导航
map("n", "<leader>ff", "<cmd>Telescope find_files<cr>", { desc = "Find Files" })
map("n", "<leader>fg", "<cmd>Telescope live_grep<cr>", { desc = "Live Grep" })
map("n", "<leader>fb", "<cmd>Telescope buffers<cr>", { desc = "Buffers" })
map("n", "<leader>fh", "<cmd>Telescope help_tags<cr>", { desc = "Help" })
map("n", "<leader>pp", "<cmd>Telescope projects<cr>", { desc = "Projects" })
-- 🎯 Flash 快速定位
if package.loaded["flash"] then
map({ "n", "x", "o" }, "s", "<cmd>lua require('flash').jump()<cr>", { desc = "Flash Jump" })
map({ "n", "x", "o" }, "S", "<cmd>lua require('flash').treesitter()<cr>", { desc = "Flash Treesitter" })
map({ "n", "x", "o" }, "r", "<cmd>lua require('flash').remote()<cr>", { desc = "Flash Remote" })
map({ "n", "x", "o" }, "f", "<cmd>lua require('flash').jump({ char = 'f' })<cr>", { desc = "Flash f" })
map({ "n", "x", "o" }, "F", "<cmd>lua require('flash').jump({ char = 'F' })<cr>", { desc = "Flash F" })
map({ "n", "x", "o" }, "t", "<cmd>lua require('flash').jump({ char = 't' })<cr>", { desc = "Flash t" })
map({ "n", "x", "o" }, "T", "<cmd>lua require('flash').jump({ char = 'T' })<cr>", { desc = "Flash T" })
end
-- 💬 注释
if package.loaded["Comment"] then
map("n", "gcc", "<cmd>lua require('Comment.api').toggle.linewise.current()<cr>", { desc = "Comment Line" })
map("v", "gc", "<cmd>lua require('Comment.api').toggle.linewise(vim.fn.visualmode())<cr>", { desc = "Comment Visual" })
map("n", "gbc", "<cmd>lua require('Comment.api').toggle.blockwise.current()<cr>", { desc = "Comment Block" })
map("v", "gb", "<cmd>lua require('Comment.api').toggle.blockwise(vim.fn.visualmode())<cr>", { desc = "Comment Block Visual" })
end
-- 🧩 括号快速包裹
if package.loaded["nvim-autopairs"] then
map("n", "<M-e>", "<cmd>lua require('nvim-autopairs.fast_wrap')()<cr>", { desc = "Fast Wrap" })
end
-- 🧩 代码片段
if package.loaded["luasnip"] then
map("i", "<C-j>", "<cmd>lua require('luasnip').jump(1)<cr>", { desc = "Snippet Next" })
map("i", "<C-k>", "<cmd>lua require('luasnip').jump(-1)<cr>", { desc = "Snippet Prev" })
map("i", "<C-l>", "<cmd>lua require('luasnip').expand_or_jump()<cr>", { desc = "Snippet Expand" })
end
-- 🌳 Tree-sitter 增量选择
map("n", "<CR>", "<cmd>lua require('nvim-treesitter.incremental_selection').init_selection()<cr>", { desc = "TS Select Init" })
map("n", "<S-CR>", "<cmd>lua require('nvim-treesitter.incremental_selection').scope_incremental()<cr>", { desc = "TS Select Scope" })
-- 📂 代码折叠
map("n", "zM", "<cmd>set foldlevel=0<cr>", { desc = "Fold All" })
map("n", "zR", "<cmd>set foldlevel=99<cr>", { desc = "Unfold All" })
map("n", "za", "<cmd>normal! za<cr>", { desc = "Toggle Fold" })
-- 📊 LSP 通用
map("n", "<leader>gd", "<cmd>lua vim.lsp.buf.definition()<cr>", { desc = "Go to Definition" })
map("n", "<leader>gr", "<cmd>lua vim.lsp.buf.references()<cr>", { desc = "References" })
map("n", "<leader>gR", "<cmd>lua vim.lsp.buf.rename()<cr>", { desc = "Rename" })
map("n", "<leader>ca", "<cmd>lua vim.lsp.buf.code_action()<cr>", { desc = "Code Action" })
map("n", "<leader>fd", "<cmd>lua vim.lsp.buf.format({ async = true })<cr>", { desc = "Format Document" })
-- 📁 Git
if package.loaded["gitsigns"] then
map("n", "<leader>gs", "<cmd>Gitsigns stage_hunk<cr>", { desc = "Git Stage" })
map("n", "<leader>gr", "<cmd>Gitsigns reset_hunk<cr>", { desc = "Git Reset" })
map("n", "]c", "&diff ? g] : ]c", { expr = true, desc = "Next Git hunk" })
map("n", "[c", "&diff ? g[ : [c", { expr = true, desc = "Prev Git hunk" })
end
-- 🖥️ 终端
map("n", "<C-\\>", "<cmd>ToggleTerm<cr>", { desc = "Toggle Terminal" })
-- ✍️ 写作环境专用
if vim.fn.filereadable(vim.fn.stdpath("config") .. "/.nvim-env-writer") == 1 then
map("n", "<leader>h1", "<cmd>put =repeat('#', 1) . ' '<cr>", { desc = "Header 1" })
map("n", "<leader>h2", "<cmd>put =repeat('#', 2) . ' '<cr>", { desc = "Header 2" })
map("n", "<leader>ul", "<cmd>put = '- '<cr>", { desc = "Unordered List" })
map("n", "]s", "]s", { desc = "Next misspelling" })
map("n", "[s", "[s", { desc = "Prev misspelling" })
map("n", "z=", "z=", { desc = "Spelling suggestions" })
end🚀 部署脚本
# 创建目录
mkdir -p ~/.config/nvim/lua/core
# 部署通用配置
# (将上面四个文件的内容分别保存到对应位置)
echo "✅ 通用插件配置部署完成!"
echo "📝 接下来可以逐个部署环境专用配置"✅ 通用功能验证清单
- Tree-sitter: 打开文件,检查语法高亮是否精准
- Flash: 按
s测试多字符跳转 - Comment: 按
gcc测试行注释 - Autopairs: 输入
{测试自动补全 - Telescope: 按
<leader>ff测试文件查找 - Git: 修改文件,查看行号旁的 Git 标记
- 折叠: 按
zM/zR测试代码折叠 - 终端: 按
<C-\>测试内置终端
现在你有了一个 完整的通用插件基础!接下来我们可以逐个生成环境专用配置:
- Python 环境
- TypeScript 环境
- Web 环境
- Rust 环境
- Writer 环境
你想先从哪个环境开始?