From 883f9d26c2113de9ab6424c953f42e088e907523 Mon Sep 17 00:00:00 2001 From: Jelle Spreeuwenberg Date: Fri, 4 Sep 2026 19:49:42 +0200 Subject: [PATCH] neovim refactor --- PLAN.md | 190 +++++++++++ .../capabilities/neovim/_kanagawa-theme.nix | 56 ---- modules/capabilities/neovim/default.nix | 185 +++++++---- .../capabilities/neovim/lua-config/init.lua | 11 +- .../neovim/lua-config/lua/autocmds.lua | 7 + .../neovim/lua-config/lua/keymaps.lua | 23 ++ .../neovim/lua-config/lua/options.lua | 71 +--- .../lua-config/lua/plugins/completion.lua | 87 ++--- .../neovim/lua-config/lua/plugins/core.lua | 57 ---- .../lua-config/lua/plugins/database.lua | 95 ++++++ .../lua-config/lua/plugins/diagnostics.lua | 34 ++ .../neovim/lua-config/lua/plugins/editing.lua | 141 ++++++++ .../lua-config/lua/plugins/formatting.lua | 66 ++-- .../neovim/lua-config/lua/plugins/http.lua | 62 ++++ .../neovim/lua-config/lua/plugins/lsp.lua | 310 ++++++------------ .../lua-config/lua/plugins/navigation.lua | 131 ++++++++ .../neovim/lua-config/lua/plugins/notes.lua | 53 +++ .../lua-config/lua/plugins/telescope.lua | 111 ------- .../lua-config/lua/plugins/treesitter.lua | 28 -- .../neovim/lua-config/lua/plugins/ui.lua | 149 +++------ .../neovim/lua-config/lua/project.lua | 7 + .../neovim/lua-config/snippets/nix.json | 55 ++++ .../neovim/lua-config/snippets/nix.lua | 91 ----- .../neovim/lua-config/snippets/package.json | 11 + modules/profiles/host-base.nix | 3 +- 25 files changed, 1154 insertions(+), 880 deletions(-) create mode 100644 PLAN.md delete mode 100644 modules/capabilities/neovim/_kanagawa-theme.nix create mode 100644 modules/capabilities/neovim/lua-config/lua/autocmds.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/keymaps.lua delete mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/core.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/database.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/diagnostics.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/editing.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/http.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/navigation.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/notes.lua delete mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/telescope.lua delete mode 100644 modules/capabilities/neovim/lua-config/lua/plugins/treesitter.lua create mode 100644 modules/capabilities/neovim/lua-config/lua/project.lua create mode 100644 modules/capabilities/neovim/lua-config/snippets/nix.json delete mode 100644 modules/capabilities/neovim/lua-config/snippets/nix.lua create mode 100644 modules/capabilities/neovim/lua-config/snippets/package.json diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..6f5cc5f --- /dev/null +++ b/PLAN.md @@ -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. `e` opens the current file's directory. Keep filesystem-change confirmation. + +## Keymap and discovery contract + +Set `` to space and `` 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. +- `s…`: Telescope project files/grep, cursor word, current buffer, recent files, workspace symbols, diagnostics, help, commands, keymaps and resume. +- `c…`: `ca` code action, `cr` rename, `cf` format, `cR` project-wide replacement. Remove displaced `gr*` LSP mappings. +- `d…`: persistent workspace/buffer diagnostics. Remove `x…` Trouble and location-list diagnostic mappings. +- `b…`: buffer picker/delete. Remove the duplicate `` picker. +- `q…`: database workspace; `qo` toggles Dadbod UI. +- `r…`: global HTTP facilities, including the scratchpad. +- `n…`: central notes; `nn` captures, `nf` finds notes and `nt` finds tags. Inside a `zk` note, `ni` inserts a link. +- `u…`: UI toggles only. +- `gl`: diagnostic details; ``: window focus; ``: 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` 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 ``; 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 `/` 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 `. 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. diff --git a/modules/capabilities/neovim/_kanagawa-theme.nix b/modules/capabilities/neovim/_kanagawa-theme.nix deleted file mode 100644 index 6cbcc7a..0000000 --- a/modules/capabilities/neovim/_kanagawa-theme.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ themeName }: -'' - require("kanagawa").setup({ - dimInactive = true, - colors = { - theme = { - all = { - ui = { - bg_gutter = "none" - } - } - } - }, - - overrides = function(colors) - local theme = colors.theme - - local makeDiagnosticColor = function(color) - local c = require("kanagawa.lib.color") - return { fg = color, bg = c(color):blend(theme.ui.bg, 0.95):to_hex() } - end - - return { - TelescopeTitle = { fg = theme.ui.special, bold = true }, - TelescopePromptNormal = { bg = theme.ui.bg_p1 }, - TelescopePromptBorder = { fg = theme.ui.bg_p1, bg = theme.ui.bg_p1 }, - TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 }, - TelescopeResultsBorder = { fg = theme.ui.bg_m1, bg = theme.ui.bg_m1 }, - TelescopePreviewNormal = { bg = theme.ui.bg_dim }, - TelescopePreviewBorder = { bg = theme.ui.bg_dim, fg = theme.ui.bg_dim }, - - Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1 }, -- add `blend = vim.o.pumblend` to enable transparency - PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 }, - PmenuSbar = { bg = theme.ui.bg_m1 }, - PmenuThumb = { bg = theme.ui.bg_p2 }, - - DiagnosticVirtualTextHint = makeDiagnosticColor(theme.diag.hint), - DiagnosticVirtualTextInfo = makeDiagnosticColor(theme.diag.info), - DiagnosticVirtualTextWarn = makeDiagnosticColor(theme.diag.warning), - DiagnosticVirtualTextError = makeDiagnosticColor(theme.diag.error), - - DiagnosticVirtualLinesHint = makeDiagnosticColor(theme.diag.hint), - DiagnosticVirtualLinesInfo = makeDiagnosticColor(theme.diag.info), - DiagnosticVirtualLinesWarn = makeDiagnosticColor(theme.diag.warning), - DiagnosticVirtualLinesError = makeDiagnosticColor(theme.diag.error), - - FloatBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.float.bg }, - NormalFloat = { fg = theme.ui.float.fg, bg = theme.ui.float.bg }, - WinBar = { fg = theme.ui.fg_dim, bg = "NONE" }, - WinBarNC = { fg = theme.ui.nontext, bg = theme.ui.bg_dim }, - } - end, - }) - - vim.cmd.colorscheme("${themeName}") -'' diff --git a/modules/capabilities/neovim/default.nix b/modules/capabilities/neovim/default.nix index 59f1300..3c2c59a 100644 --- a/modules/capabilities/neovim/default.nix +++ b/modules/capabilities/neovim/default.nix @@ -24,11 +24,33 @@ in hash = "sha256-RIAe30TTzZhHuXxC2VRVk/X73Qm1u2LWOW3AsnUfRzI="; }; }); - nvimTreesitterWithAllGrammars = nvimTreesitter.withPlugins ( - _: - map ( - grammar: if grammar == nvimTreesitter.builtGrammars.svelte then svelteGrammar else grammar - ) nvimTreesitter.allGrammars + nvimTreesitterWithGrammars = nvimTreesitter.withPlugins ( + grammars: with grammars; [ + astro + css + html + http + javascript + jsdoc + json + lua + markdown + markdown_inline + nix + python + query + regex + rust + sql + svelteGrammar + toml + tsx + typescript + typst + vim + vimdoc + yaml + ] ); in { @@ -41,118 +63,148 @@ in wrappers.neovim = { enable = true; - settings.config_directory = ./lua-config; runtimePkgs = with pkgs; [ ripgrep fd wl-clipboard + stylua + nixfmt + oxfmt taplo yamlfmt - lua-language-server - nixd - nixfmt - dafny - vscode-langservers-extracted - tailwindcss-language-server - rust-analyzer rustfmt - astro-language-server - tinymist typstyle - websocat - ty ruff + lua-language-server + nixd + vscode-langservers-extracted + yaml-language-server vtsls - oxlint - oxfmt - emmet-language-server svelteLanguageServer + tailwindcss-language-server + emmet-language-server + oxlint + rust-analyzer + astro-language-server + tinymist + ty + + postgresql + mariadb + mongosh + + kulala-core + kulala-fmt + curl + jq + openssl + + zk ]; specs = { - lz-n = { - data = pkgs.vimPlugins.lz-n; - }; + lz-n.data = pkgs.vimPlugins.lz-n; - support = { - data = with pkgs.vimPlugins; [ - plenary-nvim - kanagawa-nvim - nvimTreesitterWithAllGrammars - nvim-treesitter-textobjects - rainbow-delimiters-nvim - ]; - }; - - completion = { + editing = { lazy = true; data = with pkgs.vimPlugins; [ - blink-cmp - luasnip - friendly-snippets - colorful-menu-nvim + mini-nvim + guess-indent-nvim + nvimTreesitterWithGrammars + nvim-treesitter-textobjects + rainbow-delimiters-nvim + nvim-ts-autotag + grug-far-nvim ]; }; + navigation = { + lazy = true; + data = with pkgs.vimPlugins; [ + plenary-nvim + telescope-nvim + telescope-fzf-native-nvim + telescope-ui-select-nvim + { + data = oil-nvim; + lazy = false; + } + ]; + }; + + diagnostics = { + lazy = true; + data = with pkgs.vimPlugins; [ trouble-nvim ]; + }; + lsp = { lazy = true; data = with pkgs.vimPlugins; [ nvim-lspconfig lazydev-nvim nvim-navic - trouble-nvim - typst-preview-nvim + SchemaStore-nvim + ]; + }; + + completion = { + lazy = true; + data = with pkgs.vimPlugins; [ + blink-cmp + colorful-menu-nvim + friendly-snippets + { + data = blink-compat; + lazy = false; + } ]; }; formatting = { lazy = true; - data = with pkgs.vimPlugins; [ - conform-nvim - ]; - }; - - core = { - lazy = true; - data = with pkgs.vimPlugins; [ - mini-nvim - guess-indent-nvim - direnv-vim - ]; + data = with pkgs.vimPlugins; [ conform-nvim ]; }; ui = { lazy = true; data = with pkgs.vimPlugins; [ + { + data = kanagawa-nvim; + lazy = false; + } lualine-nvim gitsigns-nvim zen-mode-nvim which-key-nvim - kulala-nvim ]; }; - project = { + database = { lazy = true; data = with pkgs.vimPlugins; [ - project-nvim + vim-dadbod + vim-dadbod-completion + vim-dadbod-ui ]; }; - telescope = { + http = { lazy = true; - data = with pkgs.vimPlugins; [ - telescope-nvim - telescope-fzf-native-nvim - telescope-ui-select-nvim - ]; + data = with pkgs.vimPlugins; [ kulala-nvim ]; + }; + + notes = { + lazy = true; + data = with pkgs.vimPlugins; [ zk-nvim ]; }; }; + env.ZK_NOTEBOOK_DIR = "${config.home.homeDirectory}/sync/notes"; + settings = { nixdExtras = { nixpkgs = "import ${pkgs.path} {}"; @@ -160,18 +212,9 @@ in home_manager_options = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options.home-manager.users.type.getSubOptions []''; }; - themeSetup = import ./_kanagawa-theme.nix { - themeName = "kanagawa-wave"; - }; - - typstPreviewDependencies = { - tinymist = "${pkgs.tinymist}/bin/tinymist"; - websocat = "${pkgs.websocat}/bin/websocat"; - }; + kulalaCorePath = "${pkgs.kulala-core}/bin/kulala-core"; }; - hosts.python3.nvim-host.enable = true; - hosts.node.nvim-host.enable = true; binName = "nvim"; }; }; diff --git a/modules/capabilities/neovim/lua-config/init.lua b/modules/capabilities/neovim/lua-config/init.lua index 58946c4..0b2e59d 100644 --- a/modules/capabilities/neovim/lua-config/init.lua +++ b/modules/capabilities/neovim/lua-config/init.lua @@ -1,8 +1,13 @@ require("options") +require("keymaps") +require("autocmds") +require("plugins.editing") +require("plugins.navigation") +require("plugins.diagnostics") require("plugins.lsp") require("plugins.completion") require("plugins.formatting") -require("plugins.treesitter") -require("plugins.telescope") require("plugins.ui") -require("plugins.core") +require("plugins.database") +require("plugins.http") +require("plugins.notes") diff --git a/modules/capabilities/neovim/lua-config/lua/autocmds.lua b/modules/capabilities/neovim/lua-config/lua/autocmds.lua new file mode 100644 index 0000000..a5f9900 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/autocmds.lua @@ -0,0 +1,7 @@ +vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Highlight yanked text", + group = vim.api.nvim_create_augroup("lux-highlight-yank", { clear = true }), + callback = function() + vim.hl.on_yank() + end, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/keymaps.lua b/modules/capabilities/neovim/lua-config/lua/keymaps.lua new file mode 100644 index 0000000..bbdecde --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/keymaps.lua @@ -0,0 +1,23 @@ +vim.g.mapleader = " " +vim.g.maplocalleader = "," + +for _, lhs in ipairs({ "grn", "gra", "grx", "grr", "gri", "grt", "gO" }) do + vim.keymap.del("n", lhs) +end +vim.keymap.del("x", "gra") +vim.keymap.del("i", "") +vim.keymap.del("s", "") + +vim.keymap.set("n", "", "", { desc = "Focus left window" }) +vim.keymap.set("n", "", "", { desc = "Focus lower window" }) +vim.keymap.set("n", "", "", { desc = "Focus upper window" }) +vim.keymap.set("n", "", "", { desc = "Focus right window" }) +vim.keymap.set("n", "gl", vim.diagnostic.open_float, { desc = "Show diagnostic details" }) +vim.keymap.set("t", "", "", { desc = "Leave terminal mode" }) +vim.keymap.set("n", "bd", "bdelete", { desc = "Delete current buffer" }) +vim.keymap.set("n", "[d", function() + vim.diagnostic.jump({ count = -1 }) +end, { desc = "Previous diagnostic" }) +vim.keymap.set("n", "]d", function() + vim.diagnostic.jump({ count = 1 }) +end, { desc = "Next diagnostic" }) diff --git a/modules/capabilities/neovim/lua-config/lua/options.lua b/modules/capabilities/neovim/lua-config/lua/options.lua index c593e3c..08ad92c 100644 --- a/modules/capabilities/neovim/lua-config/lua/options.lua +++ b/modules/capabilities/neovim/lua-config/lua/options.lua @@ -1,76 +1,31 @@ -vim.g.mapleader = " " -vim.g.maplocalleader = " " - vim.o.expandtab = true vim.o.shiftwidth = 2 vim.o.tabstop = 2 vim.o.softtabstop = 2 vim.o.number = true --- vim.o.relativenumber = true - -vim.o.mouse = "a" - vim.o.showmode = false vim.o.showtabline = 0 - -vim.opt.shortmess:append("Wc") - -vim.schedule(function() - vim.o.clipboard = "unnamedplus" -end) - -vim.o.breakindent = true - -vim.o.undofile = true - -vim.o.ignorecase = true -vim.o.smartcase = true - vim.o.signcolumn = "yes" +vim.o.cursorline = true +vim.o.scrolloff = 10 +vim.o.mouse = "a" +vim.o.clipboard = "unnamedplus" +vim.o.confirm = true +vim.o.timeoutlen = 300 vim.o.updatetime = 250 -vim.o.timeoutlen = 300 +vim.o.breakindent = true +vim.o.undofile = true +vim.o.ignorecase = true +vim.o.smartcase = true +vim.o.inccommand = "split" vim.o.splitright = true vim.o.splitbelow = true +vim.opt.shortmess:append("Wc") + vim.o.list = true vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } - -vim.o.inccommand = "split" - -vim.o.cursorline = true - -vim.o.scrolloff = 10 - -vim.o.confirm = true - -vim.keymap.set("n", "", "nohlsearch") - -vim.keymap.set("n", "q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" }) -vim.keymap.set("n", "bd", "bdelete", { desc = "[B]uffer [D]elete" }) - -vim.keymap.set("t", "", "", { desc = "Exit terminal mode" }) - -vim.keymap.set("n", "", "", { desc = "Move focus to the left window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the right window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the lower window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the upper window" }) - -vim.keymap.set("n", "j", "gj", { silent = true }) -vim.keymap.set("n", "k", "gk", { silent = true }) - --- vim.keymap.set("n", "", "H", { desc = "Move window to the left" }) --- vim.keymap.set("n", "", "L", { desc = "Move window to the right" }) --- vim.keymap.set("n", "", "J", { desc = "Move window to the lower" }) --- vim.keymap.set("n", "", "K", { desc = "Move window to the upper" }) - -vim.api.nvim_create_autocmd("TextYankPost", { - desc = "Highlight when yanking (copying) text", - group = vim.api.nvim_create_augroup("lux-highlight-yank", { clear = true }), - callback = function() - vim.hl.on_yank() - end, -}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/completion.lua b/modules/capabilities/neovim/lua-config/lua/plugins/completion.lua index 6ed2db1..f7570e5 100644 --- a/modules/capabilities/neovim/lua-config/lua/plugins/completion.lua +++ b/modules/capabilities/neovim/lua-config/lua/plugins/completion.lua @@ -1,19 +1,7 @@ +require("blink.compat").setup({}) + require("lz.n").load({ - { - "friendly-snippets", - }, - { - "luasnip", - event = { "InsertEnter", "CmdlineEnter" }, - before = function() - require("lz.n").trigger_load("friendly-snippets") - end, - after = function() - require("luasnip.loaders.from_vscode").lazy_load() - -- Load custom lua snippets - require("luasnip.loaders.from_lua").load({ paths = { vim.fn.stdpath("config") .. "/snippets" } }) - end, - }, + { "friendly-snippets" }, { "colorful-menu.nvim", event = { "InsertEnter", "CmdlineEnter" }, @@ -24,41 +12,18 @@ require("lz.n").load({ { "blink.cmp", event = { "InsertEnter", "CmdlineEnter" }, - before = function() - -- Trigger lazydev so it's ready for blink source - require("lz.n").trigger_load({ "lazydev.nvim", "luasnip", "colorful-menu.nvim" }) - end, after = function() require("blink.cmp").setup({ keymap = { preset = "default", - - -- [Up/Down] [""] = { "select_next", "fallback" }, - [""] = { "select_prev", "fallback" }, -- Overrides Signature Help - - -- [Insert Suggestion] - [""] = { "select_and_accept", "fallback" }, - - -- [Remap Signature Help] - -- Since we took , let's move signature help to (optional) + [""] = { "select_prev", "fallback" }, + [""] = { "select_and_accept", "fallback" }, [""] = { "show_signature", "hide_signature", "fallback" }, }, - - appearance = { - nerd_font_variant = "mono", - }, - completion = { - documentation = { - auto_show = true, - auto_show_delay_ms = 500, - window = { - border = "none", - }, - }, + documentation = { auto_show = true }, menu = { - border = "none", draw = { columns = { { "kind_icon" }, { "label", gap = 1 } }, components = { @@ -74,38 +39,30 @@ require("lz.n").load({ }, }, }, - cmdline = { - completion = { - menu = { - auto_show = true, - }, - }, + completion = { menu = { auto_show = true } }, keymap = { preset = "inherit" }, }, - sources = { - default = { - "lsp", - "path", - "snippets", - "lazydev", + default = { "lsp", "path", "snippets" }, + per_filetype = { + lua = { inherit_defaults = true, "lazydev" }, + sql = { inherit_defaults = true, "vim-dadbod-completion" }, + mysql = { inherit_defaults = true, "vim-dadbod-completion" }, + plsql = { inherit_defaults = true, "vim-dadbod-completion" }, }, providers = { - lazydev = { module = "lazydev.integrations.blink", score_offset = 100 }, - }, - }, - - snippets = { preset = "luasnip" }, - - fuzzy = { implementation = "prefer_rust_with_warning" }, - - signature = { - enabled = true, - window = { - border = "none", + lazydev = { + module = "lazydev.integrations.blink", + score_offset = 100, + }, + ["vim-dadbod-completion"] = { + name = "vim-dadbod-completion", + module = "blink.compat.source", + }, }, }, + signature = { enabled = true }, }) end, }, diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/core.lua b/modules/capabilities/neovim/lua-config/lua/plugins/core.lua deleted file mode 100644 index 1449537..0000000 --- a/modules/capabilities/neovim/lua-config/lua/plugins/core.lua +++ /dev/null @@ -1,57 +0,0 @@ -require("lz.n").load({ - { - "mini.nvim", - event = { "BufReadPre", "BufNewFile" }, - after = function() - require("mini.ai").setup({ n_lines = 500 }) - require("mini.surround").setup() - require("mini.pairs").setup() - - local files = require("mini.files") - files.setup() - vim.keymap.set("n", "e", function() - if not files.close() then - files.open(vim.api.nvim_buf_get_name(0)) - end - end, { desc = "File [E]xplorer" }) - - local icons = require("mini.icons") - icons.setup() - icons.mock_nvim_web_devicons() - - local hipatterns = require("mini.hipatterns") - hipatterns.setup({ - highlighters = { - hex_color = hipatterns.gen_highlighter.hex_color(), - fixme = { pattern = "%f[%w]()FIXME()%f[%W]", group = "MiniHipatternsFixme" }, - hack = { pattern = "%f[%w]()HACK()%f[%W]", group = "MiniHipatternsHack" }, - todo = { pattern = "%f[%w]()TODO()%f[%W]", group = "MiniHipatternsTodo" }, - note = { pattern = "%f[%w]()NOTE()%f[%W]", group = "MiniHipatternsNote" }, - }, - }) - - local indentscope = require("mini.indentscope") - indentscope.setup({ - symbol = "│", - }) - - vim.api.nvim_create_autocmd("FileType", { - pattern = { "help", "Trouble" }, - callback = function() - vim.b.miniindentscope_disable = true - end, - }) - end, - }, - { - "guess-indent.nvim", - event = { "BufReadPre", "BufNewFile" }, - after = function() - require("guess-indent").setup({}) - end, - }, - { - "direnv.vim", - event = "BufEnter", - }, -}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/database.lua b/modules/capabilities/neovim/lua-config/lua/plugins/database.lua new file mode 100644 index 0000000..8a65414 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/database.lua @@ -0,0 +1,95 @@ +local commands = { + "DBUI", + "DBUIToggle", + "DBUIAddConnection", + "DBUIFindBuffer", + "DBUIRenameBuffer", + "DBUILastQueryInfo", +} +local filetypes = { "sql", "mysql", "plsql" } + +require("lz.n").load({ + { "vim-dadbod" }, + { "vim-dadbod-completion", ft = filetypes }, + { + "vim-dadbod-ui", + cmd = commands, + ft = filetypes, + keys = { + { "qo", "DBUIToggle", desc = "Toggle database workspace" }, + { + "r", + "(DBUI_ExecuteQuery)", + mode = { "n", "x" }, + ft = filetypes, + remap = true, + desc = "Execute database query", + }, + { + "s", + "(DBUI_SaveQuery)", + ft = filetypes, + remap = true, + desc = "Save database query", + }, + { + "p", + "(DBUI_EditBindParameters)", + ft = filetypes, + remap = true, + desc = "Edit query parameters", + }, + { "", "(DBUI_SelectLine)", ft = "dbui", remap = true, desc = "Open database item" }, + { + "a", + "(DBUI_AddConnection)", + ft = "dbui", + remap = true, + desc = "Add database connection", + }, + { + "d", + "(DBUI_DeleteLine)", + ft = "dbui", + remap = true, + desc = "Delete database item", + }, + { + "n", + "(DBUI_RenameLine)", + ft = "dbui", + remap = true, + desc = "Rename database item", + }, + { + "r", + "(DBUI_Redraw)", + ft = "dbui", + remap = true, + desc = "Refresh database workspace", + }, + { + "f", + "(DBUI_JumpToForeignKey)", + ft = "dbout", + remap = true, + desc = "Follow foreign key", + }, + { + "l", + "(DBUI_ToggleResultLayout)", + ft = "dbout", + remap = true, + desc = "Toggle result layout", + }, + }, + before = function() + vim.g.db_ui_execute_on_save = 0 + vim.g.db_ui_disable_mappings = 1 + vim.g.db_ui_show_help = 0 + if vim.env.DATABASE_URL and vim.env.DATABASE_URL ~= "" then + vim.g.db = vim.env.DATABASE_URL + end + end, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/diagnostics.lua b/modules/capabilities/neovim/lua-config/lua/plugins/diagnostics.lua new file mode 100644 index 0000000..e9cafc5 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/diagnostics.lua @@ -0,0 +1,34 @@ +vim.diagnostic.config({ + signs = { + text = { + [vim.diagnostic.severity.ERROR] = " ", + [vim.diagnostic.severity.WARN] = " ", + [vim.diagnostic.severity.INFO] = " ", + [vim.diagnostic.severity.HINT] = "󰠠 ", + }, + }, + severity_sort = true, + float = { source = "if_many" }, +}) + +require("lz.n").load({ + { + "trouble.nvim", + cmd = "Trouble", + keys = { + { + "dd", + "Trouble diagnostics toggle", + desc = "Show workspace diagnostics", + }, + { + "db", + "Trouble diagnostics toggle filter.buf=0", + desc = "Show buffer diagnostics", + }, + }, + after = function() + require("trouble").setup({}) + end, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/editing.lua b/modules/capabilities/neovim/lua-config/lua/plugins/editing.lua new file mode 100644 index 0000000..9a5b45f --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/editing.lua @@ -0,0 +1,141 @@ +require("lz.n").load({ + { + "mini.nvim", + event = "VimEnter", + after = function() + require("mini.ai").setup({ n_lines = 500 }) + require("mini.surround").setup() + require("mini.pairs").setup() + + local icons = require("mini.icons") + icons.setup() + icons.mock_nvim_web_devicons() + end, + }, + { + "guess-indent.nvim", + event = { "BufReadPre", "BufNewFile" }, + after = function() + require("guess-indent").setup({}) + end, + }, + { + "nvim-treesitter", + event = "FileType", + after = function() + require("nvim-treesitter").setup({}) + vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("lux-treesitter", { clear = true }), + callback = function(args) + if vim.bo[args.buf].buftype ~= "" then + return + end + + if pcall(vim.treesitter.start, args.buf) then + vim.bo[args.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + end + end, + }) + end, + }, + { + "nvim-treesitter-textobjects", + event = "FileType", + after = function() + require("nvim-treesitter-textobjects").setup({ + select = { lookahead = true }, + move = { set_jumps = true }, + }) + + local select = require("nvim-treesitter-textobjects.select") + local move = require("nvim-treesitter-textobjects.move") + local objects = { + { "if", "@function.inner", "Select inner function" }, + { "af", "@function.outer", "Select outer function" }, + { "ic", "@class.inner", "Select inner class" }, + { "ac", "@class.outer", "Select outer class" }, + { "ia", "@parameter.inner", "Select inner parameter" }, + { "aa", "@parameter.outer", "Select outer parameter" }, + { "ii", "@conditional.inner", "Select inner conditional" }, + { "ai", "@conditional.outer", "Select outer conditional" }, + { "il", "@loop.inner", "Select inner loop" }, + { "al", "@loop.outer", "Select outer loop" }, + { "ib", "@block.inner", "Select inner block" }, + { "ab", "@block.outer", "Select outer block" }, + } + + for _, object in ipairs(objects) do + vim.keymap.set({ "o", "x" }, object[1], function() + select.select_textobject(object[2], "textobjects") + end, { desc = object[3] }) + end + + local motions = { + { "[f", move.goto_previous_start, "@function.outer", "Previous function" }, + { "]f", move.goto_next_start, "@function.outer", "Next function" }, + { "[c", move.goto_previous_start, "@class.outer", "Previous class" }, + { "]c", move.goto_next_start, "@class.outer", "Next class" }, + { "[a", move.goto_previous_start, "@parameter.inner", "Previous parameter" }, + { "]a", move.goto_next_start, "@parameter.inner", "Next parameter" }, + } + + for _, motion in ipairs(motions) do + vim.keymap.set({ "n", "x", "o" }, motion[1], function() + motion[2](motion[3], "textobjects") + end, { desc = motion[4] }) + end + end, + }, + { + "rainbow-delimiters.nvim", + event = "FileType", + after = function() + require("rainbow-delimiters.setup").setup({}) + end, + }, + { + "nvim-ts-autotag", + ft = { "svelte", "astro", "html", "javascriptreact", "typescriptreact" }, + after = function() + local enabled = { enable_close = true, enable_rename = true } + require("nvim-ts-autotag").setup({ + opts = { enable_close = false, enable_rename = false }, + per_filetype = { + svelte = enabled, + astro = enabled, + html = enabled, + javascriptreact = enabled, + typescriptreact = enabled, + }, + }) + end, + }, + { + "grug-far.nvim", + cmd = "GrugFar", + keys = { + { + "cR", + function() + require("grug-far").open({ + prefills = { + search = vim.fn.expand(""), + paths = require("project").root(), + }, + }) + end, + desc = "Replace across project", + }, + { + "cR", + function() + require("grug-far").with_visual_selection({ + prefills = { paths = require("project").root() }, + }) + end, + mode = "x", + desc = "Replace selection across project", + }, + }, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/formatting.lua b/modules/capabilities/neovim/lua-config/lua/plugins/formatting.lua index c5bbe11..7e85aa7 100644 --- a/modules/capabilities/neovim/lua-config/lua/plugins/formatting.lua +++ b/modules/capabilities/neovim/lua-config/lua/plugins/formatting.lua @@ -1,15 +1,22 @@ -local function format_options(bufnr) - local oxfmt = vim.lsp.get_clients({ - bufnr = bufnr, - name = "oxfmt", - method = "textDocument/formatting", - })[1] - - return { - lsp_format = "fallback", - name = oxfmt and "oxfmt" or nil, - } -end +local formatters_by_ft = { + lua = { "stylua" }, + nix = { "nixfmt" }, + javascript = { "oxfmt" }, + javascriptreact = { "oxfmt" }, + typescript = { "oxfmt" }, + typescriptreact = { "oxfmt" }, + json = { "oxfmt" }, + jsonc = { "oxfmt" }, + css = { "oxfmt" }, + html = { "oxfmt" }, + svelte = { "oxfmt" }, + astro = { lsp_format = "fallback" }, + python = { "ruff_fix", "ruff_format" }, + rust = { "rustfmt" }, + toml = { "taplo" }, + yaml = { "yamlfmt" }, + typst = { "typstyle" }, +} require("lz.n").load({ { @@ -18,40 +25,23 @@ require("lz.n").load({ cmd = "ConformInfo", keys = { { - "f", + "cf", function() - local options = format_options(vim.api.nvim_get_current_buf()) - options.async = true - require("conform").format(options) + require("conform").format({ async = true }) end, - mode = "", - desc = "[F]ormat buffer", + mode = { "n", "x" }, + desc = "Format selection or buffer", }, }, after = function() - require("conform").setup({ - notify_on_error = true, + local conform = require("conform") + conform.setup({ + formatters_by_ft = formatters_by_ft, format_on_save = function(bufnr) - local disable_filetypes = { c = true, cpp = true } - if disable_filetypes[vim.bo[bufnr].filetype] then - return nil - else - local options = format_options(bufnr) - options.timeout_ms = 500 - return options + if formatters_by_ft[vim.bo[bufnr].filetype] then + return { timeout_ms = 500 } end end, - formatters_by_ft = { - lua = { "stylua" }, - python = { "ruff_fix", "ruff_format", "ruff_organize_imports" }, - toml = { "taplo" }, - yaml = { "yamlfmt" }, - }, - formatters = { - stylua = { - prepend_args = { "--indent-type", "Spaces", "--indent-width", "2" }, - }, - }, }) end, }, diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/http.lua b/modules/capabilities/neovim/lua-config/lua/plugins/http.lua new file mode 100644 index 0000000..62fa977 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/http.lua @@ -0,0 +1,62 @@ +require("lz.n").load({ + { + "kulala.nvim", + ft = { "http", "rest" }, + keys = { + { + "r", + function() + require("kulala").run() + end, + mode = { "n", "x" }, + ft = { "http", "rest" }, + desc = "Execute HTTP request", + }, + { + "a", + function() + require("kulala").run_all() + end, + ft = { "http", "rest" }, + desc = "Execute all HTTP requests", + }, + { + "e", + function() + require("kulala").set_selected_env() + end, + ft = { "http", "rest" }, + desc = "Select HTTP environment", + }, + { + "rr", + function() + require("kulala").scratchpad() + end, + desc = "Open HTTP scratchpad", + }, + { + "rc", + function() + require("kulala").from_curl() + end, + desc = "Import cURL request", + }, + { + "ro", + function() + require("kulala").open() + end, + desc = "Open HTTP request", + }, + }, + after = function() + require("kulala").setup({ + kulala_core = { path = require("nix-info").settings.kulalaCorePath }, + treesitter = { enable = false }, + session = { restore = false }, + ui = { winbar = false }, + }) + end, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/lsp.lua b/modules/capabilities/neovim/lua-config/lua/plugins/lsp.lua index e81e55c..fcd21a6 100644 --- a/modules/capabilities/neovim/lua-config/lua/plugins/lsp.lua +++ b/modules/capabilities/neovim/lua-config/lua/plugins/lsp.lua @@ -1,20 +1,8 @@ require("lz.n").load({ - { - "typst-preview.nvim", - ft = "typst", - after = function() - -- Setup typst-preview - require("typst-preview").setup({ - -- Optionally configure things here - dependencies_bin = require("nix-info").settings.typstPreviewDependencies, - }) - - vim.keymap.set("n", "tp", "TypstPreviewToggle", { desc = "[T]ypst [P]review Toggle" }) - end, - }, + { "nvim-navic" }, + { "SchemaStore.nvim" }, { "lazydev.nvim", - cmd = "LazyDev", ft = "lua", after = function() require("lazydev").setup({ @@ -27,163 +15,92 @@ require("lz.n").load({ { "nvim-lspconfig", event = { "BufReadPre", "BufNewFile" }, - before = function() - require("lz.n").trigger_load("lazydev.nvim") - end, after = function() - local telescope_plugins = { - "project.nvim", - "telescope.nvim", - "telescope-fzf-native.nvim", - "telescope-ui-select.nvim", - } - - local telescope_picker = function(picker) - return function() - require("lz.n").trigger_load(telescope_plugins) - require("telescope.builtin")[picker]() - end - end - - local lsp_float = { border = "single" } - - local navic_excluded_filetypes = { - [""] = true, - help = true, - minifiles = true, - TelescopePrompt = true, - Trouble = true, - } - - local function navic_enabled(bufnr) - return vim.bo[bufnr].buftype == "" and not navic_excluded_filetypes[vim.bo[bufnr].filetype] - end - - _G.lux_navic_location = function() - local ok, navic = pcall(require, "nvim-navic") - if not ok or not navic.is_available() then - return "" - end - - return navic.get_location() - end - - local function update_winbar(winid, bufnr) - if not vim.api.nvim_win_is_valid(winid) then - return - end - - local is_float = vim.api.nvim_win_get_config(winid).relative ~= "" - local winbar = "" - if not is_float and vim.b[bufnr].lux_navic_attached and navic_enabled(bufnr) then - winbar = "%{%v:lua.lux_navic_location()%}" - end - - vim.api.nvim_set_option_value("winbar", winbar, { win = winid }) - end - - local function update_winbars_for_buffer(bufnr) - for _, winid in ipairs(vim.fn.win_findbuf(bufnr)) do - update_winbar(winid, bufnr) - end - end - - vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "WinEnter" }, { - group = vim.api.nvim_create_augroup("lux-navic-winbar", { clear = true }), - callback = function(args) - update_winbar(vim.api.nvim_get_current_win(), args.buf) - end, - }) + local attach_group = vim.api.nvim_create_augroup("lux-lsp-attach", { clear = true }) + local detach_group = vim.api.nvim_create_augroup("lux-lsp-detach", { clear = true }) + local highlight_group = vim.api.nvim_create_augroup("lux-lsp-highlight", { clear = true }) vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("lux-lsp-attach", { clear = true }), + group = attach_group, callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) + local client = assert(vim.lsp.get_client_by_id(args.data.client_id)) local bufnr = args.buf - - local map = function(keys, func, desc, mode) - mode = mode or "n" - vim.keymap.set(mode, keys, func, { buffer = bufnr, desc = "LSP: " .. desc }) + local map = function(mode, lhs, rhs, desc) + vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc }) end - map("rn", vim.lsp.buf.rename, "[R]e[n]ame") - map("ca", vim.lsp.buf.code_action, "[C]ode [A]ction", { "n", "x" }) - map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") - map("K", function() - vim.lsp.buf.hover(lsp_float) - end, "Hover Documentation") - map("", function() - vim.lsp.buf.signature_help(lsp_float) - end, "Signature Help", { "i", "s" }) + map("n", "gd", function() + require("telescope.builtin").lsp_definitions() + end, "Go to definition") + map("n", "gD", vim.lsp.buf.declaration, "Go to declaration") + map("n", "gr", function() + require("telescope.builtin").lsp_references() + end, "Find references") + map("n", "gI", function() + require("telescope.builtin").lsp_implementations() + end, "Go to implementation") + map("n", "gy", function() + require("telescope.builtin").lsp_type_definitions() + end, "Go to type definition") + map("n", "gO", function() + require("telescope.builtin").lsp_document_symbols() + end, "Find document symbols") + map("n", "K", vim.lsp.buf.hover, "Show hover documentation") + map({ "n", "x" }, "ca", vim.lsp.buf.code_action, "Apply code action") + map("n", "cr", vim.lsp.buf.rename, "Rename symbol") - map("gd", telescope_picker("lsp_definitions"), "[G]oto [D]efinition") - map("gr", telescope_picker("lsp_references"), "[G]oto [R]eferences") - map("gI", telescope_picker("lsp_implementations"), "[G]oto [I]mplementation") - map("D", telescope_picker("lsp_type_definitions"), "Type [D]efinition") - map("ds", telescope_picker("lsp_document_symbols"), "[D]ocument [S]ymbols") - map("ws", telescope_picker("lsp_dynamic_workspace_symbols"), "[W]orkspace [S]ymbols") + if client:supports_method("textDocument/documentSymbol", bufnr) then + require("nvim-navic").attach(client, bufnr) + end - if client and client:supports_method("textDocument/documentSymbol", bufnr) and navic_enabled(bufnr) then - require("lz.n").trigger_load("nvim-navic") - local ok, navic = pcall(require, "nvim-navic") - if ok then - navic.attach(client, bufnr) - vim.b[bufnr].lux_navic_attached = true - update_winbars_for_buffer(bufnr) + if client:supports_method("textDocument/documentHighlight", bufnr) then + local autocmds = vim.api.nvim_get_autocmds({ group = highlight_group, buffer = bufnr }) + if #autocmds == 0 then + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + group = highlight_group, + buffer = bufnr, + callback = vim.lsp.buf.document_highlight, + }) + vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { + group = highlight_group, + buffer = bufnr, + callback = vim.lsp.buf.clear_references, + }) end end - if client and client:supports_method("textDocument/documentHighlight", bufnr) then - local highlight_augroup = vim.api.nvim_create_augroup("lux-lsp-highlight", { clear = false }) - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - buffer = bufnr, - group = highlight_augroup, - callback = vim.lsp.buf.document_highlight, - }) - - vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { - buffer = bufnr, - group = highlight_augroup, - callback = vim.lsp.buf.clear_references, - }) - - vim.api.nvim_create_autocmd("LspDetach", { - group = vim.api.nvim_create_augroup("lux-lsp-detach", { clear = true }), - callback = function(event) - vim.lsp.buf.clear_references() - vim.api.nvim_clear_autocmds({ group = "lux-lsp-highlight", buffer = event.buf }) - end, - }) + if client:supports_method("textDocument/inlayHint", bufnr) then + vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) + map("n", "uh", function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr }) + end, "Toggle inlay hints") end - if client and client:supports_method("textDocument/inlayHint", bufnr) then - vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) - map("th", function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr })) - end, "[T]oggle Inlay [H]ints") + if client.name == "tinymist" then + vim.api.nvim_buf_create_user_command(bufnr, "TinymistPreview", function() + client:exec_cmd({ command = "tinymist.startDefaultPreview" }, { bufnr = bufnr }) + end, { desc = "Start Tinymist preview", force = true }) end end, }) - vim.diagnostic.config({ - severity_sort = true, - underline = true, - signs = { - text = { - [vim.diagnostic.severity.ERROR] = " ", - [vim.diagnostic.severity.WARN] = " ", - [vim.diagnostic.severity.INFO] = " ", - [vim.diagnostic.severity.HINT] = "󰠠 ", - }, - }, - virtual_text = false, - virtual_lines = { - current_line = true, - }, - float = { - border = "single", - source = "if_many", - }, + vim.api.nvim_create_autocmd("LspDetach", { + group = detach_group, + callback = function(args) + local supports_highlights = vim + .iter(vim.lsp.get_clients({ + bufnr = args.buf, + method = "textDocument/documentHighlight", + })) + :any(function(client) + return client.id ~= args.data.client_id + end) + + if not supports_highlights then + vim.lsp.buf.clear_references() + vim.api.nvim_clear_autocmds({ group = highlight_group, buffer = args.buf }) + end + end, }) vim.lsp.config("lua_ls", { @@ -197,10 +114,8 @@ require("lz.n").load({ }, }, }) - vim.lsp.enable("lua_ls") local settings = require("nix-info").settings - vim.lsp.config("nixd", { settings = { nixd = { @@ -209,64 +124,53 @@ require("lz.n").load({ nixos = { expr = settings.nixdExtras.nixos_options }, ["home-manager"] = { expr = settings.nixdExtras.home_manager_options }, }, - formatting = { command = { "nixfmt" } }, }, }, }) - vim.lsp.enable("nixd") - vim.lsp.enable("dafny") - vim.lsp.enable("jsonls") + vim.lsp.config("jsonls", { + settings = { + json = { + schemas = require("schemastore").json.schemas(), + validate = { enable = true }, + format = { enable = false }, + }, + }, + }) + + vim.lsp.config("yamlls", { + settings = { + yaml = { + schemas = require("schemastore").yaml.schemas(), + schemaStore = { enable = false, url = "" }, + format = { enable = false }, + }, + }, + }) vim.lsp.config("vtsls", { settings = { - vtsls = { - autoUseWorkspaceTsdk = true, - }, + vtsls = { autoUseWorkspaceTsdk = true }, }, }) - vim.lsp.enable("vtsls") - vim.lsp.enable("cssls") - vim.lsp.enable("html") - vim.lsp.enable("emmet_language_server") - vim.lsp.enable("oxlint") - - vim.lsp.config("oxfmt", { - filetypes = vim.list_extend({ "svelte" }, vim.lsp.config.oxfmt.filetypes), - }) - vim.lsp.enable("oxfmt") - - vim.lsp.enable("tailwindcss") - vim.lsp.enable("rust_analyzer") - vim.lsp.enable("ty") - vim.lsp.enable("ruff") - vim.lsp.enable("astro") - vim.lsp.enable("svelte") - - vim.lsp.config("tinymist", { - settings = { - tinymist = { - formatterMode = "typstyle", - }, - }, - }) - vim.lsp.enable("tinymist") - end, - }, - { - "trouble.nvim", - cmd = "Trouble", - keys = { - { "xx", "Trouble diagnostics toggle", desc = "Diagnostics (Trouble)" }, - { "xX", "Trouble diagnostics toggle filter.buf=0", desc = "Buffer Diagnostics (Trouble)" }, - }, - after = function() - require("trouble").setup({ - focus = true, - preview = { - border = "single", - }, + vim.lsp.enable({ + "lua_ls", + "nixd", + "jsonls", + "yamlls", + "vtsls", + "cssls", + "html", + "emmet_language_server", + "oxlint", + "tailwindcss", + "rust_analyzer", + "ty", + "ruff", + "astro", + "svelte", + "tinymist", }) end, }, diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/navigation.lua b/modules/capabilities/neovim/lua-config/lua/plugins/navigation.lua new file mode 100644 index 0000000..ab85250 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/navigation.lua @@ -0,0 +1,131 @@ +require("oil").setup({}) +vim.keymap.set("n", "e", function() + local name = vim.api.nvim_buf_get_name(0) + require("oil").open(name == "" and vim.fn.getcwd() or vim.fs.dirname(name)) +end, { desc = "Open file directory" }) + +require("lz.n").load({ + { "plenary.nvim" }, + { "telescope-fzf-native.nvim" }, + { "telescope-ui-select.nvim" }, + { + "telescope.nvim", + event = "VimEnter", + keys = { + { + "sf", + function() + require("telescope.builtin").find_files({ cwd = require("project").root() }) + end, + desc = "Find project files", + }, + { + "sg", + function() + require("telescope.builtin").live_grep({ cwd = require("project").root() }) + end, + desc = "Search project text", + }, + { + "sw", + function() + require("telescope.builtin").grep_string({ cwd = require("project").root() }) + end, + desc = "Search cursor word", + }, + { + "sb", + function() + require("telescope.builtin").current_buffer_fuzzy_find() + end, + desc = "Search current buffer", + }, + { + "so", + function() + require("telescope.builtin").oldfiles() + end, + desc = "Find recent files", + }, + { + "ss", + function() + require("telescope.builtin").lsp_dynamic_workspace_symbols() + end, + desc = "Find workspace symbols", + }, + { + "sd", + function() + require("telescope.builtin").diagnostics() + end, + desc = "Find diagnostics", + }, + { + "sh", + function() + require("telescope.builtin").help_tags() + end, + desc = "Find help", + }, + { + "sc", + function() + require("telescope.builtin").commands() + end, + desc = "Find commands", + }, + { + "sk", + function() + require("telescope.builtin").keymaps() + end, + desc = "Find keymaps", + }, + { + "sr", + function() + require("telescope.builtin").resume() + end, + desc = "Resume last search", + }, + { + "bb", + function() + require("telescope.builtin").buffers() + end, + desc = "Find open buffers", + }, + }, + after = function() + local actions = require("telescope.actions") + local promote = function(prompt_bufnr) + actions.smart_send_to_qflist(prompt_bufnr) + vim.cmd("Trouble qflist open") + end + + require("telescope").setup({ + defaults = { + mappings = { + i = { + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + [""] = promote, + }, + n = { + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + [""] = promote, + }, + }, + }, + extensions = { + ["ui-select"] = require("telescope.themes").get_dropdown(), + }, + }) + + require("telescope").load_extension("fzf") + require("telescope").load_extension("ui-select") + end, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/notes.lua b/modules/capabilities/neovim/lua-config/lua/plugins/notes.lua new file mode 100644 index 0000000..9b64b6a --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/plugins/notes.lua @@ -0,0 +1,53 @@ +require("lz.n").load({ + { + "zk-nvim", + cmd = { "ZkNew", "ZkNotes", "ZkTags", "ZkInsertLink", "ZkBacklinks", "ZkLinks" }, + ft = "markdown", + keys = { + { + "nn", + function() + local title = vim.trim(vim.fn.input("Title: ")) + if title ~= "" then + require("zk").new({ notebook_path = vim.env.ZK_NOTEBOOK_DIR, title = title }) + end + end, + desc = "Create note", + }, + { + "nf", + function() + require("zk").edit({ notebook_path = vim.env.ZK_NOTEBOOK_DIR }, { picker = "telescope" }) + end, + desc = "Find notes", + }, + { + "nt", + function() + require("zk.commands").get("ZkTags")({ notebook_path = vim.env.ZK_NOTEBOOK_DIR }) + end, + desc = "Find note tags", + }, + }, + after = function() + require("zk").setup({ + picker = "telescope", + lsp = { config = { root_dir = vim.env.ZK_NOTEBOOK_DIR } }, + }) + + vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("lux-notes-maps", { clear = true }), + pattern = "markdown", + callback = function(args) + local path = vim.api.nvim_buf_get_name(args.buf) + if require("zk.util").notebook_root(path) then + vim.keymap.set("n", "ni", "ZkInsertLink", { + buffer = args.buf, + desc = "Insert note link", + }) + end + end, + }) + end, + }, +}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/telescope.lua b/modules/capabilities/neovim/lua-config/lua/plugins/telescope.lua deleted file mode 100644 index 185bd42..0000000 --- a/modules/capabilities/neovim/lua-config/lua/plugins/telescope.lua +++ /dev/null @@ -1,111 +0,0 @@ -local telescope_plugins = { - "project.nvim", - "telescope.nvim", - "telescope-fzf-native.nvim", - "telescope-ui-select.nvim", -} - -local function load_telescope() - require("lz.n").trigger_load(telescope_plugins) - return require("telescope.builtin") -end - -local function map_picker(lhs, picker, desc, opts) - vim.keymap.set("n", lhs, function() - load_telescope()[picker](opts or {}) - end, { desc = desc }) -end - -map_picker("sh", "help_tags", "[S]earch [H]elp") -map_picker("sk", "keymaps", "[S]earch [K]eymaps") -map_picker("sf", "find_files", "[S]earch [F]iles") -map_picker("ss", "builtin", "[S]earch [S]elect Telescope") -map_picker("sw", "grep_string", "[S]earch current [W]ord") -map_picker("sg", "live_grep", "[S]earch by [G]rep") -map_picker("sd", "diagnostics", "[S]earch [D]iagnostics") -map_picker("sr", "resume", "[S]earch [R]esume") -map_picker("s.", "oldfiles", '[S]earch Recent Files ("." for repeat)') -map_picker("", "buffers", "[ ] Find existing buffers") -map_picker("sn", "find_files", "[S]earch [N]eovim files", { cwd = vim.fn.stdpath("config") }) - -vim.keymap.set("n", "sp", function() - load_telescope() - require("telescope").extensions.projects.projects({}) -end, { desc = "[S]earch [P]rojects" }) - -vim.keymap.set("n", "/", function() - local builtin = load_telescope() - builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({ - winblend = 10, - previewer = false, - })) -end, { desc = "[/] Fuzzily search in current buffer" }) - -vim.keymap.set("n", "s/", function() - load_telescope().live_grep({ - grep_open_files = true, - prompt_title = "Live Grep in Open Files", - }) -end, { desc = "[S]earch [/] in Open Files" }) - -require("lz.n").load({ - { - "project.nvim", - event = "VimEnter", - after = function() - require("project").setup({ - manual_mode = false, - lsp = { enabled = true }, - patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "flake.nix" }, - show_hidden = true, - scope_chdir = "global", - }) - end, - }, - { - "telescope-fzf-native.nvim", - }, - { - "telescope-ui-select.nvim", - }, - { - "telescope.nvim", - cmd = "Telescope", - before = function() - require("lz.n").trigger_load("project.nvim") - end, - after = function() - local actions = require("telescope.actions") - - require("telescope").setup({ - defaults = { - path_display = { "truncate" }, - border = true, - borderchars = { "─", "│", "─", "│", "┌", "┐", "┘", "└" }, - layout_strategy = "horizontal", - layout_config = { - prompt_position = "top", - }, - sorting_strategy = "ascending", - mappings = { - i = { - [""] = actions.move_selection_previous, - [""] = actions.move_selection_next, - [""] = actions.send_selected_to_qflist + actions.open_qflist, - }, - }, - }, - extensions = { - ["ui-select"] = { - require("telescope.themes").get_dropdown(), - }, - }, - }) - - require("lz.n").trigger_load({ "telescope-fzf-native.nvim", "telescope-ui-select.nvim" }) - pcall(require("telescope").load_extension, "projects") - pcall(require("telescope").load_extension, "fzf") - pcall(require("telescope").load_extension, "ui-select") - end, - }, -}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/treesitter.lua b/modules/capabilities/neovim/lua-config/lua/plugins/treesitter.lua deleted file mode 100644 index bcbff63..0000000 --- a/modules/capabilities/neovim/lua-config/lua/plugins/treesitter.lua +++ /dev/null @@ -1,28 +0,0 @@ -local ok, treesitter = pcall(require, "nvim-treesitter") - -if not ok then - return -end - -treesitter.setup({}) - -local group = vim.api.nvim_create_augroup("lux-treesitter", { clear = true }) -local enableTreesitter = function(bufnr) - vim.schedule(function() - if not vim.api.nvim_buf_is_valid(bufnr) then - return - end - - if pcall(vim.treesitter.start, bufnr) then - vim.bo[bufnr].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" - end - end) -end - -vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "FileType" }, { - group = group, - pattern = "*", - callback = function(args) - enableTreesitter(args.buf) - end, -}) diff --git a/modules/capabilities/neovim/lua-config/lua/plugins/ui.lua b/modules/capabilities/neovim/lua-config/lua/plugins/ui.lua index b5a81ec..cef56e4 100644 --- a/modules/capabilities/neovim/lua-config/lua/plugins/ui.lua +++ b/modules/capabilities/neovim/lua-config/lua/plugins/ui.lua @@ -1,67 +1,52 @@ -require("lz.n").load({ - { - "theme-loader", - event = "VimEnter", - load = function() - local settings = require("nix-info").settings - local theme_code = settings.themeSetup +require("kanagawa").setup({ + dimInactive = true, + colors = { + theme = { + all = { + ui = { bg_gutter = "none" }, + }, + }, + }, +}) +vim.cmd.colorscheme("kanagawa-wave") - local func, err = loadstring(theme_code) - if func then - func() - else - print("Error loading theme code: " .. err) - end - end, - }, - { - "kulala.nvim", - after = function() - require("kulala").setup({ - global_keymaps = true, - global_keymaps_prefix = "R", - }) - end, - }, +require("lz.n").load({ { "lualine.nvim", event = "VimEnter", after = function() - local filename = { - "filename", - path = 1, - symbols = { - modified = "●", - readonly = "", - unnamed = "[No Name]", - }, - } + local navic = require("nvim-navic") + local breadcrumb = function() + if not navic.is_available() then + return "" + end + + local location = navic.get_location() + if vim.fn.strdisplaywidth(location) <= 60 then + return location + end + + while vim.fn.strdisplaywidth(location) > 59 do + location = vim.fn.strcharpart(location, 0, vim.fn.strchars(location) - 1) + end + return location .. "…" + end require("lualine").setup({ options = { - icons_enabled = true, - globalstatus = false, + theme = "kanagawa", component_separators = "", section_separators = "", - theme = "kanagawa", + globalstatus = true, }, sections = { lualine_a = { "mode" }, - lualine_b = { "branch", "diff", "diagnostics" }, - lualine_c = { filename }, - - lualine_x = { "lsp_status" }, - lualine_y = { "progress" }, + lualine_b = { "branch" }, + lualine_c = { { "filename", path = 1 }, breadcrumb }, + lualine_x = { "diagnostics" }, + lualine_y = { "filetype" }, lualine_z = { "location" }, }, - inactive_sections = { - lualine_a = {}, - lualine_b = {}, - lualine_c = { filename }, - lualine_x = {}, - lualine_y = {}, - lualine_z = {}, - }, }) end, }, @@ -78,17 +63,9 @@ require("lz.n").load({ changedelete = { text = "~" }, untracked = { text = "┆" }, }, - signs_staged_enable = true, on_attach = function(bufnr) - local gs = package.loaded.gitsigns - local map = function(mode, lhs, rhs, desc, opts) - opts = opts or {} - opts.buffer = bufnr - opts.desc = desc - vim.keymap.set(mode, lhs, rhs, opts) - end - - map("n", "]h", function() + local gs = require("gitsigns") + vim.keymap.set("n", "]h", function() if vim.wo.diff then return "]h" end @@ -96,9 +73,8 @@ require("lz.n").load({ gs.nav_hunk("next") end) return "" - end, "Next git hunk", { expr = true }) - - map("n", "[h", function() + end, { buffer = bufnr, desc = "Next git hunk", expr = true }) + vim.keymap.set("n", "[h", function() if vim.wo.diff then return "[h" end @@ -106,20 +82,7 @@ require("lz.n").load({ gs.nav_hunk("prev") end) return "" - end, "Previous git hunk", { expr = true }) - - map("n", "hp", gs.preview_hunk, "Git [H]unk [P]review") - map("n", "hs", gs.stage_hunk, "Git [H]unk [S]tage") - map("n", "hr", gs.reset_hunk, "Git [H]unk [R]eset") - map("n", "hu", gs.undo_stage_hunk, "Git [H]unk [U]ndo stage") - map("n", "hS", gs.stage_buffer, "Git [H]unk [S]tage buffer") - map("n", "hR", gs.reset_buffer, "Git [H]unk [R]eset buffer") - map("v", "hs", function() - gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) - end, "Git [H]unk [S]tage") - map("v", "hr", function() - gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) - end, "Git [H]unk [R]eset") + end, { buffer = bufnr, desc = "Previous git hunk", expr = true }) end, }) end, @@ -127,36 +90,28 @@ require("lz.n").load({ { "zen-mode.nvim", cmd = "ZenMode", + keys = { + { "uz", "ZenMode", desc = "Toggle zen mode" }, + }, after = function() - require("zen-mode").setup({ - window = { - options = { - linebreak = true, - }, - }, - }) + require("zen-mode").setup({}) end, }, { "which-key.nvim", event = "VimEnter", - before = function() - require("lz.n").trigger_load("mini.nvim") - end, after = function() require("which-key").setup({ - preset = "modern", - delay = 200, - icons = { - mappings = true, - keys = {}, - }, - + preset = "helix", spec = { - { "b", group = "[B]uffer" }, - { "s", group = "[S]earch" }, - { "t", group = "[T]oggle" }, - { "h", group = "Git [H]unk", mode = { "n", "v" } }, + { "b", group = "Buffers" }, + { "c", group = "Code" }, + { "d", group = "Diagnostics" }, + { "n", group = "Notes" }, + { "q", group = "Database" }, + { "r", group = "HTTP" }, + { "s", group = "Search" }, + { "u", group = "UI" }, }, }) end, diff --git a/modules/capabilities/neovim/lua-config/lua/project.lua b/modules/capabilities/neovim/lua-config/lua/project.lua new file mode 100644 index 0000000..14ab670 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/lua/project.lua @@ -0,0 +1,7 @@ +local M = {} + +function M.root() + return vim.fs.root(0, { ".git" }) or vim.fn.getcwd() +end + +return M diff --git a/modules/capabilities/neovim/lua-config/snippets/nix.json b/modules/capabilities/neovim/lua-config/snippets/nix.json new file mode 100644 index 0000000..eeeb3e0 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/snippets/nix.json @@ -0,0 +1,55 @@ +{ + "Full lux module": { + "prefix": "luxmod", + "description": "Full lux module (NixOS and Home Manager)", + "body": [ + "{ inputs, ... }:", + "{", + " lux.${1:moduleName} = {", + " nixos = { config, lib, pkgs, ... }: {", + " $2", + " };", + "", + " homeManager = { config, lib, pkgs, ... }: {", + " $3", + " };", + " };", + "}" + ] + }, + "Lux NixOS module": { + "prefix": "luxnixos", + "description": "Lux NixOS-only module", + "body": [ + "{ inputs, ... }:", + "{", + " lux.${1:moduleName}.nixos = { config, lib, pkgs, ... }: {", + " $0", + " };", + "}" + ] + }, + "Lux Home Manager module": { + "prefix": "luxhm", + "description": "Lux Home Manager-only module", + "body": [ + "{ inputs, ... }:", + "{", + " lux.${1:moduleName}.homeManager = { config, lib, pkgs, ... }: {", + " $0", + " };", + "}" + ] + }, + "Den inline aspect": { + "prefix": "denaspect", + "description": "Den inline aspect", + "body": [ + "(", + " { host, user, ... }: {", + " $0", + " }", + ")" + ] + } +} diff --git a/modules/capabilities/neovim/lua-config/snippets/nix.lua b/modules/capabilities/neovim/lua-config/snippets/nix.lua deleted file mode 100644 index 1f1ec0b..0000000 --- a/modules/capabilities/neovim/lua-config/snippets/nix.lua +++ /dev/null @@ -1,91 +0,0 @@ -local ls = require("luasnip") -local s = ls.snippet -local t = ls.text_node -local i = ls.insert_node - -return { - -- Full lux module (both nixos and homeManager) - s("luxmod", { - t({ - "{ inputs, ... }:", - "{", - " lux." - }), - i(1, "moduleName"), - t({ - " = {", - " nixos = { config, lib, pkgs, ... }: {", - " " - }), - i(2), - t({ - "", - " };", - "", - " homeManager = { config, lib, pkgs, ... }: {", - " " - }), - i(3), - t({ - "", - " };", - " };", - "}", - }), - }), - - -- lux nixos only module - s("luxnixos", { - t({ - "{ inputs, ... }:", - "{", - " lux." - }), - i(1, "moduleName"), - t({ - ".nixos = { config, lib, pkgs, ... }: {", - " " - }), - i(0), - t({ - "", - " };", - "}", - }), - }), - - -- lux homeManager only module - s("luxhm", { - t({ - "{ inputs, ... }:", - "{", - " lux." - }), - i(1, "moduleName"), - t({ - ".homeManager = { config, lib, pkgs, ... }: {", - " " - }), - i(0), - t({ - "", - " };", - "}", - }), - }), - - -- den inline aspect - s("denaspect", { - t({ - "(", - " { host, user, ... }: {", - " " - }), - i(0), - t({ - "", - " }", - ")" - }), - }), -} \ No newline at end of file diff --git a/modules/capabilities/neovim/lua-config/snippets/package.json b/modules/capabilities/neovim/lua-config/snippets/package.json new file mode 100644 index 0000000..6f9cd78 --- /dev/null +++ b/modules/capabilities/neovim/lua-config/snippets/package.json @@ -0,0 +1,11 @@ +{ + "name": "lux-nix-snippets", + "contributes": { + "snippets": [ + { + "language": "nix", + "path": "./nix.json" + } + ] + } +} diff --git a/modules/profiles/host-base.nix b/modules/profiles/host-base.nix index c66af48..9c79880 100644 --- a/modules/profiles/host-base.nix +++ b/modules/profiles/host-base.nix @@ -15,7 +15,6 @@ in nixosModules.nix nixosModules.locale nixosModules.sops-password - nixosModules.helix-cache ]; home-manager = { @@ -26,7 +25,7 @@ in hmModules.facts hmModules.syncthing hmModules.shell - hmModules.primary-editor-helix + hmModules.primary-editor-neovim ]; };