neovim refactor
This commit is contained in:
1 parent
b12c211a69
commit
883f9d26c2
25 files changed
+1154
-880
No files matched your search
@@ -0,0 +1,190 @@
|
||||
# Neovim redesign and cleanup plan
|
||||
|
||||
## Governing intent
|
||||
|
||||
Make Neovim the primary editor and turn its configuration into a small, readable, cohesive system. Refactoring, simplification, runtime performance, reliability and UX are equal deliverables; do not bolt new plugins onto the current structure.
|
||||
|
||||
Use Helix's philosophy as the decision framework throughout implementation, including unforeseen choices:
|
||||
|
||||
- Prefer a few orthogonal concepts over aliases and special cases.
|
||||
- Make related commands symmetric, mnemonic and context-aware.
|
||||
- Provide one canonical interface for each task; hide plugin identity.
|
||||
- Make first use behave like later use; load order must not affect behavior.
|
||||
- Keep the screen quiet and reveal information when relevant or requested.
|
||||
- Prefer native Neovim behavior when it fits this model.
|
||||
- Remove code, configuration and plugins that do not justify their complexity.
|
||||
|
||||
These principles govern the detailed plan. If a minor implementation detail conflicts with them, choose the simpler coherent solution and report the deviation. If resolving a conflict changes the user-facing command model, dependencies or scope, stop and request a plan amendment. Do not use this discretion to expand scope.
|
||||
|
||||
## Context and scope
|
||||
|
||||
- Neovim module: `modules/capabilities/neovim/default.nix`.
|
||||
- Lua root: `modules/capabilities/neovim/lua-config`.
|
||||
- `modules/profiles/host-base.nix` currently selects `primary-editor-helix`; therefore the active shell has no `nvim`.
|
||||
- Locked versions include Neovim 0.12.4 and Kulala 6.29.0. Target them; add no older-version compatibility.
|
||||
- Retain `nix-wrapper-modules`, `lz.n` and the custom Svelte Treesitter grammar.
|
||||
- First-class languages: Nix, TypeScript/JavaScript, Svelte, Rust and Python.
|
||||
- Also retain Lua, JSON, CSS, HTML, Astro, Typst, TOML, YAML, Markdown/`zk` and snippets. Remove Dafny.
|
||||
- Add Oil, Grug-far, Dadbod UI, SQL completion, Kulala request/environment/import support and `zk-nvim`.
|
||||
- Add YAML/JSON schema support and automatic web-tag closing/renaming.
|
||||
- Exclude sessions, embedded-terminal workflow beyond leaving terminal mode, Git porcelain, debugging, test runners, AI tooling and graphical ER modeling.
|
||||
- Preserve unrelated worktree changes, including `modules/capabilities/desktop-defaults.nix` if still modified.
|
||||
|
||||
Known defects and cleanup targets:
|
||||
|
||||
- Nix plugin groups and Lua modules do not share a clear capability structure; Kulala is in `ui.lua`, while `lsp.lua` also owns Telescope loading, diagnostics and breadcrumbs.
|
||||
- `options.lua` contains mappings and an autocmd.
|
||||
- Telescope dependency arrays and manual `trigger_load` calls are duplicated. Code-action UI changes after Telescope first loads.
|
||||
- Treesitter starts through three overlapping events.
|
||||
- Navic uses a global callback evaluated by winbars.
|
||||
- LSP attach callbacks recreate shared autocmd groups.
|
||||
- `project.nvim` changes global cwd; `direnv.vim` runs on every buffer entry although the launching shell owns the environment.
|
||||
- Dadbod is absent; Kulala installs global mappings; several installed plugins lack explicit setup.
|
||||
|
||||
## Required structure and code quality
|
||||
|
||||
Before editing, inventory every Neovim option, mapping, autocmd, plugin, runtime package and server. Delete duplicates, unused entries and configuration that restates defaults.
|
||||
|
||||
Align Nix plugin groups with these Lua modules:
|
||||
|
||||
- `init.lua`: ordered `require` calls only.
|
||||
- `options.lua`: options only.
|
||||
- `keymaps.lua`: plugin-independent mappings and intentional default removals.
|
||||
- `autocmds.lua`: editor-wide autocmds.
|
||||
- `plugins/editing.lua`: mini.ai/surround/pairs/icons, indentation detection, Treesitter, text objects, rainbow delimiters, automatic tag handling and Grug-far.
|
||||
- `plugins/navigation.lua`: Telescope, FZF, `ui-select` and Oil.
|
||||
- `plugins/diagnostics.lua`: native diagnostic presentation and Trouble.
|
||||
- `plugins/lsp.lua`: servers, attach/detach behavior and Navic attachment.
|
||||
- `plugins/completion.lua`, `formatting.lua`, `ui.lua`, `database.lua`, `http.lua`, `notes.lua`: one concern each.
|
||||
|
||||
Enforce these rules:
|
||||
|
||||
- One owner per option, mapping, autocmd and plugin setup.
|
||||
- Keep plugin-backed mappings in their plugin specification; declare Which-key groups centrally.
|
||||
- Give every lazy plugin an explicit `keys`, `cmd`, `ft` or `event` trigger. Only dependency entries may omit one.
|
||||
- Use `lz.n` declaratively. Remove scattered `trigger_load` wrappers.
|
||||
- Create each augroup once and scope buffer behavior with `buffer = args.buf`.
|
||||
- Keep state local; add no `_G` callbacks.
|
||||
- Add a helper only when at least two capabilities use it and it reduces conceptual complexity.
|
||||
- Comments explain non-obvious constraints or decisions, not syntax. Delete commented-out code.
|
||||
- Prefer current native APIs and defaults. Add no speculative guards, fallbacks or compatibility layers.
|
||||
- Move Kanagawa setup into `ui.lua`; delete the generated Lua string and `_kanagawa-theme.nix`. Use `nix-info` only for Nix expressions and store paths.
|
||||
- Group Nix packages by capability/language and remove obsolete entries.
|
||||
|
||||
## Interaction model
|
||||
|
||||
| Task | Canonical interface |
|
||||
| --- | --- |
|
||||
| Filesystem operations | Oil editable directory buffer |
|
||||
| Files, text, symbols, references, diagnostics, commands | Telescope |
|
||||
| Project-wide text or regex replacement | Grug-far |
|
||||
| Syntax movement/selection in the current buffer | Treesitter |
|
||||
| Code relationships and semantic refactors | LSP; Telescope renders result collections |
|
||||
| Persistent diagnostics/promoted results | Trouble |
|
||||
| Database inspection/queries | Dadbod UI |
|
||||
| HTTP requests | Kulala |
|
||||
| Note capture and discovery | `zk-nvim`; Telescope renders note collections |
|
||||
|
||||
Use buffers, not tabs or sessions, as the open-file model. Root project searches at `vim.fs.root(0, { ".git" })`, falling back to the process cwd; never change cwd implicitly. Keep Telescope's default result behavior. Provide one Telescope action that sends results to quickfix and opens Trouble.
|
||||
|
||||
Keep LSP rename and code actions as the semantic project-wide refactoring interface. Use Grug-far for explicit text or regular-expression replacement; do not add an integration layer between them.
|
||||
|
||||
Make Oil the directory handler. `<leader>e` opens the current file's directory. Keep filesystem-change confirmation.
|
||||
|
||||
## Keymap and discovery contract
|
||||
|
||||
Set `<leader>` to space and `<localleader>` to comma. Every custom mapping needs an action-oriented `desc`. Remove displaced plugin/native aliases.
|
||||
|
||||
- `g…`: `gd` definition, `gD` declaration, `gr` references, `gI` implementation, `gy` type definition, `gO` document symbols, `K` hover.
|
||||
- `[x`/`]x`: previous/next diagnostic `d`, Git hunk `h`, function `f`, class/type `c`, parameter `a`. Replace conflicting defaults for these exact keys as one family.
|
||||
- `<leader>s…`: Telescope project files/grep, cursor word, current buffer, recent files, workspace symbols, diagnostics, help, commands, keymaps and resume.
|
||||
- `<leader>c…`: `ca` code action, `cr` rename, `cf` format, `cR` project-wide replacement. Remove displaced `gr*` LSP mappings.
|
||||
- `<leader>d…`: persistent workspace/buffer diagnostics. Remove `<leader>x…` Trouble and location-list diagnostic mappings.
|
||||
- `<leader>b…`: buffer picker/delete. Remove the duplicate `<leader><leader>` picker.
|
||||
- `<leader>q…`: database workspace; `qo` toggles Dadbod UI.
|
||||
- `<leader>r…`: global HTTP facilities, including the scratchpad.
|
||||
- `<leader>n…`: central notes; `nn` captures, `nf` finds notes and `nt` finds tags. Inside a `zk` note, `ni` inserts a link.
|
||||
- `<leader>u…`: UI toggles only.
|
||||
- `gl`: diagnostic details; `<C-h/j/k/l>`: window focus; `<Esc><Esc>`: leave terminal mode.
|
||||
- Keep native `gg`, `G` and word motions. Do not alias `ge` to end-of-file. Replace native mappings only as part of a complete family.
|
||||
|
||||
Provide operator-pending and visual Treesitter objects: `if/af` function, `ic/ac` class/type, `ia/aa` parameter, `ii/ai` conditional, `il/al` loop, `ib/ab` block. Retain `ci<object>` grammar and make structural bracket movements repeatable.
|
||||
|
||||
Context-local mappings:
|
||||
|
||||
- SQL: `,r` execute query/selection, `,s` save query, `,p` edit bind parameters.
|
||||
- HTTP: `,r` execute request at cursor, `,a` execute file, `,e` select environment.
|
||||
- Dadbod drawer/output: keep normal motions and `<CR>`; describe local mutation/refresh actions instead of adding globals.
|
||||
|
||||
Configure Which-key with the `helix` preset and automatic normal, visual, select and operator-pending triggers. Enable its operator, motion, text-object, window, navigation, `g`, `z`, mark, register and spelling documentation. Define groups once without duplicating mappings. Use Telescope keymap, command and help pickers as the full-catalog fallback; do not remap single-key built-ins only to display them.
|
||||
|
||||
## Feature changes
|
||||
|
||||
### Editing, navigation and UI
|
||||
|
||||
- Stop configuring `mini.files`; add `pkgs.vimPlugins.oil-nvim`.
|
||||
- Remove `project.nvim`, `direnv.vim` and `mini.indentscope`.
|
||||
- Start Treesitter once on `FileType` for normal file buffers. Configure text objects and rainbow delimiters explicitly.
|
||||
- Add `nvim-ts-autotag` for Svelte, Astro, HTML, JSX and TSX only.
|
||||
- Retain mini.ai/surround/pairs/icons and indentation detection. Benchmark `mini.hipatterns`; retain hex/TODO highlighting only if it adds no measurable scrolling cost.
|
||||
- Configure Grug-far as the only project-wide text/regex replacement interface. Open it with the cursor word or visual selection when available and retain its editable-buffer workflow.
|
||||
- Reduce Gitsigns to signs, hunk navigation and preview.
|
||||
- Keep Kanagawa Wave and colorful semantic completion. Use opaque surfaces and one border style for popups.
|
||||
- Use absolute line numbers, no tabline and markers only for tabs, trailing spaces and non-breaking spaces.
|
||||
- Use one global statusline containing mode, branch, filename, diagnostics, filetype, location and a truncated Navic breadcrumb when available. Remove diff/LSP-status duplication and all winbars.
|
||||
|
||||
### LSP, completion and formatting
|
||||
|
||||
- Remove the Dafny package/server. Keep current servers for retained languages.
|
||||
- Add `yaml-language-server` (`yamlls`) and `SchemaStore.nvim` for schema-aware YAML and JSON completion and validation. Disable LSP formatting in favor of Conform.
|
||||
- Remove `oxfmt` as an LSP; invoke Conform's `oxfmt` CLI formatter.
|
||||
- Remove `typst-preview.nvim`, `websocat` and their `nix-info` settings. Invoke the locked Tinymist server's preview commands.
|
||||
- Enable supported inlay hints by default with one toggle. Retain semantic tokens unless profiling identifies them as a bottleneck.
|
||||
- Show diagnostics through signs, underlines and severity sorting. Remove virtual lines; use `gl` for text.
|
||||
- Install one buffer-local document-highlight autocmd set on attach; remove it on detach without affecting other buffers.
|
||||
- Ensure every Telescope-backed LSP action and `telescope-ui-select` works on first invocation.
|
||||
- Retain Blink, colorful-menu and friendly-snippets with `<C-j>/<C-k>` selection. Use Blink's native `vim.snippet` support and convert the custom Nix snippets to VS Code JSON; remove LuaSnip.
|
||||
- Define one Conform pipeline per filetype. Prefer packaged CLIs; use LSP formatting only as an explicit fallback. Run one Ruff fix plus Ruff format for Python and one Oxfmt pass for supported web files.
|
||||
- Keep format-on-save synchronous with a finite timeout; keep manual formatting asynchronous.
|
||||
|
||||
### Databases and HTTP
|
||||
|
||||
- Add `vim-dadbod`, `vim-dadbod-ui`, `vim-dadbod-completion` and `blink-compat`; load them on database commands/filetypes only.
|
||||
- Add wrapper-local `postgresql`, `mariadb` and `mongosh`. PostgreSQL is primary; retain MySQL and MongoDB adapters.
|
||||
- Integrate relational SQL completion into Blink through `blink.compat`; do not enable it for MongoDB.
|
||||
- Expose schemas, tables, views, constraints/index helpers, saved queries, results and relational foreign-key jumps.
|
||||
- Use `DATABASE_URL` as the default project connection when set. Never store credentials in Nix or committed files. Store ad-hoc saved queries under XDG data; keep schema/migration SQL in projects.
|
||||
- Treat MongoDB as collection/document exploration, not relational navigation.
|
||||
- Move Kulala from `ui.lua` to `http.lua`; load it on `http`/`rest` files and explicit commands only. Disable its global mappings.
|
||||
- Add wrapper-local `kulala-core`, `kulala-fmt`, `curl`, `jq` and `openssl`. Pass the packaged core path through `nix-info`; disable backend downloads.
|
||||
- Use the Nix-provided `http` Treesitter grammar; disable Kulala parser downloads/builds.
|
||||
- Use JetBrains-compatible `.http` files. Commit non-secret `http-client.env.json`; keep credentials in ignored `http-client.private.env.json` or shell/direnv variables.
|
||||
- Support conversion with `kulala-fmt convert --from openapi --to http -o <output> <spec>`. Add no editor wrapper until repeated use justifies it.
|
||||
|
||||
### Notes
|
||||
|
||||
- Add wrapper-local `zk` and `zk-nvim` with Telescope as its picker. Let `zk-nvim` start `zk lsp` only for Markdown buffers inside a notebook; do not also configure `zk` through `nvim-lspconfig`.
|
||||
- Set `ZK_NOTEBOOK_DIR` to `~/sync/notes`. Global capture and discovery always target this notebook; new notes use its existing filename and template rules and never prompt for a directory.
|
||||
- Use the standard LSP mappings to follow links, find backlinks and preview linked notes. Add only the three global mappings and notebook-local insert-link mapping defined above.
|
||||
|
||||
### Nix integration
|
||||
|
||||
Keep the wrapper self-contained; do not rely on login-shell packages. Align Nix groups with the Lua structure and delete unused declarations. After validation, change `host-base.nix` to `primary-editor-neovim` and remove its Helix cache import; retain the optional Helix capability.
|
||||
|
||||
## Performance and reliability
|
||||
|
||||
1. Before refactoring, build the current wrapper without switching the running system. Record median headless startup time over repeated runs. Profile scrolling in representative large Nix, TypeScript/Svelte, Rust and Python buffers with LSP attached.
|
||||
2. Remove known hot-path duplication: repeated Treesitter starts, winbar evaluation, virtual-line layout changes, unused visual scanners, the formatter-only LSP and the separate Typst preview process layer.
|
||||
3. Re-profile after editing/navigation, LSP and UI changes. Add no size thresholds, caches, debounce wrappers or feature cutoffs without a measured problem.
|
||||
4. Keep inlay hints, semantic tokens and required servers unless measurements identify a specific offender.
|
||||
5. Temporary files, non-file buffers, inaccessible parent directories and files outside Git repositories must not change cwd or emit configuration errors.
|
||||
|
||||
## Verification and completion
|
||||
|
||||
- Run `nix fmt`, `nix flake check --no-build` and no-switch builds for `zenith`, `polaris` and `orion`.
|
||||
- Run the built wrapper headlessly with no arguments and with Nix, TypeScript, JavaScript, Svelte, Rust and Python files. Run `:checkhealth`; resolve errors from configured providers instead of suppressing them.
|
||||
- In fresh processes, test every semantic mapping, code action before any other Telescope command, Trouble promotion, Oil directory handling, Grug-far replacement, YAML/JSON schemas, automatic tag handling, central note capture/discovery, native Tinymist preview, SQL completion/query actions and Kulala request/environment actions.
|
||||
- Open a temporary prompt file outside a project and confirm no workspace, cwd or access error.
|
||||
- With disposable data, test Oil multi-create/rename/move/copy/delete, Dadbod against PostgreSQL, MySQL/MongoDB client and adapter loading, a local Kulala request and a small OpenAPI conversion.
|
||||
- Repeat startup and attached-LSP scrolling measurements; report before/after results and any remaining bottleneck.
|
||||
- Apply the governing Helix principles throughout, not only at final review. Completion requires no duplicate mapping/setup, misplaced capability, lazy plugin that fails on first action or retained code without a current purpose.
|
||||
Reference in new issue
Block a user