diff options
Diffstat (limited to 'common/nixvim.nix')
-rw-r--r-- | common/nixvim.nix | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/common/nixvim.nix b/common/nixvim.nix new file mode 100644 index 0000000..cfb33bb --- /dev/null +++ b/common/nixvim.nix | |||
@@ -0,0 +1,508 @@ | |||
1 | inputs: | ||
2 | { | ||
3 | config, | ||
4 | lib, | ||
5 | pkgs, | ||
6 | ... | ||
7 | }: | ||
8 | |||
9 | let | ||
10 | inherit (inputs.nixvim.legacyPackages.x86_64-linux) makeNixvim; | ||
11 | in | ||
12 | { | ||
13 | options.programs.nixvim = lib.mkOption { | ||
14 | type = lib.types.submodule { | ||
15 | freeformType = lib.types.anything; | ||
16 | config.finalPackage = makeNixvim (builtins.removeAttrs config.programs.nixvim [ "finalPackage" ]); | ||
17 | }; | ||
18 | }; | ||
19 | |||
20 | config.programs.nixvim = { | ||
21 | # enable = true; | ||
22 | luaLoader.enable = true; | ||
23 | |||
24 | globals = { | ||
25 | mapleader = ";"; | ||
26 | maplocalleader = ","; | ||
27 | }; | ||
28 | |||
29 | opts = { | ||
30 | backup = true; | ||
31 | # Use `//` at the end to store the absolute file name | ||
32 | backupdir.__raw = "vim.fn.stdpath('data') .. '/backup//'"; | ||
33 | colorcolumn = "80"; | ||
34 | completeopt = [ | ||
35 | "menu" | ||
36 | "menuone" | ||
37 | "noinsert" | ||
38 | "noselect" | ||
39 | ]; | ||
40 | cursorline = true; | ||
41 | diffopt = [ | ||
42 | "internal" | ||
43 | "filler" | ||
44 | "closeoff" | ||
45 | "linematch:60" | ||
46 | ]; | ||
47 | grepformat = "%f:%l:%c:%m,%f:%l:%m,%f:%l%m,%f %l%m"; | ||
48 | grepprg = "${lib.getExe pkgs.ripgrep} --vim-grep --smart-case"; | ||
49 | ignorecase = true; | ||
50 | inccommand = "split"; | ||
51 | list = true; | ||
52 | listchars = { | ||
53 | extends = ">"; | ||
54 | nbsp = "+"; | ||
55 | precedes = "<"; | ||
56 | tab = " "; | ||
57 | trail = "-"; | ||
58 | }; | ||
59 | scrolloff = 3; | ||
60 | shiftwidth = 4; | ||
61 | shortmess = "ncAxoTOtfFli"; | ||
62 | showmode = false; | ||
63 | sidescrolloff = 5; | ||
64 | smartcase = true; | ||
65 | smartindent = true; | ||
66 | tabstop = 4; | ||
67 | title = true; | ||
68 | undofile = true; | ||
69 | updatetime = 1000; | ||
70 | wildmode = [ | ||
71 | "longest:full" | ||
72 | "full" | ||
73 | ]; | ||
74 | }; | ||
75 | |||
76 | colorschemes.gruvbox = { | ||
77 | enable = true; | ||
78 | |||
79 | settings = { | ||
80 | # bold = true; | ||
81 | # italics = true; | ||
82 | # underline = true; | ||
83 | # undercurl = true; | ||
84 | italic.strings = false; | ||
85 | overrides = { | ||
86 | GitSignsAdd.link = "GruvboxGreenSign"; | ||
87 | GitSignsChange.link = "GruvboxOrangeSign"; | ||
88 | GitSignsDelete.link = "GruvboxRedSign"; | ||
89 | IblScope.link = "GruvboxAqua"; | ||
90 | }; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | highlight = { | ||
95 | TSDefinition.link = "GruvboxBlueSign"; | ||
96 | TSDefinitionUsage.link = "GruvboxAquaSign"; | ||
97 | }; | ||
98 | |||
99 | keymaps = [ | ||
100 | { | ||
101 | key = "<leader>fu"; | ||
102 | action = "require('telescope').extensions.undo.undo"; | ||
103 | lua = true; | ||
104 | options = { | ||
105 | silent = true; | ||
106 | desc = "Telescope undo"; | ||
107 | }; | ||
108 | } | ||
109 | |||
110 | { | ||
111 | key = "-"; | ||
112 | action = "require('oil').open"; | ||
113 | lua = true; | ||
114 | options.desc = "Open parent directory"; | ||
115 | } | ||
116 | |||
117 | # TODO: add "] " and "[ " | ||
118 | |||
119 | # Gitsigns | ||
120 | |||
121 | # TODO: that was not exactly that | ||
122 | # { | ||
123 | # key = "]g"; | ||
124 | # action = "require('gitsigns').next_hunk"; | ||
125 | # lua = true; | ||
126 | # } | ||
127 | |||
128 | # TODO: noremap? buffer local? silent? | ||
129 | { | ||
130 | key = "<leader>gs"; | ||
131 | action = "require('gitsigns').stage_hunk"; | ||
132 | lua = true; | ||
133 | options.desc = "Stage hunk"; | ||
134 | } | ||
135 | |||
136 | { | ||
137 | key = "<leader>gr"; | ||
138 | action = "require('gitsigns').reset_hunk"; | ||
139 | lua = true; | ||
140 | options.desc = "Reset hunk"; | ||
141 | } | ||
142 | |||
143 | # TODO: visual stage/reset | ||
144 | |||
145 | { | ||
146 | key = "<leader>gS"; | ||
147 | action = "require('gitsigns').stage_buffer"; | ||
148 | lua = true; | ||
149 | options.desc = "Stage buffer"; | ||
150 | } | ||
151 | |||
152 | { | ||
153 | key = "<leader>gR"; | ||
154 | action = "require('gitsigns').reset_buffer"; | ||
155 | lua = true; | ||
156 | options.desc = "Stage buffer"; | ||
157 | } | ||
158 | |||
159 | { | ||
160 | key = "<leader>gu"; | ||
161 | action = "require('gitsigns').undo_stage_hunk"; | ||
162 | lua = true; | ||
163 | options.desc = "Undo stage hunk"; | ||
164 | } | ||
165 | |||
166 | { | ||
167 | key = "<leader>gp"; | ||
168 | action = "require('gitsigns').preview_hunk_inline"; | ||
169 | lua = true; | ||
170 | options.desc = "Preview hunk"; | ||
171 | } | ||
172 | |||
173 | { | ||
174 | key = "<leader>gb"; | ||
175 | action = "function() require('gitsigns').blame_line { full = true } end"; | ||
176 | lua = true; | ||
177 | options.desc = "Blame line"; | ||
178 | } | ||
179 | ]; | ||
180 | |||
181 | # TODO: | ||
182 | # extraPlugins = with pkgs.unstable.vimPlugins; [ | ||
183 | extraPlugins = with inputs.nixpkgs-unstable.legacyPackages.x86_64-linux.vimPlugins; [ | ||
184 | highlight-undo-nvim | ||
185 | vim-abolish | ||
186 | |||
187 | # TODO: make that modular | ||
188 | playground | ||
189 | |||
190 | vim-rhubarb | ||
191 | fugitive-gitlab-vim | ||
192 | ]; | ||
193 | |||
194 | plugins = { | ||
195 | cmp = { | ||
196 | enable = true; | ||
197 | |||
198 | settings = { | ||
199 | mapping.__raw = '' | ||
200 | cmp.mapping.preset.insert { | ||
201 | ['<CR>'] = cmp.mapping.confirm({ select = false }), | ||
202 | |||
203 | ["<Tab>"] = cmp.mapping(function(fallback) | ||
204 | local luasnip = require("luasnip") | ||
205 | if luasnip.locally_jumpable(1) then | ||
206 | luasnip.jump(1) | ||
207 | else | ||
208 | fallback() | ||
209 | end | ||
210 | end, { "i", "s" }), | ||
211 | |||
212 | ["<S-Tab>"] = cmp.mapping(function(fallback) | ||
213 | local luasnip = require("luasnip") | ||
214 | if luasnip.locally_jumpable(-1) then | ||
215 | luasnip.jump(-1) | ||
216 | else | ||
217 | fallback() | ||
218 | end | ||
219 | end, { "i", "s" }), | ||
220 | } | ||
221 | ''; | ||
222 | |||
223 | snippet.expand = '' | ||
224 | function(args) | ||
225 | require('luasnip').lsp_expand(args.body) | ||
226 | end | ||
227 | ''; | ||
228 | |||
229 | sources = [ | ||
230 | { name = "nvim_lsp"; } | ||
231 | { name = "nvim_lsp_signature_help"; } | ||
232 | { name = "cmp_pandoc"; } | ||
233 | # TODO: make this modular | ||
234 | { name = "crates"; } | ||
235 | { name = "luasnip"; } | ||
236 | { name = "calc"; } | ||
237 | { name = "path"; } | ||
238 | { name = "treesitter"; } | ||
239 | { name = "git"; } | ||
240 | { name = "tmux"; } | ||
241 | { name = "spell"; } | ||
242 | # Use \k for iskeyword because of UTF-8 | ||
243 | { | ||
244 | name = "buffer"; | ||
245 | option.keyword_pattern = ''\k\+''; | ||
246 | } | ||
247 | ]; | ||
248 | }; | ||
249 | }; | ||
250 | # cmp-buffer.enable = true; | ||
251 | # cmp-calc.enable = true; | ||
252 | # cmp-cmdline.enable = true; | ||
253 | # cmp-git.enable = true; | ||
254 | |||
255 | comment.enable = true; | ||
256 | |||
257 | dressing.enable = true; | ||
258 | |||
259 | fidget = { | ||
260 | enable = true; | ||
261 | notification.overrideVimNotify = true; | ||
262 | }; | ||
263 | |||
264 | # TODO: add xdg-open for :GBrowse? | ||
265 | fugitive.enable = true; | ||
266 | |||
267 | gitignore.enable = true; | ||
268 | |||
269 | gitsigns.enable = true; | ||
270 | |||
271 | indent-blankline = { | ||
272 | enable = true; | ||
273 | settings.indent = { | ||
274 | char = "│"; | ||
275 | tab_char = "│"; | ||
276 | }; | ||
277 | }; | ||
278 | |||
279 | lastplace.enable = true; | ||
280 | |||
281 | lualine = { | ||
282 | enable = true; | ||
283 | iconsEnabled = false; | ||
284 | |||
285 | componentSeparators.left = ""; | ||
286 | componentSeparators.right = ""; | ||
287 | |||
288 | sectionSeparators.left = ""; | ||
289 | sectionSeparators.right = ""; | ||
290 | }; | ||
291 | |||
292 | luasnip.enable = true; | ||
293 | |||
294 | vim-matchup = { | ||
295 | enable = true; | ||
296 | treesitterIntegration.enable = true; | ||
297 | }; | ||
298 | |||
299 | mini = { | ||
300 | enable = true; | ||
301 | modules = { | ||
302 | ai = { }; | ||
303 | align = { }; | ||
304 | bracketed = { }; | ||
305 | clue = { | ||
306 | triggers = [ | ||
307 | { | ||
308 | mode = "n"; | ||
309 | keys = "["; | ||
310 | } | ||
311 | { | ||
312 | mode = "n"; | ||
313 | keys = "]"; | ||
314 | } | ||
315 | { | ||
316 | mode = "n"; | ||
317 | keys = "<leader>"; | ||
318 | } | ||
319 | ]; | ||
320 | }; | ||
321 | surround = { }; | ||
322 | trailspace = { }; | ||
323 | }; | ||
324 | }; | ||
325 | |||
326 | none-ls = { | ||
327 | enable = true; | ||
328 | sources = { | ||
329 | code_actions = { | ||
330 | gitrebase.enable = true; | ||
331 | gitsigns.enable = true; | ||
332 | # TODO: maybe? | ||
333 | #refactoring.enable = true; | ||
334 | statix.enable = true; | ||
335 | }; | ||
336 | |||
337 | diagnostics = { | ||
338 | deadnix.enable = true; | ||
339 | statix.enable = true; | ||
340 | vale = { | ||
341 | enable = true; | ||
342 | withArgs = '' | ||
343 | { filetypes = { "markdown", "pandoc", "rst", "tex", "asciidoc" }, } | ||
344 | ''; | ||
345 | }; | ||
346 | }; | ||
347 | |||
348 | formatting.shfmt.enable = true; | ||
349 | }; | ||
350 | }; | ||
351 | |||
352 | nvim-osc52 = { | ||
353 | enable = true; | ||
354 | keymaps.enable = true; | ||
355 | }; | ||
356 | |||
357 | oil.enable = true; | ||
358 | |||
359 | # TODO: maybe | ||
360 | #refactoring.enable = true; | ||
361 | |||
362 | spider = { | ||
363 | enable = true; | ||
364 | keymaps.motions = { | ||
365 | b = "<localleader>b"; | ||
366 | e = "<localleader>e"; | ||
367 | ge = "<localleader>ge"; | ||
368 | w = "<localleader>w"; | ||
369 | }; | ||
370 | }; | ||
371 | |||
372 | telescope = { | ||
373 | enable = true; | ||
374 | settings = { }; | ||
375 | |||
376 | extensions.undo.enable = true; | ||
377 | |||
378 | keymapsSilent = true; | ||
379 | keymaps = { | ||
380 | "<leader>fb" = { | ||
381 | action = "buffers"; | ||
382 | options.desc = "Telescope buffers"; | ||
383 | }; | ||
384 | |||
385 | "<leader>ff" = { | ||
386 | action = "find_files"; | ||
387 | options.desc = "Telescope find files"; | ||
388 | }; | ||
389 | |||
390 | "<leader>fg" = { | ||
391 | action = "live_grep"; | ||
392 | options.desc = "Telescope live grep"; | ||
393 | }; | ||
394 | |||
395 | "<leader>fh" = { | ||
396 | action = "help_tags"; | ||
397 | options.desc = "Telescope help tags"; | ||
398 | }; | ||
399 | |||
400 | "<leader>fo" = { | ||
401 | action = "oldfiles"; | ||
402 | options.desc = "Telescope old files"; | ||
403 | }; | ||
404 | |||
405 | "<leader>fs" = { | ||
406 | action = "spell_suggest"; | ||
407 | options.desc = "Telescope spell suggest"; | ||
408 | }; | ||
409 | |||
410 | "<leader>ft" = { | ||
411 | action = "treesitter"; | ||
412 | options.desc = "Telescope treesitter"; | ||
413 | }; | ||
414 | |||
415 | "<leader>fw" = { | ||
416 | action = "git_status"; | ||
417 | options.desc = "Telescope git status"; | ||
418 | }; | ||
419 | }; | ||
420 | }; | ||
421 | |||
422 | treesitter = { | ||
423 | enable = true; | ||
424 | indent = true; | ||
425 | |||
426 | incrementalSelection.enable = true; | ||
427 | nixvimInjections = true; | ||
428 | }; | ||
429 | |||
430 | treesitter-context = { | ||
431 | enable = true; | ||
432 | settings = { | ||
433 | max_lines = 5; | ||
434 | min_window_height = 20; | ||
435 | }; | ||
436 | }; | ||
437 | |||
438 | treesitter-refactor = { | ||
439 | enable = true; | ||
440 | highlightDefinitions.enable = true; | ||
441 | }; | ||
442 | |||
443 | treesitter-textobjects = { | ||
444 | enable = true; | ||
445 | lspInterop = { | ||
446 | enable = true; | ||
447 | peekDefinitionCode = { | ||
448 | "<leader>df" = { | ||
449 | query = "@function.outer"; | ||
450 | desc = "Peek outer function"; | ||
451 | }; | ||
452 | "<leader>dF" = { | ||
453 | query = "@class.outer"; | ||
454 | desc = "Peek outer class"; | ||
455 | }; | ||
456 | }; | ||
457 | }; | ||
458 | select = { | ||
459 | enable = true; | ||
460 | lookahead = true; | ||
461 | # selectionModes = "V"; | ||
462 | keymaps = let | ||
463 | keymap = object: type: { | ||
464 | query = "@${object}.${type}"; | ||
465 | desc = "Select ${type} ${object}"; | ||
466 | }; | ||
467 | in { | ||
468 | "af" = keymap "function" "outer"; | ||
469 | "if" = keymap "function" "inner"; | ||
470 | "aF" = keymap "call" "outer"; | ||
471 | "iF" = keymap "call" "inner"; | ||
472 | "aC" = keymap "comment" "outer"; | ||
473 | "iC" = keymap "comment" "inner"; | ||
474 | "ab" = keymap "block" "outer"; | ||
475 | "ib" = keymap "block" "inner"; | ||
476 | "aa" = keymap "parameter" "outer"; | ||
477 | "ia" = keymap "parameter" "inner"; | ||
478 | }; | ||
479 | }; | ||
480 | }; | ||
481 | }; | ||
482 | |||
483 | extraConfigLuaPost = '' | ||
484 | vim.api.nvim_create_autocmd("TextYankPost", { | ||
485 | desc = "Highlight yanked text", | ||
486 | callback = function() | ||
487 | vim.highlight.on_yank() | ||
488 | end, | ||
489 | }) | ||
490 | |||
491 | require('highlight-undo').setup() | ||
492 | |||
493 | |||
494 | -- For fugitive's :GBrowse | ||
495 | |||
496 | vim.api.nvim_create_user_command("Browse", function(opts) | ||
497 | local Job = require('plenary.job') | ||
498 | |||
499 | Job:new({ | ||
500 | command = 'xdg-open', | ||
501 | args = { opts.args }, | ||
502 | }):start() | ||
503 | end, { nargs = 1 }) | ||
504 | ''; | ||
505 | }; | ||
506 | |||
507 | config.environment.systemPackages = [config.programs.nixvim.finalPackage]; | ||
508 | } | ||