1{ 2 pkgs, 3 config, 4 lib, 5 ... 6}: 7 8let 9 ltex-ls-nvim = pkgs.vimUtils.buildVimPlugin { 10 pname = "ltex-ls.nvim"; 11 version = "2.6.0"; 12 src = pkgs.fetchFromGitHub { 13 owner = "vigoux"; 14 repo = "ltex-ls.nvim"; 15 rev = "c8139ea6b7f3d71adcff121e16ee8726037ffebd"; 16 sha256 = "sha256-jY3ALr6h88xnWN2QdKe3R0vvRcSNhFWDW56b2NvnTCs="; 17 }; 18 }; 19 vim-ledger-2024-07-15 = pkgs.vimUtils.buildVimPlugin { 20 pname = "vim-ledger"; 21 version = "2024-07-15"; 22 src = pkgs.fetchFromGitHub { 23 owner = "ledger"; 24 repo = "vim-ledger"; 25 rev = "dbc683e24bd5338b8c12540227a58b2d247e097a"; 26 sha256 = "sha256-y2f0s0aAieXtj4mSnJdH7UxQlMqJqABNVPoGLlLc57A="; 27 }; 28 meta.homepage = "https://github.com/ledger/vim-ledger/"; 29 }; 30 calendar-nvim = pkgs.vimUtils.buildVimPlugin { 31 pname = "calendar-nvim"; 32 version = "2024-07-23"; 33 src = pkgs.fetchFromGitHub { 34 owner = "RyanGibb"; 35 repo = "calendar.nvim"; 36 rev = "e1ebd87eb953a91de5cba2c6eff04b127c6a894b"; 37 sha256 = "sha256-0iiW6dAvdS5UDbjJvXWKTDqvo/4yoFkYfDind+RuTmE="; 38 }; 39 meta.homepage = "https://github.com/RyanGibb/calendar.nvim/"; 40 }; 41 cfg = config.custom; 42in 43{ 44 options.custom.nvim-lsps = lib.mkEnableOption "nvim-lsps"; 45 46 config = { 47 xdg.configFile = { 48 "ftplugin/mail.vim".text = '' 49 setlocal tw=72 50 set formatoptions+=w 51 ''; 52 }; 53 programs.neovim = { 54 enable = true; 55 viAlias = true; 56 vimAlias = true; 57 extraPackages = 58 with pkgs; 59 [ 60 ripgrep 61 nixd 62 ] 63 ++ lib.lists.optionals cfg.nvim-lsps [ 64 nixfmt-rfc-style 65 # stop complaining when launching but a devshell is better 66 ocamlPackages.ocaml-lsp 67 ocamlPackages.ocamlformat 68 lua-language-server 69 pyright 70 black 71 ltex-ls 72 jdt-language-server 73 nodejs_18 74 clang-tools 75 typst-lsp 76 ]; 77 extraLuaConfig = builtins.readFile ./init.lua; 78 # undo transparent background 79 # + "colorscheme gruvbox"; 80 plugins = 81 with pkgs.vimPlugins; 82 [ 83 { 84 plugin = gruvbox-nvim; 85 type = "lua"; 86 # TODO is there a better place to put this? 87 runtime = 88 let 89 ml-style = '' 90 setlocal expandtab 91 setlocal shiftwidth=2 92 setlocal tabstop=2 93 setlocal softtabstop=2 94 ''; 95 in 96 { 97 "ftplugin/nix.vim".text = ml-style; 98 "ftplugin/ocaml.vim".text = ml-style; 99 "ftplugin/ledger.vim".text = '' 100 setlocal foldmethod=syntax 101 vnoremap <silent> <buffer> <Tab> :LedgerAlign<CR> 102 nnoremap <silent> <buffer> <Tab> :LedgerAlign<CR> 103 ''; 104 }; 105 } 106 107 { 108 plugin = telescope-nvim; 109 type = "lua"; 110 config = builtins.readFile ./telescope-nvim.lua; 111 } 112 telescope-fzf-native-nvim 113 telescope-undo-nvim 114 telescope-file-browser-nvim 115 116 { 117 plugin = gitsigns-nvim; 118 type = "lua"; 119 config = '' 120 require('gitsigns').setup{ 121 on_attach = function(bufnr) 122 local gitsigns = require('gitsigns') 123 124 local function map(mode, l, r, opts) 125 opts = opts or {} 126 opts.buffer = bufnr 127 vim.keymap.set(mode, l, r, opts) 128 end 129 130 map('n', ']c', function() 131 if vim.wo.diff then 132 vim.cmd.normal({']c', bang = true}) 133 else 134 gitsigns.nav_hunk('next') 135 end 136 end, { desc = 'Git next hunk' }) 137 138 map('n', '[c', function() 139 if vim.wo.diff then 140 vim.cmd.normal({'[c', bang = true}) 141 else 142 gitsigns.nav_hunk('prev') 143 end 144 end, { desc = 'Git prev hunk' }) 145 146 map('n', '<leader>gs', gitsigns.stage_hunk, { desc = 'Git stage hunk' }) 147 map('n', '<leader>gr', gitsigns.reset_hunk, { desc = 'Git reset hunk' }) 148 map('v', '<leader>gs', function() gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git stage hunk' }) 149 map('v', '<leader>gr', function() gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git reset hunk' }) 150 map('n', '<leader>gS', gitsigns.stage_buffer, { desc = 'Git stage buffer' }) 151 map('n', '<leader>gu', gitsigns.undo_stage_hunk, { desc = 'Git unstage hunk' }) 152 map('n', '<leader>gR', gitsigns.reset_buffer, { desc = 'Git reset buffer' }) 153 map('n', '<leader>gp', gitsigns.preview_hunk, { desc = 'Git preview hunk' }) 154 map('n', '<leader>gb', function() gitsigns.blame_line{full=true} end, { desc = 'Git blame' }) 155 map('n', '<leader>gtb', gitsigns.toggle_current_line_blame, { desc = 'Git toggle line blame' }) 156 map('n', '<leader>gd', gitsigns.diffthis, { desc = 'Git diff index' }) 157 map('n', '<leader>gD', function() gitsigns.diffthis('~') end, { desc = 'Git diff last' }) 158 map('n', '<leader>gtd', gitsigns.toggle_deleted, { desc = 'Git toggle deleted' }) 159 160 -- vih 161 map({'o', 'x'}, 'ih', ':<C-U>Git select_hunk<CR>', { desc = 'Gitsigns select hunk' }) 162 end 163 } 164 ''; 165 } 166 { 167 plugin = pkgs.overlay-unstable.vimPlugins.neogit; 168 type = "lua"; 169 config = '' 170 local neogit = require('neogit') 171 neogit.setup {} 172 ''; 173 } 174 175 plenary-nvim 176 pkgs.ripgrep 177 178 { 179 plugin = nvim-cmp; 180 type = "lua"; 181 config = builtins.readFile ./nvim-cmp.lua; 182 } 183 cmp-path 184 cmp-buffer 185 cmp-cmdline 186 { 187 plugin = cmp-dictionary; 188 type = "lua"; 189 config = '' 190 require("cmp_dictionary").setup({ 191 paths = { "${pkgs.scowl}/share/dict/words.txt" }, 192 exact_length = 2, 193 first_case_insensitive = true, 194 }) 195 ''; 196 } 197 198 { 199 plugin = luasnip; 200 type = "lua"; 201 config = builtins.readFile ./luasnip.lua; 202 } 203 cmp_luasnip 204 pkgs.overlay-unstable.vimPlugins.friendly-snippets 205 206 { 207 plugin = nvim-treesitter.withAllGrammars; 208 type = "lua"; 209 config = '' 210 require'nvim-treesitter.configs'.setup { 211 highlight = { 212 enable = true, 213 -- :h vimtex-faq-treesitter 214 disable = { "latex" }, 215 }, 216 } 217 vim.opt.foldmethod = "expr" 218 vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" 219 vim.opt.foldenable = false 220 ''; 221 } 222 { 223 plugin = nvim-treesitter-textobjects; 224 type = "lua"; 225 config = '' 226 require'nvim-treesitter.configs'.setup { 227 textobjects = { 228 select = { 229 enable = true, 230 lookahead = true, 231 keymaps = { 232 ["af"] = "@function.outer", 233 ["if"] = "@function.inner", 234 ["ac"] = "@conditional.outer", 235 ["ic"] = "@conditional.inner", 236 ["al"] = "@loop.outer", 237 ["il"] = "@loop.inner", 238 }, 239 include_surrounding_whitespace = true, 240 }, 241 swap = { 242 enable = true, 243 swap_next = { 244 ["<leader>a"] = "@parameter.inner", 245 }, 246 swap_previous = { 247 ["<leader>A"] = "@parameter.inner", 248 }, 249 }, 250 move = { 251 enable = true, 252 set_jumps = true, 253 goto_next_start = { 254 ["]m"] = "@function.outer", 255 }, 256 goto_next_end = { 257 ["]M"] = "@function.outer", 258 }, 259 goto_previous_start = { 260 ["[m"] = "@function.outer", 261 }, 262 goto_previous_end = { 263 ["[M"] = "@function.outer", 264 }, 265 }, 266 }, 267 } 268 -- could use some tweaking 269 vim.treesitter.query.set("ocaml", "textobjects", [[ 270 ((value_definition (let_binding)) @function.outer) 271 ((let_binding body: (_) @function.inner)) 272 ]]) 273 ''; 274 } 275 276 { 277 plugin = vimtex; 278 type = "lua"; 279 config = '' 280 vim.cmd("filetype plugin indent on") 281 vim.cmd("syntax enable") 282 vim.g.vimtex_quickfix_mode = 0 283 vim.g.vimtex_view_general_viewer = 'evince' 284 ''; 285 } 286 { 287 plugin = sved; 288 type = "lua"; 289 runtime = { 290 "ftplugin/tex.lua".text = '' 291 vim.keymap.set('n', '<localleader>v', ':call SVED_Sync()<CR>') 292 ''; 293 }; 294 } 295 cmp-omni 296 297 { 298 plugin = nvim-surround; 299 type = "lua"; 300 config = '' 301 require('nvim-surround').setup({}) 302 ''; 303 } 304 { 305 plugin = comment-nvim; 306 type = "lua"; 307 config = '' 308 require('Comment').setup() 309 ''; 310 } 311 { 312 plugin = undotree; 313 type = "lua"; 314 config = '' 315 vim.keymap.set('n', '<leader>u', vim.cmd.UndotreeToggle, { desc = 'Undotree toggle' }) 316 ''; 317 } 318 { 319 plugin = leap-nvim; 320 type = "lua"; 321 config = '' 322 vim.keymap.set({'n', 'x', 'o'}, 's', '<Plug>(leap-forward)', { desc = "Leap forward"} ) 323 vim.keymap.set({'n', 'x', 'o'}, 'S', '<Plug>(leap-backward)', { desc = "Leap backward"} ) 324 vim.keymap.set({'n', 'x', 'o'}, 'gs', '<Plug>(leap-from-window)', { desc = "Leap from window"} ) 325 ''; 326 } 327 { 328 plugin = pkgs.overlay-unstable.vimPlugins.which-key-nvim; 329 type = "lua"; 330 config = '' 331 local wk = require('which-key') 332 wk.setup({ 333 plugins = { 334 spelling = { 335 enabled = false 336 }, 337 }, 338 icons = { mappings = false }, 339 triggers = { 340 { "<leader>", mode = { "n", "v" } }, 341 { "<auto>", mode = "nixsotc" }, 342 }, 343 delay = 1000, 344 }) 345 wk.add({ 346 { "<leader>f", group = 'Find' }, 347 { "<leader>l", group = 'LSP' }, 348 { "<leader>;", group = 'DAP' }, 349 { "<leader>s", group = 'Session' }, 350 { "<leader>t", group = 'Tab' }, 351 { "<leader>h", group = 'Hunk' }, 352 { "<leader>x", group = 'Trouble' }, 353 { "<leader>g", group = 'Git' }, 354 { "<leader>i", group = 'Insert' }, 355 }) 356 ''; 357 } 358 359 { 360 plugin = vim-ledger-2024-07-15; 361 type = "lua"; 362 config = '' 363 vim.g.ledger_fuzzy_account_completion = true 364 vim.g.ledger_extra_options = '--pedantic' 365 vim.g.ledger_align_at = 50 366 vim.g.ledger_accounts_cmd = 'ledger accounts --add-budget' 367 368 vim.g.ledger_date_format = '%Y-%m-%d' 369 370 vim.cmd([[ 371 autocmd FileType ledger nnoremap <buffer> <leader>e :call ledger#entry()<CR> 372 ]]) 373 ''; 374 } 375 { 376 plugin = orgmode; 377 type = "lua"; 378 config = '' 379 -- In any orgmode buffer press g? for help 380 require('orgmode').setup({ 381 org_agenda_files = { '~/vault/*.org' }, 382 org_default_notes_file = '~/vault/todo.org', 383 org_capture_templates = { 384 t = { 385 description = 'Task', 386 template = '* TODO %?\n %u', 387 }, 388 }, 389 }) 390 ''; 391 } 392 ] 393 ++ lib.lists.optionals cfg.nvim-lsps [ 394 { 395 plugin = nvim-lspconfig; 396 type = "lua"; 397 config = builtins.readFile ./lsp.lua; 398 runtime = { 399 "ftplugin/java.lua".text = '' 400 local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t') 401 local workspace_dir = '~/.cache/jdt/' .. project_name 402 require('jdtls').start_or_attach { 403 on_attach = On_attach, 404 capabilities = Capabilities, 405 cmd = { 'jdt-language-server', '-data', workspace_dir, }, 406 root_dir = vim.fs.dirname(vim.fs.find({'gradlew', '.git', 'mvnw'}, { upward = true })[1]), 407 } 408 ''; 409 }; 410 } 411 { 412 plugin = nvim-dap; 413 type = "lua"; 414 config = builtins.readFile ./dap.lua; 415 } 416 cmp-nvim-lsp 417 cmp-nvim-lsp-signature-help 418 ltex-ls-nvim 419 nvim-jdtls 420 ]; 421 }; 422 }; 423}