Skip to content

Latest commit

 

History

History
577 lines (444 loc) · 38.5 KB

TODO.md

File metadata and controls

577 lines (444 loc) · 38.5 KB

TODO

Phase 0 - Repository Hygiene

  • Replace the old install script with a real CLI in bin/
  • Add a dedicated test runner under tests/
  • Rename TODO to TODO.md
  • Remove exploratory Lua files not used by the runtime config
  • Decide whether .tmux.conf belongs in this repository
  • Add LICENSE.md after validating the license choice

Phase 1 - Safety Net

  • Add a first failing smoke-level CLI test suite
  • Make the initial CLI tests pass
  • Add a Neovim startup smoke test for init.lua
  • Add regression tests for startup failures fixed in the config

Phase 2 - Startup Stability

  • Fix invalid null-ls sources
  • Remove or replace deprecated nvim-tree options
  • Migrate legacy kyazdani42 plugin namespaces to maintained repositories
  • Replace null-ls.nvim with the maintained none-ls.nvim repository
  • Remove references to plugins or features that are not installed
  • Consolidate diagnostics UX on trouble.nvim and remove diaglist
  • Audit keymaps that depend on optional plugins

Phase 3 - LSP And Completion

  • Replace nvim-lsp-installer with a maintained setup
  • Update deprecated LSP capability and formatting calls
  • Define an explicit maintained baseline for default LSP servers
  • Validate nvim-cmp and LuaSnip end-to-end
  • Add regression coverage for LSP bootstrap failures
  • Migrate LSP config to mason-lspconfig v2 API (setup_handlers removed in v2.0.0)

Phase 4 - Treesitter And UI Reliability

  • Replace ensure_installed = 'all' with an explicit parser list
  • Remove unsupported Treesitter modules or add the missing plugins
  • Verify lualine, bufferline, telescope, and trouble startup paths
  • Migrate Trouble keymaps from v1 API (workspace_diagnostics, document_diagnostics) to current API
  • Replace nvim-tree with neo-tree.nvim
  • Decide whether nvim-gps should be replaced with nvim-navic or aerial.nvim
  • Remove lsp-colors.nvim (redundant with Neovim 0.9+ built-in diagnostic highlights)
  • Audit Telescope extensions and remove unused or redundant integrations

Phase 5 - Documentation

  • Write a keybindings cheatsheet covering all custom mappings and plugin shortcuts
  • Write extended usage documentation (LSP workflow, completion, diagnostics, telescope, bufferline)
  • Add <Leader>? keymap to open Telescope keymaps picker (in-Neovim discoverability)
  • Annotate which-key groups with descriptions (<Leader>f = Find, <Leader>d = Diagnostics, etc.)

Phase 7 - Install And Portability

  • Add bash completion support to the CLI
  • Add zsh completion support to the CLI
  • Add fish completion support to the CLI
  • Rewrite install to cover symlink/bootstrap flows explicitly
  • Document external dependencies required by the Neovim config
  • Document bootstrap limitations in sandboxed or Snap-based environments
  • Add install nvim [--snap|--apt] subcommand (snap by default, checks if already installed)
  • Extend install all to include install nvim in the full bootstrap chain
  • Add update nvim subcommand (snap refresh or apt upgrade depending on install method)
  • Add update plugins subcommand (headless Lazy! sync via nvim --headless)
  • Add update subcommand dispatching to update nvim + update plugins
  • Document Neovim installation (minimum version, recommended method per platform)
  • Document first-run initialization sequence (lazy.nvim bootstrap → plugin install → Mason LSP server install)
  • Document full end-to-end setup flow for a new machine in README

Phase 8 - Optional Modernization

  • Decide whether to keep packer.nvim or migrate to a maintained plugin manager
  • Normalize plugin declarations and config loading patterns
  • Reduce eager startup side effects where not needed
  • Design project profiles so Neovim can enable only relevant tooling per repository
  • Decide whether the CLI should manage project profiles or only bootstrap them
  • Add in-Neovim profile switcher: :NvimProfile <name> user command + Telescope picker (depends on profile design)
  • Move frontend-only tooling such as emmet-vim behind project profiles
  • Move Node-specific Telescope integrations behind project profiles
  • Decide whether none-ls.nvim should remain global or have profile-driven sources

Phase 9 - UI Consolidation (Long-term)

Two interchangeable UI variants: classic (current stack) and modern (snacks.nvim suite). Variant chosen at Neovim startup. Default is classic unless .nvim-ui exists at the config root. CLI manages the file; .nvim-ui is gitignored.

Design: Option B — independent of the profile system. Layout: lua/ui/variant.lua — reads .nvim-ui, returns 'classic' (default) or 'modern' lua/ui/shared.lua — colorscheme, lualine, bufferline, nvim-navic (common to both variants) lua/ui/classic.lua — telescope (fzf + node_modules extensions), which-key, trouble lua/ui/modern.lua — snacks.nvim (picker, notifier, dashboard)

Evaluation result: snacks.nvim has no statusline or breadcrumb module. lualine and nvim-navic stay in shared.lua for both variants. The visible difference: picker (snacks vs telescope) and notifications.

CLI: nvim-config ui set classic|modern / nvim-config ui unset

  • Evaluate snacks.nvim as the modern variant foundation (picker, statusline, notifier, dashboard, breadcrumb)
  • Implement lua/ui/ structure (variant, shared, classic, modern)
  • Move current UI plugins into lua/ui/classic.lua
  • Implement lua/ui/modern.lua once evaluation is done
  • Add nvim-config ui set|unset CLI subcommand
  • Add .nvim-ui to .gitignore

Phase 10 - Test Suite Maintenance

  • Split tests/nvim-config.bats by domain (CLI, profiles, LSP/completion, UI/plugins, docs) for readability

Phase 11 - Quality of Life

Incremental improvements with high daily value, low implementation cost. Ordered by recommended priority.

High value

  • Clear search highlight — <Leader><CR> in normal mode to call :noh
  • Auto-save on focus loss — autocmd FocusLost/BufLeave → :silent! wa
  • gitsigns.nvim — inline diff signs, line blame, hunk navigation (]h/[h), stage/reset hunk
  • Line number toggle — <Leader>tn cycles absolute → relative → none; new <Leader>t Toggle group

Medium value

  • :w!! sudo save — write system files without relaunching Neovim as root
  • :Cheat picker — :Cheat with no argument opens vim.ui.select (variant-agnostic); with argument opens directly
  • Session restore — persistence.nvim: auto-restore on startup (no args), <Leader>qs restore, <Leader>qd stop

Phase 12 - Themes, Markdown And Filetype Detection

  • Persistent colorscheme system — lua/ui/theme.lua, .nvim-theme (gitignored), 14 dark themes
  • 4 new colorscheme plugins — catppuccin (3 variants), tokyonight (3), kanagawa (2), gruvbox-material
  • theme-init lazy.nvim spec at priority=0 — applies active colorscheme after all plugins, prevents flash
  • :Theme [name] user command — applies and persists colorscheme, tab-completion on all 14 names
  • nvim-config theme set|unset CLI subcommand — mirrors ui command; bash and zsh completions updated
  • render-markdown.nvim — in-buffer markdown rendering (headings, code blocks, bullets, checkboxes, tables); lazy-loaded on ft=markdown
  • Bash shebang detection — extensionless files with #!/.../bin/bash or #!/.../env bash auto-detected as sh via vim.filetype.add
  • Keymaps cleanup — <C-s> added in normal mode; <C-z> and <C-r> removed from insert mode (terminal conflicts, native Vim override)
  • Test coverage — 43 new tests (229 total) covering all Phase 12 additions

Phase 13 - Quality Of Life And AI

Navigation

  • harpoon (ThePrimeagen/harpoon2) — mark/jump to 4-5 key files per project (<Leader>ha, <Leader>hh, <C-1..4>)
  • vim-illuminate — auto-highlight all occurrences of the word under cursor

Editing

  • friendly-snippets — already wired as LuaSnip dependency with lazy_load()
  • nvim-spectre — project-wide search/replace (<Leader>sr, <Leader>sw)
  • mini.ai — extended text objects: function args, brackets across lines (ia/aa), n_lines=500

Git

  • diffview.nvim — enhanced diff view (<Leader>gv) and per-file git history (<Leader>gH); complements gitsigns
  • lazygit.nvim — open lazygit in a floating terminal window from inside Neovim

Code quality

  • todo-comments.nvim — colorise TODO/FIXME/HACK/NOTE in code; list all via Telescope (<Leader>ft)
  • indent-blankline.nvim — visual indent guides (essential for YAML, Python, nested Lua)

Testing and debugging

  • neotest — run and visualise test results inside Neovim (bats, phpunit, jest...)
    • neotest-bash adapter — bats-core support
    • Profile-driven adapters: neotest-vitest (web), neotest-phpunit (php/laravel), neotest-rust (rust) — loaded via profiles.get_neotest_adapters() + profile neotest_adapters field
  • nvim-dap + nvim-dap-ui — interactive debugger with breakpoints and UI
    • nvim-dap-virtual-text — inline variable values during debug
    • one-small-step-for-vimkind — Lua DAP adapter (built-in, no Mason install)
    • Profile-driven adapters: pwa-node/JS-TS (web), Xdebug/PHP (php/laravel), codelldb/Rust (rust)
    • Auto-install DAP Mason packages at startup via profiles.get_dap_mason_packages() + Mason registry

Writing

  • zen-mode.nvim — distraction-free fullscreen mode (<Leader>tz)

Terminal and AI agents

  • toggleterm.nvim — floating terminal (<C-\>, <Leader>tt); dedicated Claude Code (<Leader>tC) and Codex CLI (<Leader>tX) instances
  • install claude CLI subcommand — install Claude Code CLI (npm install -g @anthropic-ai/claude-code); skips if present; errors if npm missing
  • install codex CLI subcommand — install OpenAI Codex CLI (npm install -g @openai/codex); same guards
  • codeium.nvim — free inline AI completion; nvim-cmp source [AI]; :Codeium Auth on first use
  • avante.nvim — Cursor-like AI assistant (chat + inline edits); auth_type = "pro" authenticates via Claude Pro subscription (browser OAuth, no API key required); also supports GPT-4o
  • Gemini CLI — @google/gemini-cli (npm); free tier via Google account; install gemini CLI subcommand + dedicated toggleterm terminal <Leader>tG

Phase 14 - CLI Enhancements

Info and diagnostics

  • nvim-config status — summary: active variant, theme, profile, Neovim version
  • nvim-config doctor — health check: Neovim, required binaries (git, make, rg, fdfind, node, npm), optional tools (lazygit, tmux, claude, codex, gemini, cargo, gcc)
  • nvim-config theme info — current active theme (reads .nvim-theme)
  • nvim-config ui info — current active UI variant (reads .nvim-ui)
  • nvim-config profile info — active profile + associated LSP servers and DAP packages (parsed from profile lua file)

Discovery

  • nvim-config theme list — list all 14 available themes, mark the active one with *
  • nvim-config profile list — list all available profiles, mark active with *; skip internal files (init, picker)
  • nvim-config keymaps — open docs/keymaps.md in $PAGER

Maintenance

  • nvim-config update dap-adapters — show DAP packages for active profile, trigger Mason install headlessly

Phase 15 - Plugin Modernization And UX

Formatters and linters (modernization)

  • conform.nvim — modern formatter replacing none-ls formatting sources; per-filetype formatter chains; format_on_save option
  • nvim-lint — modern linter replacing none-ls diagnostic sources; event-driven (BufWritePost, InsertLeave)
  • Migrate profiles to use conform/nvim-lint sources instead of none-ls (additive, keep none-ls as fallback during transition)

UI enhancements

  • noice.nvim — floating cmdline (cmdline_popup), popup messages, LSP progress; notify.enabled false in modern variant (snacks owns vim.notify); LSP hover/signature kept native
  • nvim-ufo — LSP/treesitter-aware folding; zR open all, zM close all, K peek fold (falls back to LSP hover); provider chain: lsp → treesitter → indent

File management

  • oil.nvim — edit filesystem as a buffer (rename, move, delete via normal editing); - to open parent dir; default_file_explorer = false to coexist with neo-tree

Navigation

  • marks.nvim — visual marks in sign column with m[a-z] gutter indicators; ]'/[' line jumps, ]`/[` column jumps; builtin marks (. < > ^) shown

Phase 16 — Portability and MCP ecosystem (target 0.5.0)

Portability

  • Termux profile (lua/profiles/termux.lua) — environment profile for Android ARM:

  • Python language profile (lua/profiles/python.lua) — auto-detected from pyproject.toml, setup.py, setup.cfg, requirements.txt; LSP: pyright; conform: ruff_format+black; lint: ruff, mypy; neotest: neotest-python; DAP: debugpy (Mason)

    • (details in .private/termux.md)

MCP ecosystem

AI stack (after codecompanion.nvim benchmark)

  • Benchmark codecompanion.nvim vs avante.nvim — plugin installed alongside avante; <Leader>cc/<Leader>cx; evaluation pending on a real project → https://github.com/olimorris/codecompanion.nvim
  • AI profile — opt-in ai profile (lua/profiles/ai.lua) activating avante, codecompanion, codeium, mcphub, mcp-diagnostics via cond = is_active('ai') (implemented)

Phase 17 — Mise Integration

  • nvim-config install mise — curl + GPG-signature-verified installer (official mise release key), idempotent
  • install nvim — interactive cascade: mise (if present, else prompt to install) → snap (if present, else prompt to install snapd) → apt fallback; prompts auto-decline outside a TTY, under --quiet, or under --dry-run
  • update nvim — prefer mise automatically when Neovim was installed through it (mise use -g neovim@latest); snap/apt auto-detection unchanged otherwise
  • --mise/--snap/--apt flags bypass the cascade and fail fast with a clear error if the corresponding tool is missing
  • nvim-config doctor — mise added to the optional tools check
  • Fix: install nvim/install all no longer crash with sudo: snap: command not found on systems without snap
  • Fix: log_message no longer double-prints ERROR lines (stdout + stderr) — ERROR now goes to stderr only
  • Fix: cascade no longer aborts on a failed optional step (mise/snapd) — falls through to the next fallback instead
  • Fix: install all runs deps/config independently of the nvim step's outcome instead of aborting on first failure
  • Fix: install deps installs gnupg, required by install mise
  • Fix: the "install mise?" prompt lists and offers to install every missing prerequisite (curl, gnupg) via apt in the same step, instead of failing after the user already opted in
  • Fix: tmp_dir: unbound variable crash at script exit — run_install_mise's cleanup trap is now explicitly cleared before returning instead of lingering process-wide
  • All apt install calls now pass -y — the user already confirmed via the CLI invocation or an interactive prompt, apt shouldn't ask again
  • install nvim --mise / --snap now bootstrap mise/snapd on the spot instead of erroring and leaving nothing installed (explicit flag = consent, no need for a separate install mise run first)
  • mise shell activation: prompt to add the activation line to the user's shell rc (bash/zsh/fish) after a fresh install mise, idempotent (skips if already present), with a reload reminder; --activate/--no-activate flags to force either outcome unattended (for automated installs)
  • install nvim --mise: auto-installs missing prerequisites (curl/gnupg) via apt with no extra prompt, since --mise is already explicit consent
  • Fix: set -e is silently suppressed for the whole call subtree when a function is used as the left side of || (as run_install_nvim always is, from install all) — every fallible step in _install_nvim_via, _install_nvim_auto, and run_install_deps is now explicitly guarded instead of relying on implicit propagation
  • Fix: run_install_mise now adds ~/.local/bin to its own PATH right after a successful install so mise use -g neovim@latest works immediately in the same run, without waiting for a shell reload
  • The mise activation "reload your shell" reminder is now repeated once more at the very end of install nvim/install mise/install all, so it isn't buried under later apt output
  • Fix: the activation line used bare mise activate bash, which needs mise on PATH just to run — chicken-and-egg, still broken after source ~/.bashrc. Now uses the absolute mise binary path (matching mise's own installer recommendation), plus an explicit ~/.local/bin PATH guard line as defense in depth
  • Fix: that PATH guard line is now idempotent at shell-startup time (bash/zsh: case ":$PATH:" in ... check; fish: built-in fish_add_path), not just at file-write time — re-sourcing the rc file no longer accumulates duplicate PATH entries
  • Fix: git is a mandatory prerequisite (lazy.nvim bootstrap) but was only documented as "assumed present", never actually installed — install deps now installs it. lua/plugins.lua also checks vim.fn.executable('git') before bootstrapping and prints one clear actionable message instead of letting Neovim crash with a raw E475: Invalid value for argument cmd: 'git' is not executable

Phase 18 — UI Fixes

  • Fix: noice.nvim routed list-style command output (:scriptnames, :marks, :registers, :highlight, :map, :autocmd, :command, :buffers, ...) through the same notify view as :echo/:echomsg, with opts.replace = true; once the prior nvim-notify toast auto-dismissed, replaying the same or another list-style command tried to replace an expired notification and silently showed nothing. list_cmd-kind messages now route to a split view instead

Phase 19 — Dependency Fixes

  • Fix: make is checked by nvim-config doctor under "Required binaries" but was never installed by install deps, silently breaking telescope-fzf-native.nvim's native build on a fresh machine — same class of oversight as the git fix (Phase 17)
  • Fix: make alone isn't enough for telescope-fzf-native.nvim — its Makefile also needs cc. install deps now installs gcc, and doctor moves it from optional "Build tools" to "Required binaries" (cargo stays optional)
  • install deps installs wl-clipboard alongside xsel/xclip — no Wayland clipboard support previously. Installed unconditionally (not auto-detected) since session-type detection is unreliable when install deps runs over SSH or before any graphical session starts; Neovim's clipboard provider already picks the right tool at runtime

Phase 20 — Editing Performance

  • Fix: vim.opt.clipboard = 'unnamedplus' made every yank/delete/put shell out to the system clipboard tool, laggy enough on slower setups (containers) that holding x/p down only registered the first press. Removed — YY/XX/PP already give explicit, on-demand clipboard access, making automatic sync both redundant and the source of the lag

Phase 21 — LSP Fixes

  • Fix: jsonls auto-install failed on every startup with a Mason error (Could not find executable "npm" in PATH) on machines without Node.js, since json-lsp is an npm package and Node.js is intentionally opt-in (install deps --with-node). Now gated on vim.fn.executable('npm'), skipped silently instead of retrying a known failure; lua_ls (standalone binary) is unaffected

Phase 22 — Treesitter Fixes

  • Fix: nvim-treesitter failed to build parsers on first launch (ENOENT ... 'tree-sitter') — the vendored CLI (nvim-config update tree-sitter → vendor/tree-sitter/) was never added to Neovim's PATH, and the command was undocumented. lua/config/treesitter.lua now prepends the vendor dir to PATH when present; install all now also runs update tree-sitter automatically (idempotent) so it works out of the box on a fresh install

Phase 23 — Shell Completion Fixes

  • Full code/doc consistency audit: --help verified complete against the actual command dispatch (no command, subcommand, or flag missing or stale) — no gaps found
  • Fix: bash completion offered list detect set unset create info (profile's subcommands) after ui set/theme set instead of classic modern / theme names — set/unset/info are shared across profile/ui/theme and matching on the previous word alone picked profile's pattern first; a dedicated classic|modern) case existed but was dead code, unreachable due to case ordering. Bash completion now dispatches on the top-level command first
  • zsh gained the missing third-level completion (ui set → classic/modern, theme set → theme names) — it only completed two levels deep before
  • fish gained theme-name completion after theme set, for parity with the ui/set/classic-modern completion it already had
  • Theme names are now injected into all 3 generated completion scripts from the single VALID_THEMES array (placeholder substitution in show_completion()) instead of being hand-duplicated — one source of truth

Phase 24 — Pre-Publication Hygiene

  • Fix: .private/ and vendor/ were only ignored via the maintainer's personal global ~/.gitignore, not the project's own — a blind spot for anyone else cloning the repo. Added explicitly, plus the missing .nvim-profile entry (third local override file, siblings .nvim-ui/.nvim-theme were already covered) and standard OS/editor artifacts
  • Added SECURITY.md and CONTRIBUTING.md ahead of making the repo public (0.7.1)
  • CI triggers scoped down: push limited to main/develop/conventional branch prefixes (no more tags, no more scratch branches), pull_request limited to PRs targeting main; added workflow_dispatch and a concurrency group (already required by this project's own CI conventions, previously missing)
  • detect-changes job skips lint/test (via job-level if:, not a trigger-level paths-ignore) when a push/PR only touched **/*.md/docs/**/.editorconfig — the workflow still always runs so required status checks are never left stuck waiting

Phase 25 — CLI Uninstall Command

  • nvim-config uninstall [config|nvim|mise|deps|all] — reverses the corresponding install subcommand(s): removes the ~/.config/nvim symlink (only if it points at this repository), removes Neovim (detects mise/snap/apt, same detection as update nvim, asks for confirmation), removes the mise binary and the shell activation lines install mise added (identified by its own marker comment; tools mise managed are left untouched)
  • uninstall deps never runs apt remove — the packages install deps installs are shared system dependencies other tools may also rely on; it only prints the manual removal command. uninstall all follows the same policy and excludes deps
  • uninstall nvim/uninstall mise are gated behind _confirm, auto-declining under --dry-run/--quiet/outside a TTY, consistent with every other confirmation prompt in this CLI
  • Shell completion (bash/zsh/fish) and --help updated for the new command; README gained an "Uninstalling" section documenting the deps policy explicitly

Phase 26 — Native Commenting

  • Fix: gc/gcc printed [Comment.nvim] nil and commented nothing in any buffer without a treesitter parser (ssh config, php) — Comment.nvim assumes vim.treesitter.get_parser() raises when no parser exists, but on Neovim 0.12 it returns nil; the plugin is unmaintained since June 2024
  • Replace Comment.nvim with Neovim's native commenting (gc/gcc, counts, dgc); minimum Neovim raised to 0.10; php buffers keep // comments via a commentstring override
  • Profiles can declare treesitter_parsers (php → php, laravel → blade, web → tsx/vue/svelte, rust → rust/toml, python → python/toml); installed at startup and on runtime :NvimProfile activation; ssh_config added to the global parser list
  • Commenting documented in docs/cheatsheets/editing.md (count and motions included)

Phase 27 — Silent failures

  • update / update tree-sitter exited 1 without a message when the GitHub release lookup failed (offline or rate limited) — set -e ended the script inside a $(curl | grep | sed) assignment before the error was logged; now a clear error
  • --dry-run no longer depends on the network for that lookup (warns and succeeds), which had made four unrelated tests fail whenever the anonymous API quota was exhausted
  • tree-sitter download checked step by step (no more "updated" message after a failed download); a vendored binary that cannot run is replaced instead of aborting; uninstall nvim no longer aborts silently when mise current fails
  • uninstall nvim|mise --dry-run prints the removal plan instead of "Skipped" (the consent prompt is skipped in dry-run only); covered by tests with fake mise/snap/nvim

Phase 28 — Shell Profile

  • shell profile: shellcheck (nvim-lint) and shfmt (conform) for sh buffers (which covers .sh, .bash, .bats and shebang scripts); auto-detected from .shellcheckrc, a root-level *.sh/*.bash or tests/*.bats, otherwise opt-in; no language server (deferred, see below)
  • shfmt runs on demand only: conform no longer formats sh buffers on save — measured on this repo, saving bin/nvim-config would have rewritten ~970 of 1930 lines (2 470 with the tabs default of a .editorconfig that does not match the file)
  • nvim-config profile detect mirrored the Lua detection only partly: it ignored python and termux; now complete, plus shell
  • nvim-config doctor lists shellcheck and shfmt under "Shell tools (optional)"

Phase 29 — DevOps Profile

  • devops profile: hadolint (Dockerfile) and actionlint (GitHub workflows) through nvim-lint, dockerfile parser; auto-detected from a Dockerfile, a compose file or .github/workflows/
  • New generic profile field mason_packages (+ profiles.get_mason_packages() and install_mason_packages()): Mason-installed tools that are not in apt, installed at startup and on runtime :NvimProfile activation, skipped on Termux; a test checks every declared name exists in the Mason registry
  • Workflow files get the compound filetype yaml.github so actionlint never runs on arbitrary YAML (nvim-lint and conform split compound filetypes on the dot, so yaml tooling is unchanged)
  • nvim-config doctor lists actionlint and hadolint, looking in Neovim's Mason bin directory as well as the shell PATH; profile detect mirrors the new detector

Phase 30 — CI and dev loop, usability (0.10.0)

Order agreed with the maintainer; each item is its own branch and PR.

  • tests/run clears XDG_* so a local run behaves like CI
  • CI runs once per commit: push limited to main, topic branches tested through their pull request (it used to run for the push and again for the PR); tests/ci.bats guards the triggers
  • Documented minimum Neovim corrected from 0.10 to 0.11 (README + a test tying it to the APIs lua/ uses). Found by starting the real config on 0.10.4 / 0.11.0 / 0.11.7 / 0.12.0
  • CI: Neovim installed from a pinned version with a verified SHA-256 (scripts/ci-install-neovim), bats-core pinned by commit SHA (rules/ci.md)
  • tests/full-startup + CI job Startup (oldest supported Neovim and the Test job's version): the only end-to-end test of the real config; the suite alone passes on Neovim 0.10.4 where the config cannot start
  • Neovim version guard in init.lua (lua/minimum_version.lua): clear message and stop on Neovim < 0.11
  • :Cheat extension points: user directories (~/.config/nvim-cheatsheets, $NVIM_CHEATSHEET_DIRS) and a cheatsheets field a profile can declare; the shell and devops profiles ship a sheet each
  • Yazi: yazi.nvim loaded only when the yazi binary is present, <Leader>-, listed by doctor; no automatic install. A real yazi/neo-tree switch (like .nvim-ui) would come later, see Deferred
  • Docs / code consistency audit before 0.10.0: wrong ]t / [t claims, install all description, debugpy, shellcheck command, logging docs, zsh completion locals; the findings that are behaviour rather than docs (CLI paths ignoring XDG_*, daily log overwritten at each run) are the next item
  • ]t / [t navigation between TODO comments (todo-comments), replacing the unused tag-stack motions
  • Dry-run wording: "Removed" / "Linked" become "would remove" / "would link"; found on the way that --install-completion --dry-run really wrote the file (fixed), and a sweep test now guards every mutating command
  • XDG compliance of the CLI's own paths (log directory, config link, completions, fish rc file, nvm) and the zsh completion in ${XDG_DATA_HOME:-~/.local/share}/zsh/completions (the directory the maintainer's dotfiles put on fpath), with a warning about a leftover ~/.zfunc copy
  • The daily log is appended to, with a file-only Run: header line per run
  • install tmux refuses to write through a symlinked ~/.tmux.conf (dotfiles-managed) and says which line to add

Phase 31 — Reliable tests and tooling (0.11.0)

Order agreed with the maintainer on 2026-10-22; each item is its own branch and PR.

  • tests/run hands bats a minimal environment (env -i with a whitelist: PATH, HOME, TERM, TMPDIR, NVIM_HEADLESS_TESTS_SKIP, fixed locale) so a test cannot depend on the machine that runs it
  • CI pins up to date: actions/checkout v4.4.0 to v7.0.1 (Node 20 is deprecated), Neovim v0.12.5 to v0.12.6 with its SHA-256 checked against the downloaded archive; procedure in CONTRIBUTING.md "Updating the pinned Neovim", and a new "Updating a pinned action" section
  • Release guard rails: scripts/extract-changelog.sh (cited by rules/release.md, absent until now) and tests/release.bats, which checks that VERSION, the [X.Y.Z] CHANGELOG sections and the compare links agree; the CI lint step must cover every script under scripts/
  • npm-gated language servers with one shared mechanism (lua/lsp_requirements.lua, replacing the ad hoc jsonls gate and covering the web, php and python servers too): bash-language-server for shell, yaml-language-server and dockerfile-language-server for devops. Checked with the real servers: bashls with its own shellcheck off (nvim-lint keeps it), yamlls on schemastore and off the yaml.github buffers, dockerls leaving three rules to hadolint
  • Language servers installed when a profile is switched on at runtime (:NvimProfile), not only at the next startup; found while doing the previous item. Checked with the real Mason
  • nvim-config doctor lists the language servers left out because npm is missing (read from lua/lsp_requirements.lua)
  • Missing treesitter parsers installed on the fly, after a confirmation prompt (lua/treesitter_prompt.lua: Install / Not now / Never, "Never" kept in the state directory). Checked with the real nvim-treesitter, which also showed that a parser installed in the session that creates site was not found until runtimepath is assigned again

Phase 32 — Multiple profiles and the first run (target 0.11.1)

Order agreed with the maintainer on 2026-10-26; each item is its own branch and PR, and the Termux check comes last, on the commit that will be tagged.

  • .nvim-profile naming several profiles (web,php) is read as Neovim reads it by profile info, profile list and update dap-adapters (they failed on it), and profile set accepts a list and refuses an unknown name (a typo such as wbe was written silently and listed as active by Neovim)
  • The parsers installed at startup are found in the first session on a fresh machine (the site directory did not exist at startup, so Neovim does not search it until runtimepath is assigned again): the startup install now goes through lua/treesitter_install.lua, shared with the parser menu; checked with the real nvim-treesitter
  • Optional, to discuss: a CI job that installs the configuration on a clean runner and starts it (not a required check; network, duration, instability), since every defect of the last cycle came from a fresh-state condition
  • Refresh the pinned plugins of lazy-lock.json (:Lazy check first, then tests/full-startup): six plugins that follow their branch, 20 commits, none breaking; the three tag-pinned ones were already on their latest tag. Checked at the new commits with the real Mason, mason-lspconfig, nvim-lspconfig and nvim-treesitter
  • Lists read from a profile file (profile info, update dap-adapters) return only the quoted names, and update dap-adapters hands Neovim one +MasonInstall <package> argument per package: found while preparing the Termux check (stray }, lines), then a second defect behind it (the command installed nothing since it was written); checked with the real Mason
  • Check the release candidate on Termux (doctor, :NvimProfile, the parser menu), a declared target that has not been verified since 0.11.0 touched its branches

Deferred / Under Consideration

Items intentionally set aside — not yet prioritised or waiting for a relevant project context.

AI tooling

  • AI profile — implemented in Phase 16; both avante and codecompanion shipped; benchmark ongoing on real projects

  • copilot.lua (zbirenbaum) — inline AI completions via GitHub Copilot subscription; deferred — codeium.nvim covers the free inline completion use case → https://github.com/zbirenbaum/copilot.lua

  • Avante auth-mode picker — extend <Leader>aP provider picker with a second level to select the authentication mode per provider (OAuth Max, OAuth Pro, API key); REST providers (claude, claude-opus, gemini) support multiple auth_type values; ACP providers (claude-code, gemini-cli, codex) manage their own auth via CLI; requires building a two-step Telescope picker and a runtime Config.override({ providers = { … } }) call

MCP servers

Testing

  • neotest profile-driven adapters — neotest-jest (web, when Jest is preferred over Vitest), neotest-busted (Lua/busted projects); deferred until relevant project context

File explorer

  • yazi / neo-tree switch: let a setting (like .nvim-ui) make yazi the file explorer instead of neo-tree (open_for_directories = true, <Leader>n opening yazi). The coexisting integration shipped in Phase 30; this only matters if neo-tree stops being wanted → https://yazi-rs.github.io → https://github.com/mikavilpas/yazi.nvim

Profiles

  • lua profile: StyLua through conform. Its defaults (tabs, double quotes) differ from this repository's style (4 spaces, single quotes) and there is no stylua.toml here, so it only makes sense with require_cwd (format only where a stylua.toml exists) — which would leave the profile inert in this repo. lua_ls already covers diagnostics and luacheck needs luarocks. Revisit when a Lua project with a stylua.toml shows up (e.g. a WezTerm config)

  • go profile — gopls, parsers go gomod gosum gowork, Delve for DAP, formatter (gofumpt/goimports) and linter (golangci-lint) through conform/nvim-lint; detected by go.mod. Mason package names to confirm when implementing. Deferred until Go is actually used

  • java profile — jdtls, parser java, java-debug-adapter / java-test for DAP and tests, formatter; detected by pom.xml, build.gradle(.kts) or settings.gradle. jdtls needs a JDK and workspace handling that the other profiles don't, so it is the heavier of the two. Deferred until Java is actually used (a jenv install on the maintainer's PATH hints at it but doesn't confirm it)

Plugin management

  • mason-nvim-dap.nvim — declarative DAP adapter installation via Mason (alternative to current manual registry approach); evaluate if the current approach proves insufficient

CLI

  • uninstall command is missing counterparts for install tmux|claude|codex|gemini — scoped out of the 0.8.0 uninstall work (config|nvim|mise|deps|all only, matching the original backlog item) to keep that release tight; revisit if the asymmetry becomes a real pain point rather than fixing it speculatively

Config distribution selector

  • nvim-config install config --preset <name|url> — extend install config to support alternative Neovim distributions as presets; back up existing ~/.config/nvim before switching; supported presets to evaluate: