This is a personal Neovim configuration targeting Neovim 0.12+. It lives at ~/.config/nvim and is not a traditional software project — there is no build system, test suite, or package manager outside Neovim itself.
- Plugin manager: Neovim 0.12+ built-in
vim.pack(not lazy.nvim / packer).mini.nvimusesload = falseso its shared modules are immediately require-able; trigger-loaded plugins use a no-oploadcallback and explicit:packadd. All plugins are tracked innvim-pack-lock.json. - Custom lazy-loading:
lua/lazy.luais a small custom framework (unrelated to lazy.nvim). It providesload(),on_event(),on_keys()and tracks loaded modules inM._loaded. Command loading uses nativeCmdUndefined(viaon_event), so Neovim retries the original command without manual reconstruction. - Mini.nvim monorepo: Most UI/functionality comes from the single
mini.nvimpackage. Its submodules (starter, pick, extra, files, icons, notify, cmdline, completion, snippets, surround, clue, statusline, ai, cursorword, pairs) are configured individually inlua/pack.luaor on-demand.
init.lua → disables ~20 built-in plugins, sets colorscheme, loads core modules
options.lua → global vim options, yank highlighting, fold settings
keymaps.lua → keymaps (leader = space)
autocmds.lua → cursor restore, comment continuation, fold setup
usercmds.lua → :PackAdd, :PackDel, :PackUpdate, :PackClean
pack.lua → plugin declarations + lazy-loading bindings
:PackAdd user/repo " add plugin
:PackDel plugin-name " delete plugin
:PackUpdate [name] " update all or specific plugin
:PackClean " remove plugins no longer declared in pack.lua# Syntax check init.lua (run from repo root)
nvim --headless -c 'lua dofile("init.lua")' -c 'qa!'
# Check a specific module
nvim --headless -c 'lua require("pack")' -c 'qa!'
# Health check
nvim --headless -c 'checkhealth' -c 'qa!'
# Measure startup time
nvim --headless --startuptime /tmp/startup.log \
--cmd 'autocmd VimEnter * ++once lua vim.schedule(function() vim.cmd("qa!") end)'There is no traditional lint, typecheck, or test command. The validation commands above are the only verification steps.
When adding new plugins that should load lazily, use the custom framework in lua/lazy.lua — do not use lazy.nvim patterns.
| Trigger | Plugins / Modules |
|---|---|
| Startup | treesitter; missing-parser checks deferred 100ms |
VimEnter |
icons, clue, statusline |
Normal-buffer FileType |
lsp, mason(服务器按自身 filetypes 自动匹配) |
InsertEnter |
completion, snippets, pairs |
BufReadPost / BufWritePost |
gitsigns, surround, ai, cursorword |
BufWritePre |
conform (format-on-save) |
| Key press | pick, files, neogit, codediff, grugfar |
| Command | render-markdown, mason (CmdUndefined) |
Note: clue is set up on VimEnter (not via lazy.on_keys) because mini.clue must register prefix keys itself as buffer-local triggers, which is incompatible with the wrapper-mapping approach. Its buffer triggers are re-asserted on LspAttach and inside gitsigns' on_attach via MiniClue.ensure_buf_triggers().
nvim-treesitter/main is an eager-loading exception: activate it before the first FileType so queries are available. Its PackChanged hook asynchronously updates installed parsers only after that plugin is updated. Wait for updates to finish before restarting to reload parser binaries and queries.
- LSP servers: auto-detected in
lua/plugins/lsp.lua— any Mason-installed package whose registry spec declaresneovim.lspconfigis enabled automatically (no manual list to maintain). The scan runs when LSP/Mason is first initialized; after installing a new server with:MasonInstall, restart Neovim before opening a matching buffer. - Lua LSP:
vimis declared as a global inlua_lssettings to suppress "Undefined global" diagnostics - Formatters by filetype (
lua/plugins/lsp.lua):lua→ styluago→ gofumpt, goimportsjs/ts/json/jsonc/jsx/tsx→ biome (ifbiome.json/biome.jsoncfound upward) or prettierdcss/html/markdown→ prettierdtoml→ taplo
- Toggle autoformat:
vim.b[bufnr].autoformat = false(buffer) orvim.g.autoformat = false(global). Mapped to<leader>uf(global) /<leader>uF(buffer).
- Startup performance is a priority. Heavy modules are deferred to
VimEnteror the first relevantFileType, except nvim-treesitter's required early plugin/query loading. Parser installation checks and clipboard initialization remain deferred. - The active colorscheme is
ex-catppuccin-mocha, defined incolors/ex-catppuccin-mocha.lua. - Comments and UI strings are in Chinese.
- Line diagnostic float is on
<leader>df. Do not map baredf— it shadows thedf{char}operator-pending motion (delete-until-char), a footgun previously hit in this repo.
每完成一个功能点立即提交,Agent 自主判断提交时机——当一个逻辑完整的改动通过验证(语法检查 / nvim --headless 模块加载通过)后,无需等待用户指令,直接 git add + git commit。
- 提交粒度按"功能点"而非"文件":相关联的多文件改动合并为一个提交,不相关的改动拆成多个提交。
- 提交信息格式:遵循历史格式
type(scope): 中文描述type:feat(新功能)、fix(修复)、refactor(重构)、chore(杂项)等scope:功能域,如files、lsp、statusline、conform、clue、pack、pick、starter、git、fold等;跨域改动可省略 scope- 描述用中文,简明扼要说明"做了什么"
- 示例:
feat(files): mini.files 中支持复制文件路径、fix: 修复 review 发现的 7 处问题
- 提交前必须验证:改动涉及哪个模块就用对应的
nvim --headless -c 'lua require("xxx")' -c 'qa!'检查,确保不破坏启动。