|
| 1 | +--- |
| 2 | +name: lua-toolkit |
| 3 | +description: Neovim Lua plugin development playbooks following mrcjkb / nvim-best-practices conventions — project architecture, self lazy-loading, vim.g configuration, scoped commands and <Plug> keymaps, health checks, type-safe tooling, busted testing, and LuaRocks distribution. Use when writing or refactoring a Neovim Lua plugin, designing vim.g/setup config, deciding command/keymap APIs, adding checkhealth, configuring lua-ls/luacheck/stylua/LuaCATS, or setting up busted/nlua tests and SemVer LuaRocks releases. |
| 4 | +--- |
| 5 | + |
| 6 | +# Lua Toolkit |
| 7 | + |
| 8 | +Use this skill for authoring and refactoring Neovim Lua plugins targeting |
| 9 | +LuaJIT/Lua 5.1. It covers architecture, loading strategy, configuration design, |
| 10 | +public API surface, tooling, testing, and distribution. |
| 11 | + |
| 12 | +Guidance follows the mrcjkb / nvim-best-practices conventions (LuaRocks-first, |
| 13 | +type-safe, self-lazy-loading, no forced `setup()`). This skill is Neovim-plugin |
| 14 | +specific. For general Lua embedded elsewhere, only the tooling and runtime |
| 15 | +guardrails transfer. |
| 16 | + |
| 17 | +## How I choose what to do (progressive disclosure) |
| 18 | + |
| 19 | +When invoked, route to one mode and load only that reference unless the work |
| 20 | +crosses boundaries: |
| 21 | + |
| 22 | +1. **plugin-architecture** — directory layout, `plugin/` vs `lua/` separation, |
| 23 | + deferred loading, modular refactoring, and LuaJIT runtime guardrails. |
| 24 | +2. **configuration** — `vim.g.<plugin>` config tables (not forced `setup()`), |
| 25 | + `vim.tbl_deep_extend` merge semantics, `vim.validate` (0.11+ signature), and |
| 26 | + `health.lua` checks. |
| 27 | +3. **loading-and-install** — self lazy-loading (don't rely on the plugin |
| 28 | + manager), minimal install specs, native-API-over-deps, and `build` steps. |
| 29 | +4. **apis-and-keymaps** — single scoped command with subcommand completion, |
| 30 | + `<Plug>` mappings with no default keymaps, buffer-local state, and |
| 31 | + `ftplugin`/`after/ftplugin` filetype logic. |
| 32 | +5. **tooling-and-quality** — LuaCATS + lua-ls type safety, `.luarc.json`, |
| 33 | + `.luacheckrc`, and `.stylua.toml`. |
| 34 | +6. **testing-and-distribution** — `busted` + `nlua` tests, CI matrices, vimCATS |
| 35 | + Vimdoc generation, and SemVer LuaRocks publishing. |
| 36 | + |
| 37 | +If intent is unclear, ask for the mode before applying changes. |
| 38 | + |
| 39 | +## Playbooks |
| 40 | + |
| 41 | +- Read [plugin-architecture.md](references/plugin-architecture.md) for the |
| 42 | + runtimepath directory model, no-runtime-entrypoint plugins, the |
| 43 | + deferred-`require` loading pattern, the `util.lua` refactoring imperative, |
| 44 | + global-pollution rules, and the `if jit then ... else` fallback pattern. |
| 45 | +- Read [configuration.md](references/configuration.md) for the `vim.g.<plugin>` |
| 46 | + (table-or-function) config pattern, partial LuaCATS config classes, |
| 47 | + dictionary-vs-list `tbl_deep_extend` behavior, the modern `vim.validate` |
| 48 | + signature, and `lua/<plugin>/health.lua` checks. |
| 49 | +- Read [loading-and-install.md](references/loading-and-install.md) for |
| 50 | + self-lazy-loading via `plugin/`+`ftplugin/`, minimal lazy.nvim install specs, |
| 51 | + preferring native APIs over `plenary`, `lazy = true` deps, and coroutine |
| 52 | + `build` constraints. |
| 53 | +- Read [apis-and-keymaps.md](references/apis-and-keymaps.md) for the scoped |
| 54 | + subcommand + `complete` pattern, `<Plug>` mappings with no default keymaps, |
| 55 | + buffer filetype assignment timing, and `ftplugin` vs `after/ftplugin`. |
| 56 | +- Read [tooling-and-quality.md](references/tooling-and-quality.md) for LuaCATS + |
| 57 | + lua-ls as the primary correctness tool, `.luarc.json` (`"Lua 5.1"`), the |
| 58 | + `lua51` luacheck config, and the stylua baseline. |
| 59 | +- Read [testing-and-distribution.md](references/testing-and-distribution.md) for |
| 60 | + `busted`+`nlua` (and `neorocksTest` for Nix), the stable/nightly CI matrix, |
| 61 | + vimCATS/panvimdoc generation, and SemVer `.rockspec`/`luarocks-tag-release`. |
| 62 | + |
| 63 | +## Core Rules (apply in every mode) |
| 64 | + |
| 65 | +- Target Lua 5.1 / LuaJIT 2.1. Do not use Lua 5.2+ dialect features (new `goto` |
| 66 | + scoping, integer division, native bitwise operators); use `require("bit")` for |
| 67 | + bit ops — Neovim guarantees it even on non-JIT builds. |
| 68 | +- Never declare globals. All state, caches, and functions live in `local` |
| 69 | + bindings or the module table returned by the file. |
| 70 | +- Separate configuration from initialization. Do not force `setup()`; prefer a |
| 71 | + `vim.g.<plugin>` config table read lazily. |
| 72 | +- Self-lazy-load: keep startup work out of `lua/`, use `plugin/`+`ftplugin/`, |
| 73 | + and defer `require()` into command/keymap closures. Don't rely on the plugin |
| 74 | + manager to lazy-load for you. |
| 75 | +- Expose one scoped command with subcommand completion, not many commands. |
| 76 | +- Expose user-bindable actions as `<Plug>` mappings and ship no default keymaps. |
| 77 | +- Prioritize type safety: LuaCATS annotations + lua-ls, gated in CI. |
| 78 | +- Distribute on LuaRocks with SemVer; never `0ver`. |
| 79 | + |
| 80 | +## Reference Implementations |
| 81 | + |
| 82 | +Concrete examples in this skill are drawn from these repos — consult them for |
| 83 | +full, working context: |
| 84 | + |
| 85 | +- `mrcjkb/nvim-best-practices` — the prose rules this skill follows. |
| 86 | +- `mrcjkb/nvim-lua-nix-plugin-template` — Nix CI: `.busted`, `neorocksTest` |
| 87 | + stable/nightly checks, `lemmy-help` docgen, `luarocks-tag-release`, |
| 88 | + release-please. Closest match for this (Nix) repo. |
| 89 | +- `mrcjkb/rustaceanvim` — `vim.g.<plugin>` config (table-or-function), scoped |
| 90 | + `:RustLsp` command with completion, `ftplugin`-based loading (no `plugin/`), |
| 91 | + `health.lua`, `.luarc.json`. |
| 92 | +- `mrcjkb/neotest-haskell` — adapter/library with no runtime entry points; |
| 93 | + one-module-per-responsibility `lua/` tree and tree-sitter `queries/`. |
| 94 | + |
| 95 | +## Cross-Skill Boundaries |
| 96 | + |
| 97 | +- Use `writing-nix` before editing any Nix that packages or wires the plugin |
| 98 | + (e.g. Nixvim/`vimUtils` derivations). |
| 99 | +- Use `git-toolkit` for commit strategy and local history surgery. |
| 100 | +- Use `github-toolkit` for PR review comments and CI check triage. |
| 101 | +- Prefer one-off tooling via `nix shell`/`,` (stylua, luacheck, neovim nightly) |
| 102 | + instead of adding persistent dependencies just to lint or test. |
| 103 | + |
| 104 | +## Reporting Rules |
| 105 | + |
| 106 | +- Show exact commands, file paths, and minimal snippets. |
| 107 | +- Label snippets as one of: executed, syntax checked, or template only. |
| 108 | +- Separate measured facts (startup time, test output) from design guidance. |
| 109 | +- Name the Neovim version when behavior is version-gated (e.g. `vim.validate` |
| 110 | + signature deprecated in 0.11, removed in 1.0). |
0 commit comments