Home › Neovim plugins (Lua) › Neovim Lua plugin CLAUDE.md
Neovim Lua plugin CLAUDE.md
CLAUDE.md for Neovim plugins in Lua: setup(opts) config merging, autocommand groups, keymaps with desc, lazy loading, :checkhealth, and headless tests.
Claude Code (CLAUDE.md)Neovim plugins (Lua)
How to use
Save this as CLAUDE.md in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
Note: Review and test before use. Provided as is, without warranty. See Terms.
CLAUDE.mdDownload # CLAUDE.md: Neovim plugin (Lua)
## Commands
- Tests run headless: use the repo's harness (`make test`, `busted`, `nvim -l tests/minimal_init.lua`, plenary or mini.test). Never require a user config.
- Format with `stylua .`; lint with `selene` or `luacheck` if configured.
- Respect the minimum Neovim version in the README; check `vim.fn.has('nvim-0.x')` before using newer APIs (`vim.uv` vs `vim.loop`, `vim.system`, `vim.iter`).
## Layout
- `lua/<plugin>/init.lua` exposes `M.setup(opts)` and the public API; internals in `lua/<plugin>/*.lua`. `plugin/<plugin>.lua` only defines user commands and must load fast (no heavy `require` at startup).
- `doc/<plugin>.txt` vimdoc is updated with every option or command change.
- `lua/<plugin>/health.lua` implements `check()` using `vim.health.start/ok/warn/error` for dependencies and config problems.
## Code
- Merge config with `vim.tbl_deep_extend('force', defaults, opts or {})` and validate with `vim.validate`. Work with sensible defaults when `setup()` is never called, if the README says so.
- Autocommands always in a named group: `local group = vim.api.nvim_create_augroup('<plugin>', { clear = true })`. Keymaps via `vim.keymap.set` with `desc`; don't set global mappings by default—offer `<Plug>` mappings or options.
- No global variables or polluting `_G`. Module-local state only; buffer-local state in `vim.b[bufnr]` or tables keyed by buffer number, cleared on `BufWipeout`.
- Use `vim.api.nvim_*` functions over `vim.cmd` strings where an API exists. Always pass explicit buffer/window handles; don't assume the current one inside callbacks.
- Async work with `vim.system` or `vim.uv`; schedule UI updates back with `vim.schedule`. Never block the editor with synchronous shell calls.
- Report to users with `vim.notify(msg, vim.log.levels.WARN, { title = '<plugin>' })`; errors in callbacks are caught so one failure doesn't spam every keystroke.
## Done when
Tests pass headless, stylua clean, and `:checkhealth <plugin>` and vimdoc reflect any new options.