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