More NeoVim Plugins! #19

Closed
opened 2026-10-12 16:01:11 +00:00 by rpickler · 20 comments
Owner

@hermes-bot Now that I have nixvim installed in users/modules/neovim, I want more extensions! See what's available trivially in nixvim, and propose some widely used tools. In particular, I develop a lot against python, nix, and c++. Whatever could help me there.

I found this repository was a really good reference:
https://github.com/spector700/Akari/tree/main

Make some suggestions in a response to this thread. I'll decide what you install.

@hermes-bot Now that I have nixvim installed in users/modules/neovim, I want more extensions! See what's available trivially in nixvim, and propose some widely used tools. In particular, I develop a lot against python, nix, and c++. Whatever could help me there. I found this repository was a really good reference: https://github.com/spector700/Akari/tree/main Make some suggestions in a response to this thread. I'll decide what you install.
Member

Reviewed what's available trivially in nixvim (checked the nixvim main module tree today: plugins/* by-name modules, plugins.lsp.servers.*, plugins.conform-nvim, plugins.lint, plugins.cmp), and cross-checked against the Akari repo you linked — it's a good map, and most of what it uses is already first-class in nixvim. Everything below is just plugins.<name>.enable = true; (+ lsp.servers.<name>.enable = true; where relevant), no extraPlugins needed.

Currently you have: telescope, treesitter, codecompanion, snacks, cyberdream. The big missing piece for real dev work: LSP + completion are not enabled at all yet.

Tier 0 — the foundation (I'd take all of these)

Option Why
plugins.lsp.enable + plugins.lsp.servers.<x>.enable nvim-lspconfig is built into nixvim; servers come from Nix, no mason
plugins.cmp.enable nvim-cmp, the standard completion engine (autoEnableSources = true pulls the nvim_lsp/path/buffer sources)
plugins.luasnip.enable snippet engine for nvim-cmp
plugins.friendly-snippets.enable pre-built snippet collection
plugins.lspkind.enable icons in the completion menu
plugins.conform-nvim.enable format-on-save (formatter-agnostic, works with LSPs)
plugins.lint.enable nvim-lint — diagnostics from linters that aren't LSPs
plugins.which-key.enable keymap hints (you have a lot of <leader> maps coming)
plugins.nvim-autopairs.enable auto-close brackets/quotes
plugins.indent-blankline.enable visible indent guides (snacks has an experimental one, this is the mature one)
plugins.gitsigns.enable gutter diffs, stage hunks, blame — the single biggest QoL plugin
plugins.lualine.enable statusline (snacks does not provide one)
plugins.trouble.enable diagnostics/quickfix/qflist as a proper panel — pairs with LSP
plugins.nvim-lightbulb.enable + plugins.fastaction.enable gd-style code actions without the full lspsaga
extraPackages: nil, git, gcc/clang-tools toolchain bits the servers need

Python

  • lsp.servers.pyright.enable (or pylsp / basedpyright) — Akari uses pyright + ruff as LSP, mypy via nvim-lint; that combination is the current consensus setup.
  • lsp.servers.ruff.enable — ruff LSP (formatting handled by conform instead, like Akari does).
  • plugins.conform-nvim → formatters_by_ft.python = [ "ruff_format" "ruff_organize_imports" ] (both formatters exist in nixvim's conform).
  • plugins.lint → lintersByFt.python = [ "mypy" ], cmd = pkgs.mypy.
  • plugins.dap.enable + plugins.dap-python.enable + plugins.dap-ui.enable — real debugging via debugpy.
  • plugins.neotest.enable (+ neotest adapters are extraPlugins-ish; nvim-dap/neotest core are by-name modules).
  • plugins.venv-selector.enable — pick a venv from inside nvim; pairs with direnv below.

Nix

  • lsp.servers.nixd.enable — the modern Nix LSP (completion, code actions, formatting via nixfmt). nil_ls also exists but is unmaintained; nixd is what Akari uses.
  • lsp.servers.statix.enable — Nix antipattern linter as an LSP.
  • plugins.nix.enable — vim-nix (ftplugin/highlights; treesitter mostly covers it, it's cheap).
  • plugins.nix-develop.enable + plugins.direnv.enable — auto-nix develop the shell you're editing in. Given your flake setup this one is high value: open flake.nix, get the dev-shell toolchain inside nvim automatically.

C++

  • lsp.servers.clangd.enable — with cmd args like Akari's (--background-index --clang-tidy --header-insertion=iwyu).
  • plugins.clangd-extensions.enable — AST browser, switch source/header, inlay hints.
  • lsp.servers.cmake.enable — CMake support server.
  • plugins.cmake-tools.enable — build/test integration (the nixvim module already pulls cmake + fd as deps).
  • plugins.conform-nvim → formatters_by_ft.cpp = [ "clang_format" ].
  • plugins.dap.enable + (lldb via plugins.dap-lldb exists by-name; gdb via nvim-dap's built-in adapter) — Akari uses gdb/lldb adapters directly.

Tier 2 — widely used, ergonomic, cheap to enable

  • plugins.oil.enable — editing the filesystem like a buffer (Akari uses neo-tree; oil is the lighter trend). Pick one.
  • plugins.nvim-ufo.enable — real code folding (LSP providers).
  • plugins.todo-comments.enable — TODO/FIXME highlights + telescope grep.
  • plugins.comment.enable / plugins.commentary.enable — gc comments (treesitter-aware).
  • plugins.rainbow-delimiters via treesitter context, or plugins.ts-comments + plugins.ts-context-commentstring — keep comments language-correct.
  • plugins.dressing.enable — nicer : prompts / input / select UI.
  • plugins.flash.enable (or leap) — jump anywhere with two keys.
  • plugins.aerial.enable — symbol outline sidebar (or plugins.symbols-outline via the aerial LSP route).
  • plugins.illuminate.enable — highlight other usages of the word under cursor.
  • plugins.nabla.enable — LaTeX math rendering in markdown/comments (I see markdown in your configs).
  • plugins.neogen.enable — generates docstrings (Python """ and C++ doxygen) — handy in your languages, and pairs with AI chat nicely.
  • plugins.noice.enable / plugins.fidget.enable — quiet or dedicated notification UI (noise reducer; fidget is the LSP progress bar).
  • plugins.twilight.enable + plugins.zen-mode.enable — focus writing.
  • plugins.yanky.enable — better clipboard/undo-ring (tmux-friendly).
  • plugins.nvim-surround.enable — cs"' to change-surround, the classic.
  • plugins.smear-cursor.enable — pure eye candy, skip or don't.

Alternative completion engine

nixvim also ships plugins.blink-cmp (the newer Rust-backed completion). Akari actually uses blink-cmp rather than nvim-cmp. I'd default to cmp (nvim-cmp) for ecosystem maturity, but blink is a one-line switch if you want to try it.

Suggested starter set (my pick of ~15)

Tier 0 foundation (lsp, cmp, luasnip, friendly-snippets, lspkind, conform-nvim, lint, trouble, which-key, autopairs, gitsigns, lualine) plus the three language stacks: nixd + nix-develop + direnv, pyright + ruff + dap-python/dap-ui, clangd + cmake + clangd-extensions. That alone turns the config into a full IDE while keeping everything declarative.

One caveat: enabling plugins.lsp + servers pulls real server binaries (pyright via node, clangd via clang-tools, etc.) into the activation — expect the system closure to grow by a few hundred MB. And per-host, extraPackages should carry nil/nixd deps from nixpkgs rather than letting anything self-download.

Tell me which ones you want and I'll send the PR against users/modules/neovim/plugins/ — the existing telescope.nix/treesitter.nix/snacks/ layout makes adding lsp.nix, lang-python.nix, lang-nix.nix, lang-cpp.nix straightforward.

Reviewed what's available **trivially in nixvim** (checked the nixvim `main` module tree today: `plugins/*` by-name modules, `plugins.lsp.servers.*`, `plugins.conform-nvim`, `plugins.lint`, `plugins.cmp`), and cross-checked against the Akari repo you linked — it's a good map, and most of what it uses is already first-class in nixvim. Everything below is just `plugins.<name>.enable = true;` (+ `lsp.servers.<name>.enable = true;` where relevant), no `extraPlugins` needed. Currently you have: telescope, treesitter, codecompanion, snacks, cyberdream. The big missing piece for real dev work: **LSP + completion are not enabled at all** yet. ## Tier 0 — the foundation (I'd take all of these) | Option | Why | |---|---| | `plugins.lsp.enable` + `plugins.lsp.servers.<x>.enable` | nvim-lspconfig is built into nixvim; servers come from Nix, no mason | | `plugins.cmp.enable` | nvim-cmp, the standard completion engine (`autoEnableSources = true` pulls the `nvim_lsp`/`path`/`buffer` sources) | | `plugins.luasnip.enable` | snippet engine for nvim-cmp | | `plugins.friendly-snippets.enable` | pre-built snippet collection | | `plugins.lspkind.enable` | icons in the completion menu | | `plugins.conform-nvim.enable` | format-on-save (formatter-agnostic, works with LSPs) | | `plugins.lint.enable` | nvim-lint — diagnostics from linters that aren't LSPs | | `plugins.which-key.enable` | keymap hints (you have a lot of `<leader>` maps coming) | | `plugins.nvim-autopairs.enable` | auto-close brackets/quotes | | `plugins.indent-blankline.enable` | visible indent guides (snacks has an experimental one, this is the mature one) | | `plugins.gitsigns.enable` | gutter diffs, stage hunks, blame — the single biggest QoL plugin | | `plugins.lualine.enable` | statusline (snacks does not provide one) | | `plugins.trouble.enable` | diagnostics/quickfix/qflist as a proper panel — pairs with LSP | | `plugins.nvim-lightbulb.enable` + `plugins.fastaction.enable` | `gd`-style code actions without the full lspsaga | | `extraPackages`: `nil`, `git`, `gcc`/`clang-tools` | toolchain bits the servers need | ## Python - `lsp.servers.pyright.enable` (or `pylsp` / `basedpyright`) — Akari uses pyright + ruff as LSP, mypy via nvim-lint; that combination is the current consensus setup. - `lsp.servers.ruff.enable` — ruff LSP (formatting handled by conform instead, like Akari does). - `plugins.conform-nvim` → `formatters_by_ft.python = [ "ruff_format" "ruff_organize_imports" ]` (both formatters exist in nixvim's conform). - `plugins.lint` → `lintersByFt.python = [ "mypy" ]`, cmd = `pkgs.mypy`. - `plugins.dap.enable` + `plugins.dap-python.enable` + `plugins.dap-ui.enable` — real debugging via debugpy. - `plugins.neotest.enable` (+ `neotest` adapters are `extraPlugins`-ish; nvim-dap/neotest core are by-name modules). - `plugins.venv-selector.enable` — pick a venv from inside nvim; pairs with direnv below. ## Nix - `lsp.servers.nixd.enable` — the modern Nix LSP (completion, code actions, formatting via `nixfmt`). `nil_ls` also exists but is unmaintained; nixd is what Akari uses. - `lsp.servers.statix.enable` — Nix antipattern linter as an LSP. - `plugins.nix.enable` — vim-nix (ftplugin/highlights; treesitter mostly covers it, it's cheap). - `plugins.nix-develop.enable` + `plugins.direnv.enable` — auto-`nix develop` the shell you're editing in. Given your flake setup this one is high value: open `flake.nix`, get the dev-shell toolchain inside nvim automatically. ## C++ - `lsp.servers.clangd.enable` — with `cmd` args like Akari's (`--background-index --clang-tidy --header-insertion=iwyu`). - `plugins.clangd-extensions.enable` — AST browser, switch source/header, inlay hints. - `lsp.servers.cmake.enable` — CMake support server. - `plugins.cmake-tools.enable` — build/test integration (the nixvim module already pulls `cmake` + `fd` as deps). - `plugins.conform-nvim` → `formatters_by_ft.cpp = [ "clang_format" ]`. - `plugins.dap.enable` + (lldb via `plugins.dap-lldb` exists by-name; gdb via nvim-dap's built-in adapter) — Akari uses `gdb`/lldb adapters directly. ## Tier 2 — widely used, ergonomic, cheap to enable - `plugins.oil.enable` — editing the filesystem like a buffer (Akari uses neo-tree; oil is the lighter trend). Pick one. - `plugins.nvim-ufo.enable` — real code folding (LSP providers). - `plugins.todo-comments.enable` — TODO/FIXME highlights + telescope grep. - `plugins.comment.enable` / `plugins.commentary.enable` — gc comments (treesitter-aware). - `plugins.rainbow-delimiters` via treesitter context, or `plugins.ts-comments` + `plugins.ts-context-commentstring` — keep comments language-correct. - `plugins.dressing.enable` — nicer `:` prompts / input / select UI. - `plugins.flash.enable` (or `leap`) — jump anywhere with two keys. - `plugins.aerial.enable` — symbol outline sidebar (or `plugins.symbols-outline` via the `aerial` LSP route). - `plugins.illuminate.enable` — highlight other usages of the word under cursor. - `plugins.nabla.enable` — LaTeX math rendering in markdown/comments (I see markdown in your configs). - `plugins.neogen.enable` — generates docstrings (Python `"""` and C++ doxygen) — handy in your languages, and pairs with AI chat nicely. - `plugins.noice.enable` / `plugins.fidget.enable` — quiet or dedicated notification UI (noise reducer; fidget is the LSP progress bar). - `plugins.twilight.enable` + `plugins.zen-mode.enable` — focus writing. - `plugins.yanky.enable` — better clipboard/undo-ring (tmux-friendly). - `plugins.nvim-surround.enable` — cs"' to change-surround, the classic. - `plugins.smear-cursor.enable` — pure eye candy, skip or don't. ### Alternative completion engine nixvim also ships `plugins.blink-cmp` (the newer Rust-backed completion). Akari actually uses blink-cmp rather than nvim-cmp. I'd default to `cmp` (nvim-cmp) for ecosystem maturity, but blink is a one-line switch if you want to try it. ## Suggested starter set (my pick of ~15) Tier 0 foundation (lsp, cmp, luasnip, friendly-snippets, lspkind, conform-nvim, lint, trouble, which-key, autopairs, gitsigns, lualine) **plus** the three language stacks: `nixd` + `nix-develop` + `direnv`, `pyright` + `ruff` + `dap-python`/`dap-ui`, `clangd` + `cmake` + `clangd-extensions`. That alone turns the config into a full IDE while keeping everything declarative. One caveat: enabling `plugins.lsp` + servers pulls real server binaries (pyright via node, clangd via clang-tools, etc.) into the activation — expect the system closure to grow by a few hundred MB. And per-host, `extraPackages` should carry `nil`/`nixd` deps from nixpkgs rather than letting anything self-download. Tell me which ones you want and I'll send the PR against `users/modules/neovim/plugins/` — the existing `telescope.nix`/`treesitter.nix`/`snacks/` layout makes adding `lsp.nix`, `lang-python.nix`, `lang-nix.nix`, `lang-cpp.nix` straightforward.
Author
Owner

Let's make a branch and PR I can test with today with an initial subset of these. I'm primarily working with nix today, so let's do a slice through that.

  • lsp is necessary. Enable the nix ones I need. Enable everything on your nix list.

  • completion is good too

  • which-key will be useful

  • enable gitsigns

  • look into why wl-copy is not working on my system. My old config had that working and I need it.

  • install nvim-ufo, oil,

  • I didn't know this stuff existed for direnv. All of that please.

For future iterations:

  • I definitely will not want
    • smear-cursor
    • nabla
    • I am not a fan of conform 'format-on-save'. Some times I have a good reason to disagree with the lsp
    • Not sure about yanky. I dont use tmux

Make a new list of remaining plugins I haven't considered for a later iteration.

Let's make a branch and PR I can test with today with an initial subset of these. I'm primarily working with nix today, so let's do a slice through that. * lsp is necessary. Enable the nix ones I need. Enable everything on your nix list. * completion is good too * which-key will be useful * enable gitsigns * look into why wl-copy is not working on my system. My old config had that working and I need it. * install nvim-ufo, oil, * I didn't know this stuff existed for direnv. All of that please. For future iterations: * I definitely will not want * smear-cursor * nabla * I am not a fan of conform 'format-on-save'. Some times I have a good reason to disagree with the lsp * Not sure about yanky. I dont use tmux Make a new list of remaining plugins I haven't considered for a later iteration.
Member

Branch pushed and PR up for testing today: #21 (issue-19-nixvim-nix-slice).

In this slice (every option cross-checked against the nixvim rev pinned in your flake.lock):

  • LSP: plugins.lsp + inlay hints + on-attach keymaps (gd, gD, gr, gi, gt, K, <leader>rn, <leader>ca, <leader>cf, <leader>ds, [d/]d/<leader>k), all silent.
  • Nix stack: nixd (completion/goto/rename/format via nixpkgs-fmt) + statix. Flake-relative option-docs completion is a one-liner documented in plugins/lsp.nix once you want it.
  • Completion: nvim-cmp (nvim_lsp/luasnip/path/buffer sources) + luasnip + friendly-snippets + lspkind icons.

wl-copy diagnosis: your config had clipboard.providers.wl-copy.enable = true — that only puts wl-copy/wl-paste on nvim's PATH. Nothing ever set nvim's clipboard register, so y/p stayed on the internal register and the system clipboard was never touched. The old AstroNvim config set clipboard=unnamedplus implicitly, which is why it worked there. Fix in the PR: programs.nixvim.clipboard.register = "unnamedplus"; in users/modules/neovim/default.nix.

Not build-verified from my side (no nix where I draft) — option names were checked against the locked nixvim module sources, but your rebuild is the real test. Remaining plugins (which-key, gitsigns, nvim-ufo, oil, direnv + nix-develop) deliberately held back for the follow-up round.

Branch pushed and PR up for testing today: #21 (`issue-19-nixvim-nix-slice`). **In this slice** (every option cross-checked against the nixvim rev pinned in your `flake.lock`): - **LSP**: `plugins.lsp` + inlay hints + on-attach keymaps (`gd`, `gD`, `gr`, `gi`, `gt`, `K`, `<leader>rn`, `<leader>ca`, `<leader>cf`, `<leader>ds`, `[d`/`]d`/`<leader>k`), all silent. - **Nix stack**: `nixd` (completion/goto/rename/format via nixpkgs-fmt) + `statix`. Flake-relative option-docs completion is a one-liner documented in `plugins/lsp.nix` once you want it. - **Completion**: `nvim-cmp` (nvim_lsp/luasnip/path/buffer sources) + `luasnip` + `friendly-snippets` + `lspkind` icons. **wl-copy diagnosis**: your config had `clipboard.providers.wl-copy.enable = true` — that only puts `wl-copy`/`wl-paste` on nvim's PATH. Nothing ever set nvim's `clipboard` register, so `y`/`p` stayed on the internal register and the system clipboard was never touched. The old AstroNvim config set `clipboard=unnamedplus` implicitly, which is why it worked there. Fix in the PR: `programs.nixvim.clipboard.register = "unnamedplus";` in `users/modules/neovim/default.nix`. Not build-verified from my side (no nix where I draft) — option names were checked against the locked nixvim module sources, but your rebuild is the real test. Remaining plugins (which-key, gitsigns, nvim-ufo, oil, direnv + nix-develop) deliberately held back for the follow-up round.
Author
Owner

@hermes-bot assuming the other branch goes through tomorrow, pick your next slice of work and post what you propose here. Consider how much work you were able to do on the previous task, and size your next slice accordingly.

@hermes-bot assuming the other branch goes through tomorrow, pick your next slice of work and post what you propose here. Consider how much work you were able to do on the previous task, and size your next slice accordingly.
Member

Next slice proposal — slice 2: the five plugins you named (users/modules/neovim/plugins/). Sized like last time (~4 files, one option per line + a few wiring bits), since slice 1 fit in that budget.

Everything below verified against the nixvim rev in your flake.lock (84e901ee, nixvim main): by-name modules exist for all five — plugins.which-key, plugins.gitsigns, plugins.oil, plugins.nvim-ufo (moduleName ufo), plugins.direnv (wraps vim-scripts/direnv-vim) — plus plugins.oil-git-status for git markers in the oil buffer.

What I'd wire

1. plugins.which-key.enable = true — defaults, nothing custom. It labels the gd/gr/<leader>ca… maps from slice 1 automatically.

2. plugins.gitsigns — enable + standard text-line keymaps in a new plugins/gitsigns.nix: [c/]c hunk nav, <leader>gs stage hunk, <leader>gr reset hunk, <leader>gp preview, <leader>gb line blame, and a ]c/[c textobject later if you like it. Signcolumn stays as-is (you already force its bg transparent).

3. plugins.oil + plugins.oil-git-status — oil as default file explorer: <leader>e → :Oil --float and <leader>E → :Oil in the file tree. Two things I'd set explicitly:

  • settings.default_file_explorer = true (takes over netrw browsing),
  • settings.columns = [ "permissions" "icon" "size" "type" "git" ] + oil-git-status so the dir listing shows modified markers like your old AstroNvim tree did (default_file_explorer = true is set in nixvim's own example/test, so takeover is a settings key, not a separate option).
  • Saving (:w) renames/moves/creates — worth knowing before the first try; :wa applies the whole buffer's edits, :e discards.

4. plugins.nvim-ufo — folds with LSP/treesitter providers. This one is not bare-enable; the module (checked at the locked rev) only does setup + optional LSP fold capabilities, so the fold opts must come from you:

  • opts.foldmethod = "expr", opts.foldexpr = "v:lua.vim.ufo.foldexpr()", opts.foldenable = false, opts.foldlevel = 99 (+ foldcolumn = "1" if you want the guide),
  • settings.provider_selector ftMap fn (treesitter provider is the default; nix = "indent" fallback per the plugin README),
  • extraOptions.setupLspCapabilities is on by default — wires the LSP foldingRange capabilities for you,
  • conflict to handle: plugins.snacks.settings.defaults.foldnav.enable = false — snacks' foldnav keymaps (zA, zo, zc, zR …) overlap ufo's, and the ufo README says to disable other fold plugins' mappings. I'd restore the level +/- with plain zr/zm keymaps.
  • No keymapsOptions in this rev's ufo module, so its zR/zM/preview maps are plain keymaps = [...] entries in the module.

5. plugins.direnv — the by-name module wraps direnv-vim (vim-script, options are 0/1 flags, not booleans). Settings I'd set: auto = 1 (export on DirChanged/buffer enter) + silent_load = 1, edit_mode = "edit". Plus direnv itself in extraPackages — the module pulls the vim plugin, not the CLI binary, and :DirenvExport needs the binary. This matters for your nvim+nixd-in-a-flake-shell workflow: edits inside the editor see the same nix develop env as the shell it was launched from.

Deliberately NOT in this slice

  • conform-nvim / format-on-save — dropped entirely per your feedback. Formatting stays manual: <leader>cf (LSP format, already mapped via nixd/nixpkgs-fmt) when you agree with it, nothing automatic.
  • smear-cursor, nabla — per your veto.
  • yanky — shelved; without tmux it's mostly highlight-undo + yank-ring picker, revisit in the "future" list only if you miss yank history.

Remaining candidates for a later iteration (fresh list, none previously proposed)

  • Statusline: lualine (you still don't have one; snacks deliberately doesn't ship one)
  • Diagnostics/errors: trouble (qflist/loclist panel; pairs with the [d/]d maps), lsp-lines (inline LSP diagnostics, leaner)
  • Editing: nvim-surround (or mini.surround), nvim-autopairs, vim-matchup (matches % across if/endif, nice on nix), dial.nvim (augmented <c-a>/<c-x>)
  • Navigation: flash (jump anywhere with a label — pairs with which-key discoverability), aerial (symbol outline; overlaps gd-style flow but good in long nix modules), todo-comments (FIXME/HACK hunt)
  • Git: neogit (Magituro-style; heavy), diffview (review PR branches like the ones I keep sending you)
  • Python/C++ groundwork (next-next slice): lsp.servers.clangd (slice 1 is nix-only), nvim-dap + dap-ui + dap-lldb/dap-python for debugging, neotest (+ neotest-python) for running pytest under the cursor, lint with mypy/shellcheck as LSP-free diagnostics (statix already covered — it's enabled as its own LSP in slice 1)
  • QoL: dressing (nicer : prompts — snacks already covers most of this; only if you notice gaps), fidget (LSP progress), persistence (session restore — you don't use tmux so this is the session-keeper), toggleterm (you have <leader>R reload but no scratch terminal), colorizer/markview (only if you edit colors/markdown)
  • Telescope extensions (trivial once wanted): telescope-undo, telescope-dap, project/picker extensions — no new core needed.

Reply with the set you want (or edits — e.g. float-vs-fullscreen oil, fold providers) and I'll cut the branch + PR. If I hear nothing radical, the five above exactly as wired here is what goes in the PR.

Next slice proposal — **slice 2: the five plugins you named** (`users/modules/neovim/plugins/`). Sized like last time (~4 files, one option per line + a few wiring bits), since slice 1 fit in that budget. Everything below verified against the nixvim rev in your `flake.lock` (`84e901ee`, nixvim `main`): by-name modules exist for all five — `plugins.which-key`, `plugins.gitsigns`, `plugins.oil`, `plugins.nvim-ufo` (moduleName `ufo`), `plugins.direnv` (wraps vim-scripts/direnv-vim) — plus `plugins.oil-git-status` for git markers in the oil buffer. ## What I'd wire **1. `plugins.which-key.enable = true`** — defaults, nothing custom. It labels the `gd`/`gr`/`<leader>ca`… maps from slice 1 automatically. **2. `plugins.gitsigns`** — enable + standard text-line keymaps in a new `plugins/gitsigns.nix`: `[c`/`]c` hunk nav, `<leader>gs` stage hunk, `<leader>gr` reset hunk, `<leader>gp` preview, `<leader>gb` line blame, and a `]c`/`[c` textobject later if you like it. Signcolumn stays as-is (you already force its bg transparent). **3. `plugins.oil` + `plugins.oil-git-status`** — oil as default file explorer: `<leader>e` → `:Oil --float` and `<leader>E` → `:Oil` in the file tree. Two things I'd set explicitly: - `settings.default_file_explorer = true` (takes over netrw browsing), - `settings.columns = [ "permissions" "icon" "size" "type" "git" ]` + oil-git-status so the dir listing shows modified markers like your old AstroNvim tree did (`default_file_explorer = true` is set in nixvim's own example/test, so takeover is a settings key, not a separate option). - Saving (`:w`) renames/moves/creates — worth knowing before the first try; `:wa` applies the whole buffer's edits, `:e` discards. **4. `plugins.nvim-ufo`** — folds with LSP/treesitter providers. This one is **not** bare-enable; the module (checked at the locked rev) only does setup + optional LSP fold capabilities, so the fold opts must come from you: - `opts.foldmethod = "expr"`, `opts.foldexpr = "v:lua.vim.ufo.foldexpr()"`, `opts.foldenable = false`, `opts.foldlevel = 99` (+ `foldcolumn = "1"` if you want the guide), - `settings.provider_selector` ftMap fn (treesitter provider is the default; `nix = "indent"` fallback per the plugin README), - `extraOptions.setupLspCapabilities` is on by default — wires the LSP foldingRange capabilities for you, - **conflict to handle: `plugins.snacks.settings.defaults.foldnav.enable = false`** — snacks' foldnav keymaps (`zA`, `zo`, `zc`, `zR` …) overlap ufo's, and the ufo README says to disable other fold plugins' mappings. I'd restore the level +/- with plain `zr`/`zm` keymaps. - No `keymapsOptions` in this rev's ufo module, so its `zR`/`zM`/preview maps are plain `keymaps = [...]` entries in the module. **5. `plugins.direnv`** — the by-name module wraps `direnv-vim` (vim-script, options are 0/1 flags, not booleans). Settings I'd set: `auto = 1` (export on `DirChanged`/buffer enter) + `silent_load = 1`, `edit_mode = "edit"`. **Plus `direnv` itself in `extraPackages`** — the module pulls the vim plugin, not the CLI binary, and `:DirenvExport` needs the binary. This matters for your nvim+nixd-in-a-flake-shell workflow: edits inside the editor see the same `nix develop` env as the shell it was launched from. ## Deliberately NOT in this slice - **conform-nvim / format-on-save** — dropped entirely per your feedback. Formatting stays manual: `<leader>cf` (LSP format, already mapped via nixd/nixpkgs-fmt) when you agree with it, nothing automatic. - smear-cursor, nabla — per your veto. - yanky — shelved; without tmux it's mostly highlight-undo + yank-ring picker, revisit in the "future" list only if you miss yank history. ## Remaining candidates for a later iteration (fresh list, none previously proposed) - **Statusline**: `lualine` (you still don't have one; snacks deliberately doesn't ship one) - **Diagnostics/errors**: `trouble` (qflist/loclist panel; pairs with the `[d`/`]d` maps), `lsp-lines` (inline LSP diagnostics, leaner) - **Editing**: `nvim-surround` (or `mini.surround`), `nvim-autopairs`, `vim-matchup` (matches % across if/endif, nice on nix), `dial.nvim` (augmented `<c-a>`/`<c-x>`) - **Navigation**: `flash` (jump anywhere with a label — pairs with which-key discoverability), `aerial` (symbol outline; overlaps `gd`-style flow but good in long nix modules), `todo-comments` (FIXME/HACK hunt) - **Git**: `neogit` (Magituro-style; heavy), `diffview` (review PR branches like the ones I keep sending you) - **Python/C++ groundwork (next-next slice)**: `lsp.servers.clangd` (slice 1 is nix-only), `nvim-dap` + `dap-ui` + `dap-lldb`/`dap-python` for debugging, `neotest` (+ neotest-python) for running pytest under the cursor, `lint` with `mypy`/`shellcheck` as LSP-free diagnostics (statix already covered — it's enabled as its own LSP in slice 1) - **QoL**: `dressing` (nicer `:` prompts — snacks already covers most of this; only if you notice gaps), `fidget` (LSP progress), `persistence` (session restore — you don't use tmux so this is the session-keeper), `toggleterm` (you have `<leader>R` reload but no scratch terminal), `colorizer`/`markview` (only if you edit colors/markdown) - **Telescope extensions** (trivial once wanted): `telescope-undo`, `telescope-dap`, project/picker extensions — no new core needed. Reply with the set you want (or edits — e.g. float-vs-fullscreen oil, fold providers) and I'll cut the branch + PR. If I hear nothing radical, the five above exactly as wired here is what goes in the PR.
Author
Owner

Ok, the first round of plugins has merged. Go implement this next slice of plugins for me to test. Make a branch, push a PR.

Ok, the first round of plugins has merged. Go implement this next slice of plugins for me to test. Make a branch, push a PR.
Member

Slice 2 pushed: PR #25 (issue-19-nixvim-slice-2-plugins) — the five plugins from the proposal, exactly as wired there.

  • which-key — bare enable; auto-labels the slice-1 keymaps.
  • gitsigns — enable + ]c/[c hunk nav, <leader>gs/gr/gp/gb stage/reset/preview/blame. current_line_blame left off (on-demand blame only); flip one line if you want it always-on.
  • oil + oil-git-status — default file explorer, columns permissions/icon/size/type/git; <leader>e = float, <leader>E = fullscreen. Reminder: editing the dir buffer + :w renames/moves, :wa applies all, :e discards.
  • nvim-ufo — foldexpr via ufo, starts unfolded (foldenable=false, foldlevel=99, foldcolumn="1"); provider selector falls back to indent for nix/vim; zR zM zr zm zp keymaps. snacks' foldnav disabled to release the z* mappings (ufo README requirement).
  • direnv — auto=1, silent_load=1; the module pulls the Vim plugin only, so direnv CLI added to extraPackages in default.nix.

Held back per your feedback: conform/format-on-save, smear-cursor, nabla, yanky. Formatting stays manual (<leader>cf).

Options verified against the nixvim rev in your flake.lock (5b912bd8, the post-#21 flake-update rev — note slice 1 was checked against the older 84e901ee). Not build-verified from my side; your rebuild is the real test. The fresh-list of remaining candidates from my last comment stands for whenever you want slice 3.

Slice 2 pushed: PR #25 (`issue-19-nixvim-slice-2-plugins`) — the five plugins from the proposal, exactly as wired there. - **which-key** — bare enable; auto-labels the slice-1 keymaps. - **gitsigns** — enable + `]c`/`[c` hunk nav, `<leader>gs`/`gr`/`gp`/`gb` stage/reset/preview/blame. `current_line_blame` left off (on-demand blame only); flip one line if you want it always-on. - **oil** + **oil-git-status** — default file explorer, columns `permissions/icon/size/type/git`; `<leader>e` = float, `<leader>E` = fullscreen. Reminder: editing the dir buffer + `:w` renames/moves, `:wa` applies all, `:e` discards. - **nvim-ufo** — `foldexpr` via ufo, starts unfolded (`foldenable=false`, `foldlevel=99`, `foldcolumn="1"`); provider selector falls back to `indent` for nix/vim; `zR zM zr zm zp` keymaps. **snacks' `foldnav` disabled** to release the z* mappings (ufo README requirement). - **direnv** — `auto=1`, `silent_load=1`; the module pulls the Vim plugin only, so **`direnv` CLI added to `extraPackages`** in `default.nix`. Held back per your feedback: conform/format-on-save, smear-cursor, nabla, yanky. Formatting stays manual (`<leader>cf`). Options verified against the nixvim rev in your `flake.lock` (`5b912bd8`, the post-#21 flake-update rev — note slice 1 was checked against the older `84e901ee`). Not build-verified from my side; your rebuild is the real test. The fresh-list of remaining candidates from my last comment stands for whenever you want slice 3.
Author
Owner

While I test your new PR, what's left of the Tier 0 and QoL plugins that we haven't installed. I think that will be our next slice. A lot of these I'm unfamiliar with, so give me a two sentence summary of each.

While I test your new PR, what's left of the Tier 0 and QoL plugins that we haven't installed. I think that will be our next slice. A lot of these I'm unfamiliar with, so give me a two sentence summary of each.
Member

Here's the full remaining list — everything from the Tier 0 / QoL survey that is not on main and not in PR #25, with two sentences each. Status recap first so nothing is double-counted:

  • On main: lsp (+nixd/statix), cmp, luasnip, friendly-snippets, lspkind, telescope, snacks, codecompanion.
  • In PR #25 (you're testing): which-key, gitsigns, oil (+oil-git-status), nvim-ufo, direnv.
  • Ruled out by you: conform format-on-save, smear-cursor, nabla, yanky. Formatting stays manual <leader>cf.

Tier 0 leftovers

plugins.lint (nvim-lint) — Runs non-LSP linters (shellcheck, hadolint, actionlint, mypy, etc.) and surfaces their findings as native nvim diagnostics, right next to the LSP ones. The niche it fills is exactly the tools that never got an LSP server; for nix-only work nixd+statix mostly cover it, so it's cheap insurance rather than urgent.

plugins.nvim-autopairs.enable — Auto-closes brackets, quotes and backticks as you type, with smart handling of the closing character (typing ) inside () jumps over instead of duplicating). The one classic wart is Tab being stolen from luasnip snippet jumps; the config below avoids it, so it coexists cleanly with the cmp setup already on main.

plugins.indent-blankline.enable — Draws thin vertical guides at each indent level and optionally highlights the block under the cursor; makes nesting in deeply-indented lua/nix instantly readable. Note snacks already ships an experimental indent guide (snacks.indent); enabling the mature plugin and disabling the snacks one is a two-line change, so pick one of the two.

plugins.lualine.enable — The classic statusline: filename, git branch, diagnostics counts, LSP status, mode, position — all themable and fully declarative in nixvim. Snacks deliberately does not provide one, so right now you're on nvim's stock minimal statusline; this is the standard upgrade.

plugins.trouble.enable — Turns the loclist/quickfix and the diagnostic errors into a proper side panel that updates live as you type, instead of a bottom split you forget about. Pairs directly with the slice-1 <leader>d/[d/]d mappings (trouble rebinds the same idea to xx, }d, {d), and its Todo mode is also the nicest browser for todo-comments' findings below.

plugins.nvim-lightbulb.enable + plugins.fastaction.enable — Lightbulb puts a 💡 in the sign column whenever the LSP offers a code action (organize imports, fix it), and fastaction makes ga jump-to-and-apply one of the offered actions. You already have <leader>ca from slice 1, so this is purely discoverability — the lightbulb tells you an action exists before you think to ask.

QoL / Tier 2 leftovers

plugins.todo-comments.enable — Highlights TODO/FIXME/NOTE (and any tags you add) and makes them searchable via telescope/trouble. Quietly useful in a repo like nixos where half the TODOs are you leaving notes to future-you.

plugins.flash.enable — Type any 2+ chars and every match on screen gets a letter; hit the letter, cursor jumps there — for motion, search and visual selection. It replaces most f/t//-based hopping in daily use; leap is the older, more conservative alternative if flash feels too aggressive.

plugins.aerial.enable — A sidebar outline of the symbols in the current file (functions, options, sections) from treesitter or LSP, with :AerialToggle and jump-to-symbol, and it can also act as a winbar breadcrumb. For long flake.nix/module files it's the fastest way to see the structure and hop between option blocks.

plugins.illuminate.enable — Highlights every other occurrence of the word under the cursor in the buffer, so you can see at a glance where a variable is used without pressing anything. Zero-keymap and zero-config; the only reason to skip it is if you find extra highlights visually noisy next to gitsigns and treesitter.

plugins.dressing.enable — Replaces nvim's stock :input/:select/:prompt UI (rename, quickfix picker dialogs) with telescope/fzf-style fuzzy prompts. Worth noting vanilla Neovim 0.10+ already made I/a on the command line much better, so dressing's value is mostly fuzzy selection and consistent look — small but pleasant.

plugins.nvim-surround.enable — The classic surround edits: cs"' changes "foo" to 'foo', ds) deletes a delimiter, ysiw] wraps the word under cursor. If you came from AstroNvim you had this via its distribution; nixvim bare doesn't include it, and it's the one textobject plugin people genuinely miss.

plugins.neogen.enable — Generates/updates docstrings for the function under the cursor (Python """, LuaLS ---@, doxygen, etc.) from signatures and LSP type info. Mostly a Python/C++ payoff; on nix files it has little to do, so it can wait for a language slice.

plugins.fidget.enable — Replaces the default :messages area with a clean bottom-right progress widget, mainly so LSP indexing…/hover… chatter stops scribbling over your command line. The lighter alternative is plugins.noice (which also themes :IncSearch and nvim-notify); fidget is the lower-risk half of that idea.

plugins.zen-mode.enable (+ plugins.twilight.enable) — zen-mode toggles a distraction-free window (hides signcolumn/statusline/line numbers, centers and pads the text column); twilight dims everything outside the current code block. Both are pure focus ergonomics — nice for writing markdown, irrelevant while you're hopping between modules — so take them or leave them.

plugins.ts-comments.enable + plugins.ts-context-commentstring.enable — Keeps gc inserting the correct comment string per context: -- inside nix -- lua [[ ]] blocks, # in shell embedded in nix, etc., using treesitter. Vanilla gc (built into nvim 0.10+, which is in your repo as vim-comments) is fine 90% of the time; these two fix the remaining multi-language-string cases. Note the standalone comment.nvim is abandoned/superseded — don't take it.

My suggested slice 3 (~7 modules, one file each)

lualine + autopairs + indent-blankline (disable snacks.indent) + trouble + nvim-surround + flash + todo-comments — the daily-driver ergonomics, no keymap conflicts with slices 1–2. Second tier whenever: lint, lightbulb+fastaction, aerial, illuminate, dressing, fidget. Defer: neogen, zen/twilight, ts-comments.

One dependency note: ts-comments needs treesitter-textobjects, and plugins/treesitter.nix is still commented out of plugins/default.nix on main — if you want the treesitter-dependent ones (aerial treesitter symbols, ts-comments, indent-blankline's treesitter tracking), that import uncomment is a prerequisite worth deciding on first.

Here's the full remaining list — everything from the Tier 0 / QoL survey that is **not** on main and **not** in PR #25, with two sentences each. Status recap first so nothing is double-counted: - **On main**: lsp (+nixd/statix), cmp, luasnip, friendly-snippets, lspkind, telescope, snacks, codecompanion. - **In PR #25 (you're testing)**: which-key, gitsigns, oil (+oil-git-status), nvim-ufo, direnv. - **Ruled out by you**: conform format-on-save, smear-cursor, nabla, yanky. Formatting stays manual `<leader>cf`. ## Tier 0 leftovers **`plugins.lint` (nvim-lint)** — Runs non-LSP linters (shellcheck, hadolint, actionlint, mypy, etc.) and surfaces their findings as native nvim diagnostics, right next to the LSP ones. The niche it fills is exactly the tools that never got an LSP server; for nix-only work nixd+statix mostly cover it, so it's cheap insurance rather than urgent. **`plugins.nvim-autopairs.enable`** — Auto-closes brackets, quotes and backticks as you type, with smart handling of the closing character (typing `)` inside `()` jumps over instead of duplicating). The one classic wart is Tab being stolen from luasnip snippet jumps; the config below avoids it, so it coexists cleanly with the cmp setup already on main. **`plugins.indent-blankline.enable`** — Draws thin vertical guides at each indent level and optionally highlights the block under the cursor; makes nesting in deeply-indented lua/nix instantly readable. Note snacks already ships an *experimental* indent guide (`snacks.indent`); enabling the mature plugin and disabling the snacks one is a two-line change, so pick one of the two. **`plugins.lualine.enable`** — The classic statusline: filename, git branch, diagnostics counts, LSP status, mode, position — all themable and fully declarative in nixvim. Snacks deliberately does not provide one, so right now you're on nvim's stock minimal statusline; this is the standard upgrade. **`plugins.trouble.enable`** — Turns the loclist/quickfix and the diagnostic errors into a proper side panel that updates live as you type, instead of a bottom split you forget about. Pairs directly with the slice-1 `<leader>d`/`[d`/`]d` mappings (trouble rebinds the same idea to `xx`, `}d`, `{d`), and its `Todo` mode is also the nicest browser for todo-comments' findings below. **`plugins.nvim-lightbulb.enable` + `plugins.fastaction.enable`** — Lightbulb puts a `💡` in the sign column whenever the LSP offers a code action (organize imports, fix it), and fastaction makes `ga` jump-to-and-apply one of the offered actions. You already have `<leader>ca` from slice 1, so this is purely discoverability — the lightbulb tells you an action *exists* before you think to ask. ## QoL / Tier 2 leftovers **`plugins.todo-comments.enable`** — Highlights `TODO`/`FIXME`/`NOTE` (and any tags you add) and makes them searchable via telescope/trouble. Quietly useful in a repo like nixos where half the TODOs are you leaving notes to future-you. **`plugins.flash.enable`** — Type any 2+ chars and every match on screen gets a letter; hit the letter, cursor jumps there — for motion, search and visual selection. It replaces most `f`/`t`/`/`-based hopping in daily use; `leap` is the older, more conservative alternative if flash feels too aggressive. **`plugins.aerial.enable`** — A sidebar outline of the symbols in the current file (functions, options, sections) from treesitter or LSP, with `:AerialToggle` and jump-to-symbol, and it can also act as a winbar breadcrumb. For long `flake.nix`/module files it's the fastest way to see the structure and hop between option blocks. **`plugins.illuminate.enable`** — Highlights every other occurrence of the word under the cursor in the buffer, so you can see at a glance where a variable is used without pressing anything. Zero-keymap and zero-config; the only reason to skip it is if you find extra highlights visually noisy next to gitsigns and treesitter. **`plugins.dressing.enable`** — Replaces nvim's stock `:input`/`:select`/`:prompt` UI (rename, quickfix picker dialogs) with telescope/fzf-style fuzzy prompts. Worth noting vanilla Neovim 0.10+ already made `I`/`a` on the command line much better, so dressing's value is mostly fuzzy selection and consistent look — small but pleasant. **`plugins.nvim-surround.enable`** — The classic surround edits: `cs"'` changes `"foo"` to `'foo'`, `ds)` deletes a delimiter, `ysiw]` wraps the word under cursor. If you came from AstroNvim you had this via its distribution; nixvim bare doesn't include it, and it's the one textobject plugin people genuinely miss. **`plugins.neogen.enable`** — Generates/updates docstrings for the function under the cursor (Python `"""`, LuaLS `---@`, doxygen, etc.) from signatures and LSP type info. Mostly a Python/C++ payoff; on nix files it has little to do, so it can wait for a language slice. **`plugins.fidget.enable`** — Replaces the default `:messages` area with a clean bottom-right progress widget, mainly so LSP `indexing…`/`hover…` chatter stops scribbling over your command line. The lighter alternative is `plugins.noice` (which also themes `:IncSearch` and nvim-notify); fidget is the lower-risk half of that idea. **`plugins.zen-mode.enable` (+ `plugins.twilight.enable`)** — zen-mode toggles a distraction-free window (hides signcolumn/statusline/line numbers, centers and pads the text column); twilight dims everything outside the current code *block*. Both are pure focus ergonomics — nice for writing markdown, irrelevant while you're hopping between modules — so take them or leave them. **`plugins.ts-comments.enable` + `plugins.ts-context-commentstring.enable`** — Keeps `gc` inserting the *correct* comment string per context: `--` inside nix `-- lua [[ ]]` blocks, `#` in shell embedded in nix, etc., using treesitter. Vanilla `gc` (built into nvim 0.10+, which is in your repo as `vim-comments`) is fine 90% of the time; these two fix the remaining multi-language-string cases. Note the standalone `comment.nvim` is abandoned/superseded — don't take it. ## My suggested slice 3 (~7 modules, one file each) lualine + autopairs + indent-blankline (disable snacks.indent) + trouble + nvim-surround + flash + todo-comments — the daily-driver ergonomics, no keymap conflicts with slices 1–2. Second tier whenever: lint, lightbulb+fastaction, aerial, illuminate, dressing, fidget. Defer: neogen, zen/twilight, ts-comments. One dependency note: ts-comments needs `treesitter-textobjects`, and `plugins/treesitter.nix` is still commented out of `plugins/default.nix` on main — if you want the treesitter-dependent ones (aerial treesitter symbols, ts-comments, indent-blankline's treesitter tracking), that import uncomment is a prerequisite worth deciding on first.
Author
Owner

Random question, is there an lsp/syntax highlighter for grafana alloy? Currently looking at one and it's a little hard on the eyes. Also, is there a way to force what syntax something is currently being evaluated as? Just in case I need to force it to something. Also looking at a jinja2 template of an alloy config file.

Random question, is there an lsp/syntax highlighter for grafana alloy? Currently looking at one and it's a little hard on the eyes. Also, is there a way to force what syntax something is currently being evaluated as? Just in case I need to force it to something. Also looking at a jinja2 template of an alloy config file.
Member

test probe — please ignore

test probe — please ignore
Member

probe2 with percent: .*%.alloy please ignore

probe2 with percent: .*%.alloy please ignore
Member

Short answer: no LSP for the Grafana Alloy config language — and beware the trap in nvim-lspconfig/nixvim: plugins.lsp.servers.alloy_ls is the AlloyTools formal-spec language (*.als), an entirely different thing that just happens to share the name. What actually exists for Grafana Alloy:

Syntax highlighting options (best → adequate)

1. tree-sitter grammar — mattsre/tree-sitter-alloy (MIT, 2025). Parses the real Alloy DSL — component blocks, labels, dotted refs like prometheus.scrape — and ships highlight queries. It's not in nixpkgs or nvim-treesitter's grammar set, but it builds with the standard nixvim custom-grammar recipe:

programs.nixvim.plugins.treesitter = {
  grammarPackages =
    config.programs.nixvim.plugins.treesitter.package.builtGrammars ++ [ ts-alloy ];
  languageRegister.alloy = "alloy";
};
# with
ts-alloy = pkgs.tree-sitter.buildGrammar {
  language = "alloy";
  version = "0.0.0+rev=<rev>";
  src = pkgs.fetchFromGitHub { owner = "mattsre"; repo = "tree-sitter-alloy"; rev = "<rev>"; hash = "..."; };
  meta.homepage = "https://github.com/mattsre/tree-sitter-alloy";
};

(Plus extraPlugins = [ ts-alloy ]; so its queries/ dir lands on the rtp — the pattern is verbatim from the nixvim treesitter README's custom-grammars section.) This is the tier that will actually stop being hard on the eyes.

2. Official regex syntax — grafana/vim-alloy. What Grafana's own docs point Vim users at: *.alloy → ft=alloy ftdetect + a vim syntax file. Classic vim-regex tier (strings/comments/keywords, no real parsing). Also not in nixpkgs vimPlugins, so plugins.extraPlugins + pkgs.vimUtils.buildVimPlugin on rev 0273f88f7199189f9a0f32213a34ab778e226f86.

3. Cheap fallback: borrow the HCL parser. Alloy is HCL-ish but not HCL — the dotted component names become error nodes in tree-sitter-hcl (known upstream issue), so highlights will be mostly-right but wrong on exactly the loki.source.file identifiers that matter. Fine as a one-liner until you wire #1: vim.treesitter.language.register('hcl', 'alloy').

4. The thing actually worth having: alloy validate / alloy fmt. pkgs.grafana-alloy is in nixpkgs, and validate reports syntax errors, missing components, name conflicts, unset-required and unknown attributes — strictly more than any highlighter gives you. Make-prg hookup:

programs.nixvim.autoCmd = [
  {
    desc = "alloy validate via :make";
    event = "FileType";
    pattern = "alloy";
    command = "setlocal makeprg=alloy\\ validate\\ %";
  }
];

:make then fills the quickfix with the diagnostics (tweak errorformat to taste against :messages output — alloy diagnostics carry file:line:col), and formatting is just :!alloy fmt -w % — no conform needed, in keeping with your manual-formatting preference.

Forcing what a buffer is evaluated as

  • :setfiletype alloy — overrides auto-detection for the current buffer; :filetype detect re-detects. (:set ft=alloy is the same thing.)
  • :set syntax=hcl forces only the vim regex-syntax layer, leaving filetype (and hence LSP/ftplugins) alone.
  • To see what is actually painting your buffer: :Inspect (which highlight group, from which source) and :InspectTS (which parser/node captured it). Treesitter looking wrong on one buffer? :TSBufDisable highlight falls back to regex syntax for that buffer only.
  • Permanently: a FileType-setting autocmd (autoCmd with BufNewFile,BufRead + pattern), or plugins.treesitter.languageRegister once you have a parser registered.

Jinja2 template of an alloy config

Honest answer: nobody ships jinja-contains-alloy highlighting. Treesitter's injection system can do nested highlighting in principle, but no jinja→alloy injection exists; that's a build-it-yourself project, not an install. The pragmatic split:

  • Template correctness: :set ft=jinja and lean on plugins.lsp.servers.jinja_lsp (jinja-lsp is in nixpkgs) — completion/hover/diagnostics for the Jinja layer. Caveat: jinja-lsp targets minijinja, so it's ~Jinja2 but not 100%.
  • Alloy correctness: validate the rendered output, not the template — render with j2/python -m jinja2.cli (or whatever deploys it) and alloy validate the result. That's the workflow I'd rely on: highlighting can't save you from a {% if %} that renders into a broken pipeline; validate can.

Say the word and I'll package 1 + 4 (grammar build + validate autocmd, optionally vim-alloy as belt-and-braces) into the next slice PR.

Short answer: **no LSP for the Grafana Alloy config language** — and beware the trap in nvim-lspconfig/nixvim: `plugins.lsp.servers.alloy_ls` is the *AlloyTools formal-spec language* (`*.als`), an entirely different thing that just happens to share the name. What actually exists for Grafana Alloy: ## Syntax highlighting options (best → adequate) **1. tree-sitter grammar — `mattsre/tree-sitter-alloy`** (MIT, 2025). Parses the real Alloy DSL — component blocks, labels, dotted refs like `prometheus.scrape` — and ships highlight queries. It's not in nixpkgs or nvim-treesitter's grammar set, but it builds with the standard nixvim custom-grammar recipe: ```nix programs.nixvim.plugins.treesitter = { grammarPackages = config.programs.nixvim.plugins.treesitter.package.builtGrammars ++ [ ts-alloy ]; languageRegister.alloy = "alloy"; }; # with ts-alloy = pkgs.tree-sitter.buildGrammar { language = "alloy"; version = "0.0.0+rev=<rev>"; src = pkgs.fetchFromGitHub { owner = "mattsre"; repo = "tree-sitter-alloy"; rev = "<rev>"; hash = "..."; }; meta.homepage = "https://github.com/mattsre/tree-sitter-alloy"; }; ``` (Plus `extraPlugins = [ ts-alloy ];` so its queries/ dir lands on the rtp — the pattern is verbatim from the nixvim treesitter README's custom-grammars section.) This is the tier that will actually stop being hard on the eyes. **2. Official regex syntax — `grafana/vim-alloy`.** What Grafana's own docs point Vim users at: `*.alloy` → `ft=alloy` ftdetect + a vim syntax file. Classic vim-regex tier (strings/comments/keywords, no real parsing). Also not in nixpkgs `vimPlugins`, so `plugins.extraPlugins` + `pkgs.vimUtils.buildVimPlugin` on rev `0273f88f7199189f9a0f32213a34ab778e226f86`. **3. Cheap fallback: borrow the HCL parser.** Alloy is HCL-ish but *not* HCL — the dotted component names become error nodes in tree-sitter-hcl (known upstream issue), so highlights will be mostly-right but wrong on exactly the `loki.source.file` identifiers that matter. Fine as a one-liner until you wire #1: `vim.treesitter.language.register('hcl', 'alloy')`. **4. The thing actually worth having: `alloy validate` / `alloy fmt`.** `pkgs.grafana-alloy` is in nixpkgs, and `validate` reports syntax errors, missing components, name conflicts, unset-required and unknown attributes — strictly more than any highlighter gives you. Make-prg hookup: ```nix programs.nixvim.autoCmd = [ { desc = "alloy validate via :make"; event = "FileType"; pattern = "alloy"; command = "setlocal makeprg=alloy\\ validate\\ %"; } ]; ``` `:make` then fills the quickfix with the diagnostics (tweak `errorformat` to taste against `:messages` output — alloy diagnostics carry file:line:col), and formatting is just `:!alloy fmt -w %` — no conform needed, in keeping with your manual-formatting preference. ## Forcing what a buffer is evaluated as - `:setfiletype alloy` — overrides auto-detection for the current buffer; `:filetype detect` re-detects. (`:set ft=alloy` is the same thing.) - `:set syntax=hcl` forces only the vim regex-syntax layer, leaving `filetype` (and hence LSP/ftplugins) alone. - To see what is actually painting your buffer: `:Inspect` (which highlight group, from which source) and `:InspectTS` (which parser/node captured it). Treesitter looking wrong on one buffer? `:TSBufDisable highlight` falls back to regex syntax for that buffer only. - Permanently: a `FileType`-setting autocmd (`autoCmd` with `BufNewFile,BufRead` + pattern), or `plugins.treesitter.languageRegister` once you have a parser registered. ## Jinja2 template of an alloy config Honest answer: nobody ships jinja-contains-alloy highlighting. Treesitter's injection system can do nested highlighting in principle, but no jinja→alloy injection exists; that's a build-it-yourself project, not an install. The pragmatic split: - **Template correctness**: `:set ft=jinja` and lean on `plugins.lsp.servers.jinja_lsp` (`jinja-lsp` is in nixpkgs) — completion/hover/diagnostics for the Jinja layer. Caveat: jinja-lsp targets minijinja, so it's ~Jinja2 but not 100%. - **Alloy correctness**: validate the *rendered* output, not the template — render with `j2`/`python -m jinja2.cli` (or whatever deploys it) and `alloy validate` the result. That's the workflow I'd rely on: highlighting can't save you from a `{% if %}` that renders into a broken pipeline; validate can. Say the word and I'll package 1 + 4 (grammar build + validate autocmd, optionally vim-alloy as belt-and-braces) into the next slice PR.
Author
Owner

Not sure why this one was closed. It shouldn't have been, we still have a long way to go. For the next round, implement:

todo-comments, neogen, lualine, lint, trouble, autopairs, indent-blankline.

Let's also implement some of the python work.

pyright and ruff, dap, neotest. No to venv-selector as I work under nix. venv is redundant.

Not sure why this one was closed. It shouldn't have been, we still have a long way to go. For the next round, implement: todo-comments, neogen, lualine, lint, trouble, autopairs, indent-blankline. Let's also implement some of the python work. pyright and ruff, dap, neotest. No to venv-selector as I work under nix. venv is redundant.
rpickler reopened this issue 2026-10-17 05:08:44 +00:00
Member

Slice 3 pushed: PR #28 (issue-19-nixvim-slice-3-python) — the seven QoL plugins + the python stack from your last comment.

QoL (plugins/qol.nix): todo-comments (gutter signs + makes the existing telescope <leader>ft work + <leader>xt trouble view), neogen (<leader>an generates the docstring under cursor; <leader>a* stays CodeCompanion's), lualine (theme auto, globalstatus), lint (shellcheck/hadolint/yamllint, binaries auto-installed from Nix), trouble (<leader>xx/xX/xq/xl/cs/cl), nvim-autopairs (Tab stays with cmp), indent-blankline (snacks' indent renderer disabled so guides aren't drawn twice).

Python (plugins/python.nix): pyright + ruff (the modern built-in Rust LSP, not deprecated ruff-lsp) via Nix-provided servers; dap + dap-ui + virtual-text + dap-python (F5 run, F6 breakpoint, F7/F8/S-F8 steps, <leader>du UI, <leader>dr REPL — debugpy comes from Nix, nothing pip-installed); neotest python adapter (<leader>tt cursor, <leader>tT file, <leader>tl last, <leader>to panel, <leader>ts summary, <leader>ta debug-run via dap) with a Nix python3.withPackages [pytest] on nvim's PATH. No venv-selector, per your note. Formatting stays manual everywhere.

All module options verified against the nixvim rev pinned in flake.lock (5b912bd8); trouble commands from its README, neotest keymaps use the documented Lua API. Not build-verified from my side (no nix here) — switch/dev-shell will tell you fast; everything is module-level options, no raw configs to drift.

Slice 3 pushed: PR #28 (`issue-19-nixvim-slice-3-python`) — the seven QoL plugins + the python stack from your last comment. **QoL** (`plugins/qol.nix`): todo-comments (gutter signs + makes the existing telescope `<leader>ft` work + `<leader>xt` trouble view), neogen (`<leader>an` generates the docstring under cursor; `<leader>a*` stays CodeCompanion's), lualine (theme auto, globalstatus), lint (shellcheck/hadolint/yamllint, binaries auto-installed from Nix), trouble (`<leader>xx`/`xX`/`xq`/`xl`/`cs`/`cl`), nvim-autopairs (Tab stays with cmp), indent-blankline (snacks' indent renderer disabled so guides aren't drawn twice). **Python** (`plugins/python.nix`): pyright + ruff (the modern built-in Rust LSP, not deprecated ruff-lsp) via Nix-provided servers; dap + dap-ui + virtual-text + dap-python (F5 run, F6 breakpoint, F7/F8/S-F8 steps, `<leader>du` UI, `<leader>dr` REPL — debugpy comes from Nix, nothing pip-installed); neotest python adapter (`<leader>tt` cursor, `<leader>tT` file, `<leader>tl` last, `<leader>to` panel, `<leader>ts` summary, `<leader>ta` debug-run via dap) with a Nix `python3.withPackages [pytest]` on nvim's PATH. No venv-selector, per your note. Formatting stays manual everywhere. All module options verified against the nixvim rev pinned in flake.lock (5b912bd8); trouble commands from its README, neotest keymaps use the documented Lua API. Not build-verified from my side (no nix here) — switch/dev-shell will tell you fast; everything is module-level options, no raw configs to drift.
Author
Owner

I've been happily using the latest round for a few days now. What's left?

I've been happily using the latest round for a few days now. What's left?
Member

All three slices are merged, so the config now covers Nix (nixd, statix, direnv) and Python (pyright, ruff, dap, neotest) completely, plus the ergonomics layers. Here's everything that's actually left, biggest first. Every name below re-verified as a by-name module against the nixvim rev pinned in your flake.lock right now (453dc9c5).

1. C++ — the one language from the original ask that never got sliced

That's the real substance for slice 4:

  • clangd — the C/C++ LSP with Akari's args (--background-index --clang-tidy --header-insertion=iwyu). Formatting comes from clangd itself, so <leader>cf keeps working manually — no conform/format-on-save.
  • clangd-extensions — AST browser, quick .h↔.cpp switch, and richer inlay hints than clangd's built-ins.
  • cmake (LSP) + cmake-tools — CMakeLists IntelliSense, plus build/test-preset running from inside nvim; the nixvim module pulls cmake itself.
  • C++ debugging — gdb via nvim-dap's built-in adapter (gdb from Nix), or dap-lldb if you'd rather lldb. The F5/F6/F7/F8 keys from slice 3 work unchanged once an adapter matches.

2. Ergonomics leftovers — the rest of the survey list you never picked

  • nvim-surround — cs"' changes quotes, ds) deletes a delimiter, ysiw] wraps a word. It was in my proposed slice 3; your pick didn't include it; it's the one textobject plugin people genuinely miss after AstroNvim.
  • flash — type two chars and every on-screen match gets a letter; hit the letter, cursor jumps. Replaces most f/t// hopping, for motion, search, and visual selection.
  • dressing — fuzzy, telescope-style UI for nvim's stock :input/:select prompts (LSP rename dialog is the big one). Zero keymaps, purely an upgrade.
  • illuminate — highlights the other occurrences of the word under the cursor, no keymaps, no config. Skip only if it reads as visual noise next to gitsigns.
  • aerial — sidebar outline of the current file (functions, option blocks) from LSP or treesitter, with jump-to-symbol and optional winbar breadcrumbs. Nicest on long module/flake files.
  • fidget — moves the LSP indexing…/hover… progress chatter into a bottom-right widget so it stops scribbling over the command line.
  • nvim-lightbulb + fastaction — a sign-column lightbulb whenever the LSP has a code action for the cursor, and ga to apply one. Pure discoverability on top of the existing <leader>ca.

3. Nix leftovers (small)

  • nix-develop — held back from slice 1 and never landed: auto-enters nix develop when you open a flake.nix/shell.nix buffer. The installed direnv plugin only covers .envrc export, not flake dev-shells.
  • mypy via lint — one line in lintersByFt.python; redundant if you trust pyright's checking alone.
  • treesitter.nix — treesitter is enabled on main (the root default.nix turns it on for CodeCompanion's context), but the dedicated plugins/treesitter.nix file with your custom parsers/languages list is still commented out of plugins/default.nix. Uncommenting is the prerequisite for the ts-dependent bits below and sharpens aerial/autopairs.

4. Parked earlier — still open decisions

  • zen-mode + twilight — focus/writing modes; take or leave per your earlier call.
  • ts-comments + ts-context-commentstring — gc inserts the contextually correct comment char (inside nix -- blocks, embedded strings). Needs the treesitter.nix uncomment above.
  • Alloy tree-sitter grammar — the mattsre/tree-sitter-alloy recipe from the Grafana question is still ready if you're deep in .alloy files now; custom-grammar build, one file.
  • blink-cmp — a switch, not an addition (the Rust-backed successor to nvim-cmp, what Akari uses). I'd hold — cmp is doing its job.

My pick for slice 4: the full C++ stack + nvim-surround + flash + dressing + illuminate — one lang-cpp.nix plus a short addendum to qol.nix, about slice-3 sized. Say the word (or a different cut) and I'll push the branch.

All three slices are merged, so the config now covers **Nix** (nixd, statix, direnv) and **Python** (pyright, ruff, dap, neotest) completely, plus the ergonomics layers. Here's everything that's actually left, biggest first. Every name below re-verified as a by-name module against the nixvim rev pinned in your `flake.lock` right now (`453dc9c5`). ## 1. C++ — the one language from the original ask that never got sliced That's the real substance for slice 4: - **clangd** — the C/C++ LSP with Akari's args (`--background-index --clang-tidy --header-insertion=iwyu`). Formatting comes from clangd itself, so `<leader>cf` keeps working manually — no conform/format-on-save. - **clangd-extensions** — AST browser, quick `.h`↔`.cpp` switch, and richer inlay hints than clangd's built-ins. - **cmake** (LSP) + **cmake-tools** — CMakeLists IntelliSense, plus build/test-preset running from inside nvim; the nixvim module pulls cmake itself. - **C++ debugging** — gdb via nvim-dap's built-in adapter (gdb from Nix), or `dap-lldb` if you'd rather lldb. The F5/F6/F7/F8 keys from slice 3 work unchanged once an adapter matches. ## 2. Ergonomics leftovers — the rest of the survey list you never picked - **nvim-surround** — `cs"'` changes quotes, `ds)` deletes a delimiter, `ysiw]` wraps a word. It was in my proposed slice 3; your pick didn't include it; it's the one textobject plugin people genuinely miss after AstroNvim. - **flash** — type two chars and every on-screen match gets a letter; hit the letter, cursor jumps. Replaces most `f`/`t`/`/` hopping, for motion, search, and visual selection. - **dressing** — fuzzy, telescope-style UI for nvim's stock `:input`/`:select` prompts (LSP rename dialog is the big one). Zero keymaps, purely an upgrade. - **illuminate** — highlights the other occurrences of the word under the cursor, no keymaps, no config. Skip only if it reads as visual noise next to gitsigns. - **aerial** — sidebar outline of the current file (functions, option blocks) from LSP or treesitter, with jump-to-symbol and optional winbar breadcrumbs. Nicest on long module/flake files. - **fidget** — moves the LSP `indexing…`/`hover…` progress chatter into a bottom-right widget so it stops scribbling over the command line. - **nvim-lightbulb + fastaction** — a sign-column lightbulb whenever the LSP has a code action for the cursor, and `ga` to apply one. Pure discoverability on top of the existing `<leader>ca`. ## 3. Nix leftovers (small) - **nix-develop** — held back from slice 1 and never landed: auto-enters `nix develop` when you open a `flake.nix`/`shell.nix` buffer. The installed direnv plugin only covers `.envrc` export, not flake dev-shells. - **mypy via lint** — one line in `lintersByFt.python`; redundant if you trust pyright's checking alone. - **treesitter.nix** — treesitter *is* enabled on main (the root `default.nix` turns it on for CodeCompanion's context), but the dedicated `plugins/treesitter.nix` file with your custom parsers/languages list is still commented out of `plugins/default.nix`. Uncommenting is the prerequisite for the ts-dependent bits below and sharpens aerial/autopairs. ## 4. Parked earlier — still open decisions - **zen-mode + twilight** — focus/writing modes; take or leave per your earlier call. - **ts-comments + ts-context-commentstring** — `gc` inserts the contextually correct comment char (inside nix `--` blocks, embedded strings). Needs the treesitter.nix uncomment above. - **Alloy tree-sitter grammar** — the `mattsre/tree-sitter-alloy` recipe from the Grafana question is still ready if you're deep in `.alloy` files now; custom-grammar build, one file. - **blink-cmp** — a *switch*, not an addition (the Rust-backed successor to nvim-cmp, what Akari uses). I'd hold — cmp is doing its job. **My pick for slice 4:** the full C++ stack + nvim-surround + flash + dressing + illuminate — one `lang-cpp.nix` plus a short addendum to `qol.nix`, about slice-3 sized. Say the word (or a different cut) and I'll push the branch.
Author
Owner

Let's do the c++ stack, turn on telescope with the two recommended extensions, dressing, light bulb and fast action. I think that will be the last of it. Forget alloy on the telescope implementation

Let's do the c++ stack, turn on telescope with the two recommended extensions, dressing, light bulb and fast action. I think that will be the last of it. Forget alloy on the telescope implementation
Author
Owner

I can see you spiraling trying to figure out what I want in the next slice, so let me spell it out:

  • Uncomment treesitter in plugins/default.nix
  • add ts-comments and ts-context-commentstring
  • fix whatever needs fixing in treesitter
  • forget alloy treesitter
  • aerial
  • nvim-lightbulb + fastaction
  • dressing
  • c++ stack
I can see you spiraling trying to figure out what I want in the next slice, so let me spell it out: * Uncomment treesitter in plugins/default.nix * add ts-comments and ts-context-commentstring * fix whatever needs fixing in treesitter * forget alloy treesitter * aerial * nvim-lightbulb + fastaction * dressing * c++ stack
Member

Slice 4 pushed and build-verified: #48 (issue-19-nixvim-slice-4-cpp-ui) — your spelled-out list from the last comment, plus the two recommended telescope extensions from the one before (they were sitting commented-out in telescope.nix, exactly as you left them). Alloy is out everywhere.

  • treesitter — stub file was empty (that's why the import was commented out); rewritten for the nixvim rev now in your lock, which targets nvim-treesitter main via Neovim's native APIs — all grammars from Nix, highlight+indent options (indent off for nix; nixd owns that). No foldexpr fight: ufo keeps the lead and auto-picks up the new treesitter fold ranges.
  • ts-comments + ts-context-commentstring — gc on the right syntactic node, context-correct comment tokens.
  • aerial — outline sidebar, <leader>ao toggle (<leader>aO with focus).
  • nvim-lightbulb + fastaction — 💡 when a code action exists, one-key letter picking through fastaction; <leader>ca unchanged.
  • dressing — float UI for :input/:select. One note: dressing and telescope-ui-select both style vim.ui.select; both blocks are self-contained, delete either if the rename picker isn't your taste.
  • C++ stack — clangd (Akari flags: --background-index --clang-tidy --header-insertion=iwyu), clangd-extensions (AST browser, .h↔.cpp), cmake LSP + cmake-tools, and C/C++ debugging through the slice-3 dap keys (gdb MI adapter, c/cpp launch configs; cmake+gdb from Nix). Formatting stays manual — <leader>cf formats via clangd.
  • telescope extensions — fzf-native (compiled sorter) + ui-select (with the codeactions sorter).

Build-verified this time (I have nix now): full nix build of the neovim package from your sausage home-manager config against the locked nixvim rev exits 0 — all plugins land in the pack dir, clangd flags/gdb adapter/ufo in the generated init, and one real bug was caught and fixed before pushing (clangd cmd must live under settings in the nixvim server modules). Rebuild is the last word, but this is the strongest round yet.

The PR says Closes #19, so merging lands the "last of it" — if you're not done with the survey list after all (flash, nvim-surround, illuminate, fidget, zen/twilight stay parked), the keyword is one edit away.

Slice 4 pushed and build-verified: #48 (`issue-19-nixvim-slice-4-cpp-ui`) — your spelled-out list from the last comment, plus the two recommended telescope extensions from the one before (they were sitting commented-out in `telescope.nix`, exactly as you left them). Alloy is out everywhere. - **treesitter** — stub file was empty (that's why the import was commented out); rewritten for the nixvim rev now in your lock, which targets nvim-treesitter *main* via Neovim's native APIs — all grammars from Nix, highlight+indent options (indent off for `nix`; nixd owns that). No foldexpr fight: ufo keeps the lead and auto-picks up the new treesitter fold ranges. - **ts-comments + ts-context-commentstring** — `gc` on the right syntactic node, context-correct comment tokens. - **aerial** — outline sidebar, `<leader>ao` toggle (`<leader>aO` with focus). - **nvim-lightbulb + fastaction** — 💡 when a code action exists, one-key letter picking through fastaction; `<leader>ca` unchanged. - **dressing** — float UI for `:input`/`:select`. One note: dressing and telescope-ui-select both style `vim.ui.select`; both blocks are self-contained, delete either if the rename picker isn't your taste. - **C++ stack** — clangd (Akari flags: `--background-index --clang-tidy --header-insertion=iwyu`), clangd-extensions (AST browser, `.h`↔`.cpp`), cmake LSP + cmake-tools, and C/C++ debugging through the slice-3 dap keys (gdb MI adapter, `c`/`cpp` launch configs; `cmake`+`gdb` from Nix). Formatting stays manual — `<leader>cf` formats via clangd. - **telescope extensions** — `fzf-native` (compiled sorter) + `ui-select` (with the codeactions sorter). **Build-verified this time** (I have nix now): full `nix build` of the neovim package from your `sausage` home-manager config against the locked nixvim rev exits 0 — all plugins land in the pack dir, clangd flags/gdb adapter/ufo in the generated init, and one real bug was caught and fixed before pushing (clangd `cmd` must live under `settings` in the nixvim server modules). Rebuild is the last word, but this is the strongest round yet. The PR says `Closes #19`, so merging lands the "last of it" — if you're *not* done with the survey list after all (flash, nvim-surround, illuminate, fidget, zen/twilight stay parked), the keyword is one edit away.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
richardpickler.com/nixos#19
No description provided.