diff --git a/flake.lock b/flake.lock index 4a97fae..cfdabd2 100644 --- a/flake.lock +++ b/flake.lock @@ -50,6 +50,27 @@ "type": "github" } }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1777988971, + "narHash": "sha256-qIoWPDs+0/8JecyYgE3gpKQxW/4bLW/gp45vow9ioCQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "0678d8986be1661af6bb555f3489f2fdfc31f6ff", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -98,6 +119,28 @@ "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" } }, + "nixvim": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1778510615, + "narHash": "sha256-cMNCx8mQTJnVkA6kt3B3ArGpCOOniYn644hH0mJHSsw=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "fa8cd368d27cf9541f086485884928315abdcc8c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, "root": { "inputs": { "den": "den", @@ -105,7 +148,23 @@ "flake-parts": "flake-parts", "home-manager": "home-manager", "import-tree": "import-tree", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "nixvim": "nixvim" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 66592b3..6b25dac 100644 --- a/flake.nix +++ b/flake.nix @@ -16,5 +16,9 @@ }; import-tree.url = "github:vic/import-tree"; nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; } diff --git a/modules/dendritic.nix b/modules/dendritic.nix index 415b185..50564f5 100644 --- a/modules/dendritic.nix +++ b/modules/dendritic.nix @@ -13,5 +13,9 @@ url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; } diff --git a/modules/nixvim/_autocmd.nix b/modules/nixvim/_autocmd.nix new file mode 100644 index 0000000..dd6ccf2 --- /dev/null +++ b/modules/nixvim/_autocmd.nix @@ -0,0 +1,17 @@ +{ + autoGroups = { + kickstart-highlight-yank.clear = true; + VimStartup.clear = true; + }; + + autoCmd = [ + { + event = "TextYankPost"; + desc = "Hightlight when yanking text"; + group = "kickstart-highlight-yank"; + callback = { + __raw = "function() vim.hl.on_yank() end"; + }; + } + ]; +} diff --git a/modules/nixvim/_basic.nix b/modules/nixvim/_basic.nix new file mode 100644 index 0000000..953f6c3 --- /dev/null +++ b/modules/nixvim/_basic.nix @@ -0,0 +1,53 @@ +{ + colorschemes.catppuccin = { + enable = true; + settings = { + transparent_background = true; + }; + }; + + colorscheme = "catppuccin-frappe"; + + globals = { + mapleader = " "; + maplocalleader = " "; + netrw_liststyle = 3; + netrw_banner = 0; + netrw_winsize = 80; + netrw_browse_split = 2; + }; + + opts = { + number = true; + relativenumber = true; + scrolloff = 10; + cursorline = true; + + tabstop = 4; + shiftwidth = 4; + expandtab = true; + + mouse = "a"; + + showmode = false; + + breakindent = true; + undofile = true; + + # Case-insensitive search, unless search has >=1 capital letter + ignorecase = true; + smartcase = true; + + signcolumn = "yes"; + + updatetime = 250; + timeoutlen = 300; + + splitright = true; + splitbelow = true; + + inccommand = "split"; + + confirm = true; + }; +} diff --git a/modules/nixvim/_keymaps.nix b/modules/nixvim/_keymaps.nix new file mode 100644 index 0000000..d64ff42 --- /dev/null +++ b/modules/nixvim/_keymaps.nix @@ -0,0 +1,188 @@ +{ lib, ... }: +let + mkKeymap = + { + desc, + mode ? "n", + key, + action ? null, + rawAction ? null, + }: + assert lib.asserts.assertMsg ( + action != null || rawAction != null + ) "`action` or `rawAction` must be set"; + { + inherit mode key; + options = { inherit desc; }; + action = if rawAction == null then action else { __raw = rawAction; }; + }; + + mkCmdKeymap = + { + desc, + mode ? "n", + key, + cmd, + }: + { + inherit desc mode key; + action = "${cmd}"; + }; + + mkLspBufKeymap = + { + desc, + mode ? "n", + key, + lspAction, + }: + { + inherit desc mode key; + rawAction = "function() vim.lsp.buf.${lspAction}() end"; + }; + + mkRustKeymap = + { + desc, + mode ? "n", + key, + rustCmd, + }: + mkCmdKeymap { + inherit desc mode key; + cmd = "RustLsp ${rustCmd}"; + }; + +in +{ + keymaps = map mkKeymap [ + { + desc = "'jk' to exit insert mode"; + key = "jk"; + mode = "i"; + action = ""; + } + (mkCmdKeymap { + desc = "Clear search highlights in normal mode"; + key = ""; + cmd = "nohlsearch"; + }) + { + desc = "Open diagnostic quickfix list"; + key = "q"; + rawAction = "vim.diagnostic.setloclist"; + } + { + desc = "Exit terminal mode"; + key = ""; + mode = "t"; + action = ""; + } + + # Ease split navigation + { + desc = "Move focus to the left window"; + key = ""; + action = ""; + } + { + desc = "Move focus to the right window"; + key = ""; + action = ""; + } + { + desc = "Move focus to the lower window"; + key = ""; + action = ""; + } + { + desc = "Move focus to the upper window"; + key = ""; + action = ""; + } + + # Buffer management + (mkCmdKeymap { + desc = "Move to the previous buffer"; + key = ""; + cmd = ":bp"; + }) + (mkCmdKeymap { + desc = "Move to the next buffer"; + key = ""; + cmd = ":bn"; + }) + (mkCmdKeymap { + desc = "Close the current buffer"; + key = ""; + cmd = ":lua MiniBufremove.delete()"; + }) + + # LSP stuff + (mkLspBufKeymap { + desc = "Open code actions"; + key = "a"; + lspAction = "code_action"; + }) + (mkLspBufKeymap { + desc = "Go to definition"; + key = "gd"; + lspAction = "definition"; + }) + (mkLspBufKeymap { + desc = "Go to references"; + key = "gD"; + lspAction = "definition"; + }) + (mkLspBufKeymap { + desc = "Go to implementation"; + key = "gi"; + lspAction = "implementation"; + }) + (mkLspBufKeymap { + desc = "Go to type"; + key = "gt"; + lspAction = "type_definition"; + }) + + # Diagnostics + (mkCmdKeymap { + desc = "Diagnostics (Trouble)"; + key = "xx"; + cmd = "Trouble diagnostics toggle"; + }) + (mkCmdKeymap { + desc = "Buffer diagnostics (Trouble)"; + key = "xX"; + cmd = "Trouble diagnostics toggle filter.buf=0"; + }) + + # Rust + (mkRustKeymap { + desc = "Open Rust code actions"; + key = "ra"; + rustCmd = "codeAction"; + }) + (mkRustKeymap { + desc = "Open Rust code actions"; + mode = "v"; + key = "ra"; + rustCmd = "codeAction"; + }) + (mkRustKeymap { + desc = "Next Rust Diagnostic"; + key = "rd"; + rustCmd = "renderDiagnostic"; + }) + (mkRustKeymap { + desc = "Prev Rust Diagnostic"; + key = "rD"; + rustCmd = "renderDiagnostic"; + }) + (mkRustKeymap { + desc = "Open Cargo.toml"; + key = "rC"; + rustCmd = "openCargo"; + }) + ]; +} diff --git a/modules/nixvim/_lsp.nix b/modules/nixvim/_lsp.nix new file mode 100644 index 0000000..5cd1040 --- /dev/null +++ b/modules/nixvim/_lsp.nix @@ -0,0 +1,19 @@ +{ lib, ... }: +{ + plugins.lspconfig.enable = true; + plugins.lsp-format = { + enable = true; + lspServersToEnable = "all"; + }; + + plugins.nix.enable = true; + + lsp.servers = { + nixd.enable = true; + }; + + plugins.rustaceanvim = { + enable = true; + settings.standalone = false; + }; +} diff --git a/modules/nixvim/_plugins/default.nix b/modules/nixvim/_plugins/default.nix new file mode 100644 index 0000000..884171e --- /dev/null +++ b/modules/nixvim/_plugins/default.nix @@ -0,0 +1,10 @@ +{ + imports = [ + ./gitsigns.nix + ./mini.nix + ./telescope.nix + ./treesitter.nix + ./trouble.nix + ./which-key.nix + ]; +} diff --git a/modules/nixvim/_plugins/gitsigns.nix b/modules/nixvim/_plugins/gitsigns.nix new file mode 100644 index 0000000..8ba3e72 --- /dev/null +++ b/modules/nixvim/_plugins/gitsigns.nix @@ -0,0 +1,5 @@ +{ + plugins.gitsigns = { + enable = true; + }; +} diff --git a/modules/nixvim/_plugins/mini.nix b/modules/nixvim/_plugins/mini.nix new file mode 100644 index 0000000..6b87460 --- /dev/null +++ b/modules/nixvim/_plugins/mini.nix @@ -0,0 +1,23 @@ +{ + plugins.mini = { + enable = true; + mockDevIcons = true; + modules = { + ai.enable = true; + bufremove.enable = true; + completion.enable = true; + icons.enable = true; + notify.enable = true; + pairs.enable = true; + snippets.enable = true; + splitjoin.enable = true; + surround.enable = true; + statusline = { + enable = true; + use_icons = true; + }; + tabline.enable = true; + trailspace.enable = true; + }; + }; +} diff --git a/modules/nixvim/_plugins/telescope.nix b/modules/nixvim/_plugins/telescope.nix new file mode 100644 index 0000000..0a23dcd --- /dev/null +++ b/modules/nixvim/_plugins/telescope.nix @@ -0,0 +1,59 @@ +let + mkBuiltinKeymap = + { action, desc }: + { + inherit action; + options = { inherit desc; }; + }; +in +{ + plugins.telescope = { + enable = true; + extensions = { + fzf-native.enable = true; + ui-select.enable = true; + }; + keymaps = { + "sh" = mkBuiltinKeymap { + action = "help_tags"; + desc = "[S]earch [H]elp"; + }; + "sk" = mkBuiltinKeymap { + action = "keymaps"; + desc = "[S]earch [K]eymaps"; + }; + "sf" = mkBuiltinKeymap { + action = "find_files"; + desc = "[S]earch [F]iles"; + }; + "ss" = mkBuiltinKeymap { + action = "builtin"; + desc = "[S]earch [S]elect Telescope"; + }; + "sw" = mkBuiltinKeymap { + action = "grep_string"; + desc = "[S]earch current [W]ord"; + }; + "sg" = mkBuiltinKeymap { + action = "live_grep"; + desc = "[S]earch by [G]rep"; + }; + "sd" = mkBuiltinKeymap { + action = "diagnostics"; + desc = "[S]earch [D]iagnostics"; + }; + "sr" = mkBuiltinKeymap { + action = "resume"; + desc = "[S]earch [R]esume"; + }; + "s." = mkBuiltinKeymap { + action = "oldfiles"; + desc = "[S]earch Recent Files ('.' for repeat)"; + }; + "" = mkBuiltinKeymap { + action = "buffers"; + desc = "[ ] Find existing buffers"; + }; + }; + }; +} diff --git a/modules/nixvim/_plugins/treesitter.nix b/modules/nixvim/_plugins/treesitter.nix new file mode 100644 index 0000000..1e480c8 --- /dev/null +++ b/modules/nixvim/_plugins/treesitter.nix @@ -0,0 +1,23 @@ +{ + plugins.treesitter = { + enable = true; + + settings = { + auto_install = false; + highlight.enable = true; + incremental_selection.enable = true; + }; + }; + + plugins.treesitter-context = { + enable = true; + }; + + plugins.treesitter-textobjects = { + enable = true; + settings = { + select.enable = true; + swap.enable = true; + }; + }; +} diff --git a/modules/nixvim/_plugins/trouble.nix b/modules/nixvim/_plugins/trouble.nix new file mode 100644 index 0000000..1549a0f --- /dev/null +++ b/modules/nixvim/_plugins/trouble.nix @@ -0,0 +1,13 @@ +{ + plugins.trouble = { + enable = true; + settings = { + preview = { + type = "split"; + relative = "win"; + position = "right"; + size = 0.3; + }; + }; + }; +} diff --git a/modules/nixvim/_plugins/which-key.nix b/modules/nixvim/_plugins/which-key.nix new file mode 100644 index 0000000..068d1d0 --- /dev/null +++ b/modules/nixvim/_plugins/which-key.nix @@ -0,0 +1,9 @@ +{ + plugins.which-key = { + enable = true; + settings = { + delay = 0; + icons.mappings = true; + }; + }; +} diff --git a/modules/nixvim/nixvim.nix b/modules/nixvim/nixvim.nix new file mode 100644 index 0000000..69bd73f --- /dev/null +++ b/modules/nixvim/nixvim.nix @@ -0,0 +1,22 @@ +{ inputs, ... }: +{ + den.aspects.nixvim = { + homeManager = { + imports = [ inputs.nixvim.homeModules.nixvim ]; + + programs.nixvim = { + enable = true; + + imports = [ + ./_plugins + + ./_autocmd.nix + ./_basic.nix + ./_keymaps.nix + ./_lsp.nix + ]; + }; + }; + }; + +} diff --git a/modules/users/igneous.nix b/modules/users/igneous.nix index 579b6d8..c07b322 100644 --- a/modules/users/igneous.nix +++ b/modules/users/igneous.nix @@ -8,6 +8,8 @@ den.aspects.shell den.aspects.shell.zsh + + den.aspects.nixvim ]; homeManager =