diff options
author | Minijackson <minijackson@riseup.net> | 2024-05-15 22:03:04 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2024-05-15 22:03:04 +0200 |
commit | 3add3d06af15c0457075f994e0b4a91289737c74 (patch) | |
tree | aa80cabeeb7475b93edebdf4e8e8f347678b767a | |
parent | c962d1398a313b30d734a39cf4fd9e6c3bee9457 (diff) | |
download | nixos-config-reborn-3add3d06af15c0457075f994e0b4a91289737c74.tar.gz nixos-config-reborn-3add3d06af15c0457075f994e0b4a91289737c74.zip |
common/vim: switch to nixvim
-rw-r--r-- | common/default.nix | 1 | ||||
-rw-r--r-- | common/nixvim.nix | 508 | ||||
-rw-r--r-- | common/vim.nix | 2 | ||||
-rw-r--r-- | flake.lock | 296 | ||||
-rw-r--r-- | flake.nix | 42 | ||||
-rw-r--r-- | usecases/desktop/development.nix | 3 | ||||
-rw-r--r-- | usecases/desktop/development/nixvim-dev.nix | 300 |
7 files changed, 1132 insertions, 20 deletions
diff --git a/common/default.nix b/common/default.nix index 16093b6..a791e8d 100644 --- a/common/default.nix +++ b/common/default.nix | |||
@@ -8,6 +8,7 @@ inputs: | |||
8 | (import ./commandline.nix inputs) | 8 | (import ./commandline.nix inputs) |
9 | (import ./localization.nix inputs) | 9 | (import ./localization.nix inputs) |
10 | (import ./nix.nix inputs) | 10 | (import ./nix.nix inputs) |
11 | (import ./nixvim.nix inputs) | ||
11 | (import ./ssh.nix inputs) | 12 | (import ./ssh.nix inputs) |
12 | (import ./theme.nix inputs) | 13 | (import ./theme.nix inputs) |
13 | (import ./tinc.nix inputs) | 14 | (import ./tinc.nix inputs) |
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 | } | ||
diff --git a/common/vim.nix b/common/vim.nix index 23aa7e9..10a8705 100644 --- a/common/vim.nix +++ b/common/vim.nix | |||
@@ -177,7 +177,7 @@ in { | |||
177 | }; | 177 | }; |
178 | }; | 178 | }; |
179 | 179 | ||
180 | environment.systemPackages = [myNeovim]; | 180 | # environment.systemPackages = [myNeovim]; |
181 | 181 | ||
182 | environment.variables = { | 182 | environment.variables = { |
183 | EDITOR = "nvim"; | 183 | EDITOR = "nvim"; |
@@ -1,5 +1,93 @@ | |||
1 | { | 1 | { |
2 | "nodes": { | 2 | "nodes": { |
3 | "devshell": { | ||
4 | "inputs": { | ||
5 | "flake-utils": "flake-utils_2", | ||
6 | "nixpkgs": [ | ||
7 | "nixvim", | ||
8 | "nixpkgs" | ||
9 | ] | ||
10 | }, | ||
11 | "locked": { | ||
12 | "lastModified": 1713532798, | ||
13 | "narHash": "sha256-wtBhsdMJA3Wa32Wtm1eeo84GejtI43pMrFrmwLXrsEc=", | ||
14 | "owner": "numtide", | ||
15 | "repo": "devshell", | ||
16 | "rev": "12e914740a25ea1891ec619bb53cf5e6ca922e40", | ||
17 | "type": "github" | ||
18 | }, | ||
19 | "original": { | ||
20 | "owner": "numtide", | ||
21 | "repo": "devshell", | ||
22 | "type": "github" | ||
23 | } | ||
24 | }, | ||
25 | "flake-compat": { | ||
26 | "locked": { | ||
27 | "lastModified": 1696426674, | ||
28 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", | ||
29 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", | ||
30 | "revCount": 57, | ||
31 | "type": "tarball", | ||
32 | "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" | ||
33 | }, | ||
34 | "original": { | ||
35 | "type": "tarball", | ||
36 | "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" | ||
37 | } | ||
38 | }, | ||
39 | "flake-compat_2": { | ||
40 | "flake": false, | ||
41 | "locked": { | ||
42 | "lastModified": 1673956053, | ||
43 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", | ||
44 | "owner": "edolstra", | ||
45 | "repo": "flake-compat", | ||
46 | "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", | ||
47 | "type": "github" | ||
48 | }, | ||
49 | "original": { | ||
50 | "owner": "edolstra", | ||
51 | "repo": "flake-compat", | ||
52 | "type": "github" | ||
53 | } | ||
54 | }, | ||
55 | "flake-parts": { | ||
56 | "inputs": { | ||
57 | "nixpkgs-lib": [ | ||
58 | "nixvim", | ||
59 | "nixpkgs" | ||
60 | ] | ||
61 | }, | ||
62 | "locked": { | ||
63 | "lastModified": 1714641030, | ||
64 | "narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=", | ||
65 | "owner": "hercules-ci", | ||
66 | "repo": "flake-parts", | ||
67 | "rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e", | ||
68 | "type": "github" | ||
69 | }, | ||
70 | "original": { | ||
71 | "owner": "hercules-ci", | ||
72 | "repo": "flake-parts", | ||
73 | "type": "github" | ||
74 | } | ||
75 | }, | ||
76 | "flake-root": { | ||
77 | "locked": { | ||
78 | "lastModified": 1713493429, | ||
79 | "narHash": "sha256-ztz8JQkI08tjKnsTpfLqzWoKFQF4JGu2LRz8bkdnYUk=", | ||
80 | "owner": "srid", | ||
81 | "repo": "flake-root", | ||
82 | "rev": "bc748b93b86ee76e2032eecda33440ceb2532fcd", | ||
83 | "type": "github" | ||
84 | }, | ||
85 | "original": { | ||
86 | "owner": "srid", | ||
87 | "repo": "flake-root", | ||
88 | "type": "github" | ||
89 | } | ||
90 | }, | ||
3 | "flake-utils": { | 91 | "flake-utils": { |
4 | "inputs": { | 92 | "inputs": { |
5 | "systems": "systems" | 93 | "systems": "systems" |
@@ -18,6 +106,64 @@ | |||
18 | "type": "github" | 106 | "type": "github" |
19 | } | 107 | } |
20 | }, | 108 | }, |
109 | "flake-utils_2": { | ||
110 | "inputs": { | ||
111 | "systems": "systems_2" | ||
112 | }, | ||
113 | "locked": { | ||
114 | "lastModified": 1701680307, | ||
115 | "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", | ||
116 | "owner": "numtide", | ||
117 | "repo": "flake-utils", | ||
118 | "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", | ||
119 | "type": "github" | ||
120 | }, | ||
121 | "original": { | ||
122 | "owner": "numtide", | ||
123 | "repo": "flake-utils", | ||
124 | "type": "github" | ||
125 | } | ||
126 | }, | ||
127 | "flake-utils_3": { | ||
128 | "inputs": { | ||
129 | "systems": "systems_3" | ||
130 | }, | ||
131 | "locked": { | ||
132 | "lastModified": 1685518550, | ||
133 | "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", | ||
134 | "owner": "numtide", | ||
135 | "repo": "flake-utils", | ||
136 | "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", | ||
137 | "type": "github" | ||
138 | }, | ||
139 | "original": { | ||
140 | "owner": "numtide", | ||
141 | "repo": "flake-utils", | ||
142 | "type": "github" | ||
143 | } | ||
144 | }, | ||
145 | "gitignore": { | ||
146 | "inputs": { | ||
147 | "nixpkgs": [ | ||
148 | "nixvim", | ||
149 | "pre-commit-hooks", | ||
150 | "nixpkgs" | ||
151 | ] | ||
152 | }, | ||
153 | "locked": { | ||
154 | "lastModified": 1660459072, | ||
155 | "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", | ||
156 | "owner": "hercules-ci", | ||
157 | "repo": "gitignore.nix", | ||
158 | "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", | ||
159 | "type": "github" | ||
160 | }, | ||
161 | "original": { | ||
162 | "owner": "hercules-ci", | ||
163 | "repo": "gitignore.nix", | ||
164 | "type": "github" | ||
165 | } | ||
166 | }, | ||
21 | "home-manager": { | 167 | "home-manager": { |
22 | "inputs": { | 168 | "inputs": { |
23 | "nixpkgs": [ | 169 | "nixpkgs": [ |
@@ -39,6 +185,27 @@ | |||
39 | "type": "github" | 185 | "type": "github" |
40 | } | 186 | } |
41 | }, | 187 | }, |
188 | "home-manager_2": { | ||
189 | "inputs": { | ||
190 | "nixpkgs": [ | ||
191 | "nixvim", | ||
192 | "nixpkgs" | ||
193 | ] | ||
194 | }, | ||
195 | "locked": { | ||
196 | "lastModified": 1715486357, | ||
197 | "narHash": "sha256-4pRuzsHZOW5W4CsXI9uhKtiJeQSUoe1d2M9mWU98HC4=", | ||
198 | "owner": "nix-community", | ||
199 | "repo": "home-manager", | ||
200 | "rev": "44677a1c96810a8e8c4ffaeaad10c842402647c1", | ||
201 | "type": "github" | ||
202 | }, | ||
203 | "original": { | ||
204 | "owner": "nix-community", | ||
205 | "repo": "home-manager", | ||
206 | "type": "github" | ||
207 | } | ||
208 | }, | ||
42 | "musnix": { | 209 | "musnix": { |
43 | "flake": false, | 210 | "flake": false, |
44 | "locked": { | 211 | "locked": { |
@@ -55,6 +222,27 @@ | |||
55 | "type": "github" | 222 | "type": "github" |
56 | } | 223 | } |
57 | }, | 224 | }, |
225 | "nix-darwin": { | ||
226 | "inputs": { | ||
227 | "nixpkgs": [ | ||
228 | "nixvim", | ||
229 | "nixpkgs" | ||
230 | ] | ||
231 | }, | ||
232 | "locked": { | ||
233 | "lastModified": 1713946171, | ||
234 | "narHash": "sha256-lc75rgRQLdp4Dzogv5cfqOg6qYc5Rp83oedF2t0kDp8=", | ||
235 | "owner": "lnl7", | ||
236 | "repo": "nix-darwin", | ||
237 | "rev": "230a197063de9287128e2c68a7a4b0cd7d0b50a7", | ||
238 | "type": "github" | ||
239 | }, | ||
240 | "original": { | ||
241 | "owner": "lnl7", | ||
242 | "repo": "nix-darwin", | ||
243 | "type": "github" | ||
244 | } | ||
245 | }, | ||
58 | "nixpkgs": { | 246 | "nixpkgs": { |
59 | "locked": { | 247 | "locked": { |
60 | "lastModified": 1715542476, | 248 | "lastModified": 1715542476, |
@@ -87,6 +275,62 @@ | |||
87 | "type": "github" | 275 | "type": "github" |
88 | } | 276 | } |
89 | }, | 277 | }, |
278 | "nixvim": { | ||
279 | "inputs": { | ||
280 | "devshell": "devshell", | ||
281 | "flake-compat": "flake-compat", | ||
282 | "flake-parts": "flake-parts", | ||
283 | "flake-root": "flake-root", | ||
284 | "home-manager": "home-manager_2", | ||
285 | "nix-darwin": "nix-darwin", | ||
286 | "nixpkgs": [ | ||
287 | "nixpkgs-unstable" | ||
288 | ], | ||
289 | "pre-commit-hooks": "pre-commit-hooks", | ||
290 | "treefmt-nix": "treefmt-nix" | ||
291 | }, | ||
292 | "locked": { | ||
293 | "lastModified": 1715582453, | ||
294 | "narHash": "sha256-pW8a12PHt/PUphG8Tn0nb+mfbTS7JS4YbThGPepCcb0=", | ||
295 | "owner": "nix-community", | ||
296 | "repo": "nixvim", | ||
297 | "rev": "4530a35bad28a0e8b21905b0817a225e6387811c", | ||
298 | "type": "github" | ||
299 | }, | ||
300 | "original": { | ||
301 | "owner": "nix-community", | ||
302 | "repo": "nixvim", | ||
303 | "type": "github" | ||
304 | } | ||
305 | }, | ||
306 | "pre-commit-hooks": { | ||
307 | "inputs": { | ||
308 | "flake-compat": "flake-compat_2", | ||
309 | "flake-utils": "flake-utils_3", | ||
310 | "gitignore": "gitignore", | ||
311 | "nixpkgs": [ | ||
312 | "nixvim", | ||
313 | "nixpkgs" | ||
314 | ], | ||
315 | "nixpkgs-stable": [ | ||
316 | "nixvim", | ||
317 | "nixpkgs" | ||
318 | ] | ||
319 | }, | ||
320 | "locked": { | ||
321 | "lastModified": 1703939133, | ||
322 | "narHash": "sha256-Gxe+mfOT6bL7wLC/tuT2F+V+Sb44jNr8YsJ3cyIl4Mo=", | ||
323 | "owner": "cachix", | ||
324 | "repo": "pre-commit-hooks.nix", | ||
325 | "rev": "9d3d7e18c6bc4473d7520200d4ddab12f8402d38", | ||
326 | "type": "github" | ||
327 | }, | ||
328 | "original": { | ||
329 | "owner": "cachix", | ||
330 | "repo": "pre-commit-hooks.nix", | ||
331 | "type": "github" | ||
332 | } | ||
333 | }, | ||
90 | "root": { | 334 | "root": { |
91 | "inputs": { | 335 | "inputs": { |
92 | "flake-utils": "flake-utils", | 336 | "flake-utils": "flake-utils", |
@@ -94,6 +338,7 @@ | |||
94 | "musnix": "musnix", | 338 | "musnix": "musnix", |
95 | "nixpkgs": "nixpkgs", | 339 | "nixpkgs": "nixpkgs", |
96 | "nixpkgs-unstable": "nixpkgs-unstable", | 340 | "nixpkgs-unstable": "nixpkgs-unstable", |
341 | "nixvim": "nixvim", | ||
97 | "rycee-nur": "rycee-nur", | 342 | "rycee-nur": "rycee-nur", |
98 | "shmart-prompt-dir": "shmart-prompt-dir" | 343 | "shmart-prompt-dir": "shmart-prompt-dir" |
99 | } | 344 | } |
@@ -144,6 +389,57 @@ | |||
144 | "repo": "default", | 389 | "repo": "default", |
145 | "type": "github" | 390 | "type": "github" |
146 | } | 391 | } |
392 | }, | ||
393 | "systems_2": { | ||
394 | "locked": { | ||
395 | "lastModified": 1681028828, | ||
396 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||
397 | "owner": "nix-systems", | ||
398 | "repo": "default", | ||
399 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||
400 | "type": "github" | ||
401 | }, | ||
402 | "original": { | ||
403 | "owner": "nix-systems", | ||
404 | "repo": "default", | ||
405 | "type": "github" | ||
406 | } | ||
407 | }, | ||
408 | "systems_3": { | ||
409 | "locked": { | ||
410 | "lastModified": 1681028828, | ||
411 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", | ||
412 | "owner": "nix-systems", | ||
413 | "repo": "default", | ||
414 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", | ||
415 | "type": "github" | ||
416 | }, | ||
417 | "original": { | ||
418 | "owner": "nix-systems", | ||
419 | "repo": "default", | ||
420 | "type": "github" | ||
421 | } | ||
422 | }, | ||
423 | "treefmt-nix": { | ||
424 | "inputs": { | ||
425 | "nixpkgs": [ | ||
426 | "nixvim", | ||
427 | "nixpkgs" | ||
428 | ] | ||
429 | }, | ||
430 | "locked": { | ||
431 | "lastModified": 1714058656, | ||
432 | "narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", | ||
433 | "owner": "numtide", | ||
434 | "repo": "treefmt-nix", | ||
435 | "rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", | ||
436 | "type": "github" | ||
437 | }, | ||
438 | "original": { | ||
439 | "owner": "numtide", | ||
440 | "repo": "treefmt-nix", | ||
441 | "type": "github" | ||
442 | } | ||
147 | } | 443 | } |
148 | }, | 444 | }, |
149 | "root": "root", | 445 | "root": "root", |
@@ -1,24 +1,30 @@ | |||
1 | { | 1 | { |
2 | description = "My NixOS configurations"; | 2 | description = "My NixOS configurations"; |
3 | 3 | ||
4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; | 4 | inputs = { |
5 | inputs.nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; | 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; |
6 | inputs.flake-utils.url = "github:numtide/flake-utils"; | 6 | nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; |
7 | inputs.home-manager = { | 7 | flake-utils.url = "github:numtide/flake-utils"; |
8 | url = "github:nix-community/home-manager/release-23.11"; | 8 | home-manager = { |
9 | inputs.nixpkgs.follows = "nixpkgs"; | 9 | url = "github:nix-community/home-manager/release-23.11"; |
10 | }; | 10 | inputs.nixpkgs.follows = "nixpkgs"; |
11 | inputs.rycee-nur = { | 11 | }; |
12 | url = "gitlab:rycee/nur-expressions"; | 12 | rycee-nur = { |
13 | flake = false; | 13 | url = "gitlab:rycee/nur-expressions"; |
14 | }; | 14 | flake = false; |
15 | inputs.musnix = { | 15 | }; |
16 | url = "github:musnix/musnix"; | 16 | musnix = { |
17 | flake = false; | 17 | url = "github:musnix/musnix"; |
18 | }; | 18 | flake = false; |
19 | inputs.shmart-prompt-dir = { | 19 | }; |
20 | url = "github:minijackson/shmart-prompt-dir"; | 20 | nixvim = { |
21 | flake = false; | 21 | url = "github:nix-community/nixvim"; |
22 | inputs.nixpkgs.follows = "nixpkgs-unstable"; | ||
23 | }; | ||
24 | shmart-prompt-dir = { | ||
25 | url = "github:minijackson/shmart-prompt-dir"; | ||
26 | flake = false; | ||
27 | }; | ||
22 | }; | 28 | }; |
23 | 29 | ||
24 | outputs = inputs @ { self, nixpkgs, home-manager, ... }: { | 30 | outputs = inputs @ { self, nixpkgs, home-manager, ... }: { |
diff --git a/usecases/desktop/development.nix b/usecases/desktop/development.nix index f919ae1..d32e5ec 100644 --- a/usecases/desktop/development.nix +++ b/usecases/desktop/development.nix | |||
@@ -30,8 +30,9 @@ inputs: { | |||
30 | luaFormat = inputs.self.lib.generators.lua {}; | 30 | luaFormat = inputs.self.lib.generators.lua {}; |
31 | in { | 31 | in { |
32 | imports = [ | 32 | imports = [ |
33 | (import ./development/latex.nix inputs) | ||
34 | (import ./development/adb.nix inputs) | 33 | (import ./development/adb.nix inputs) |
34 | (import ./development/latex.nix inputs) | ||
35 | (import ./development/nixvim-dev.nix inputs) | ||
35 | ]; | 36 | ]; |
36 | 37 | ||
37 | options = with lib; | 38 | options = with lib; |
diff --git a/usecases/desktop/development/nixvim-dev.nix b/usecases/desktop/development/nixvim-dev.nix new file mode 100644 index 0000000..83f5d10 --- /dev/null +++ b/usecases/desktop/development/nixvim-dev.nix | |||
@@ -0,0 +1,300 @@ | |||
1 | _inputs: _: | ||
2 | |||
3 | # TODO: neodev | ||
4 | # TODO: pandoc | ||
5 | { | ||
6 | programs.nixvim = { | ||
7 | # TODO: | ||
8 | # extraConfigLuaPost = '' | ||
9 | # local function set_ltex_lang(lang) | ||
10 | # local ltex = vim.lsp.get_active_clients({ name = "ltex" })[1] | ||
11 | # if ltex == nil then | ||
12 | # return | ||
13 | # end | ||
14 | # | ||
15 | # if lang == nil then | ||
16 | # lang = vim.opt_local.spelllang:get()[1] | ||
17 | # end | ||
18 | # | ||
19 | # if lang == "en" then | ||
20 | # lang = "en-US" | ||
21 | # end | ||
22 | # | ||
23 | # ltex.config.settings.ltex.language = lang | ||
24 | # end | ||
25 | # | ||
26 | # vim.api.nvim_create_user_command( | ||
27 | # "LTeXSetLang", | ||
28 | # function(opts) | ||
29 | # local lang = opts.fargs[1] | ||
30 | # set_ltex_lang(lang) | ||
31 | # end, | ||
32 | # { | ||
33 | # nargs = 1, | ||
34 | # complete = function() return { "en", "fr" } end, | ||
35 | # } | ||
36 | # ) | ||
37 | # | ||
38 | # vim.api.nvim_create_autocmd("OptionSet", { | ||
39 | # desc = "Set LTex language on spell change", | ||
40 | # callback = function(ev) | ||
41 | # if ev.match ~= "spelllang" then | ||
42 | # return | ||
43 | # end | ||
44 | # set_ltex_lang() | ||
45 | # end, | ||
46 | # }) | ||
47 | # | ||
48 | # vim.api.nvim_create_autocmd("LspAttach", { | ||
49 | # desc = "Set LTex language on attach", | ||
50 | # callback = function(ev) | ||
51 | # local client = vim.lsp.get_client_by_id(ev.data.client_id) | ||
52 | # if client.config.name ~= "ltex" then | ||
53 | # return | ||
54 | # end | ||
55 | # set_ltex_lang() | ||
56 | # end, | ||
57 | # }) | ||
58 | # ''; | ||
59 | |||
60 | plugins = { | ||
61 | # TODO: | ||
62 | #conform-nvim.enable = true; | ||
63 | |||
64 | clangd-extensions.enable = true; | ||
65 | |||
66 | crates-nvim = { | ||
67 | enable = true; | ||
68 | extraOptions.null_ls.enabled = true; | ||
69 | }; | ||
70 | |||
71 | lsp = { | ||
72 | enable = true; | ||
73 | |||
74 | keymaps = { | ||
75 | diagnostic = { | ||
76 | "<leader>se" = { | ||
77 | action = "open_float"; | ||
78 | desc = "LSP diagnostic"; | ||
79 | }; | ||
80 | "<leader>sl" = { | ||
81 | action = "setloclist"; | ||
82 | desc = "LSP set loclist"; | ||
83 | }; | ||
84 | "<leader>sq" = { | ||
85 | action = "setqflist"; | ||
86 | desc = "LSP set quickfixlist"; | ||
87 | }; | ||
88 | }; | ||
89 | |||
90 | extra = [ | ||
91 | { | ||
92 | key = "gd"; | ||
93 | action = "require('telescope.builtin').lsp_definitions"; | ||
94 | lua = true; | ||
95 | options.desc = "LSP definitions"; | ||
96 | } | ||
97 | { | ||
98 | key = "gr"; | ||
99 | action = "require('telescope.builtin').lsp_references"; | ||
100 | lua = true; | ||
101 | options.desc = "LSP references"; | ||
102 | } | ||
103 | { | ||
104 | key = "<leader>sd"; | ||
105 | action = "require('lsp_lines').toggle"; | ||
106 | lua = true; | ||
107 | options.desc = "LSP toggle inline diagnostics"; | ||
108 | } | ||
109 | { | ||
110 | key = "<leader>sE"; | ||
111 | action = "require('telescope.builtin').diagnostics"; | ||
112 | lua = true; | ||
113 | options.desc = "LSP all diagnostics"; | ||
114 | } | ||
115 | { | ||
116 | key = "<leader>ss"; | ||
117 | action = "require('telescope.builtin').lsp_document_symbols"; | ||
118 | lua = true; | ||
119 | options.desc = "LSP document symbols"; | ||
120 | } | ||
121 | { | ||
122 | key = "<leader>sS"; | ||
123 | action = "require('telescope.builtin').lsp_workspace_symbols"; | ||
124 | lua = true; | ||
125 | options.desc = "LSP workspace symbols"; | ||
126 | } | ||
127 | ]; | ||
128 | |||
129 | lspBuf = { | ||
130 | K = { | ||
131 | action = "hover"; | ||
132 | desc = "LSP hover"; | ||
133 | }; | ||
134 | gr = { | ||
135 | action = "references"; | ||
136 | desc = "LSP references"; | ||
137 | }; | ||
138 | # TODO setup actions-preview-nvim | ||
139 | "<leader>sa" = { | ||
140 | action = "code_action"; | ||
141 | desc = "LSP code actions"; | ||
142 | }; | ||
143 | "<leader>sf" = { | ||
144 | action = "format"; | ||
145 | desc = "LSP format"; | ||
146 | }; | ||
147 | "<leader>si" = { | ||
148 | action = "implementation"; | ||
149 | desc = "LSP implementation"; | ||
150 | }; | ||
151 | "<leader>sr" = { | ||
152 | action = "rename"; | ||
153 | desc = "LSP rename"; | ||
154 | }; | ||
155 | "<leader>st" = { | ||
156 | action = "type_definition"; | ||
157 | desc = "LSP type definition"; | ||
158 | }; | ||
159 | }; | ||
160 | }; | ||
161 | |||
162 | onAttach = '' | ||
163 | require("clangd_extensions.inlay_hints").setup_autocmd() | ||
164 | require("clangd_extensions.inlay_hints").set_inlay_hints() | ||
165 | ''; | ||
166 | |||
167 | servers = { | ||
168 | bashls.enable = true; | ||
169 | clangd = { | ||
170 | enable = true; | ||
171 | extraOptions.cmd = [ | ||
172 | "clangd" | ||
173 | "--background-index" | ||
174 | "--clang-tidy" | ||
175 | "--fallback-style=WebKit" | ||
176 | "--header-insertion-decorators" | ||
177 | "--header-insertion=iwyu" | ||
178 | ]; | ||
179 | }; | ||
180 | elixirls.enable = true; | ||
181 | # TODO: buggy with lsp-lines? | ||
182 | ltex = { | ||
183 | enable = true; | ||
184 | filetypes = [ | ||
185 | "bib" | ||
186 | "gitcommit" | ||
187 | "markdown" | ||
188 | "org" | ||
189 | "plaintex" | ||
190 | "rst" | ||
191 | "rnoweb" | ||
192 | "tex" | ||
193 | # vv Added this one vv | ||
194 | "typst" | ||
195 | "pandoc" | ||
196 | "quarto" | ||
197 | "rmd" | ||
198 | "context" | ||
199 | "html" | ||
200 | "xhtml" | ||
201 | ]; | ||
202 | }; | ||
203 | lua-ls.enable = true; | ||
204 | # completion.callSnippet = "Replace";? | ||
205 | marksman.enable = true; | ||
206 | nixd = { | ||
207 | enable = true; | ||
208 | # TODO: doesn't work with string substitution | ||
209 | settings.formatting.command = [ "nixfmt" ]; | ||
210 | }; | ||
211 | pylsp = { | ||
212 | enable = true; | ||
213 | settings.plugins.ruff.enabled = true; | ||
214 | }; | ||
215 | taplo.enable = true; | ||
216 | typos-lsp.enable = true; | ||
217 | typst-lsp.enable = true; | ||
218 | }; | ||
219 | }; | ||
220 | |||
221 | lsp-lines = { | ||
222 | enable = true; | ||
223 | # TODO: seems buggy with multiple sources? | ||
224 | # currentLine = true; | ||
225 | }; | ||
226 | |||
227 | rustaceanvim = { | ||
228 | enable = true; | ||
229 | server = { | ||
230 | onAttach = '' | ||
231 | function(client, bufnr) | ||
232 | __lspOnAttach(client, bufnr) | ||
233 | |||
234 | vim.keymap.set( | ||
235 | -- {"n", "v"}, | ||
236 | "n", | ||
237 | "J", | ||
238 | function() vim.cmd.RustLsp('joinLines') end, | ||
239 | { | ||
240 | silent = true, | ||
241 | buffer = bufnr, | ||
242 | desc = "rust-analyzer join lines", | ||
243 | } | ||
244 | ) | ||
245 | |||
246 | vim.keymap.set( | ||
247 | "n", | ||
248 | "<M-Up>", | ||
249 | function() vim.cmd.RustLsp({ "moveItem", "up" }) end, | ||
250 | { | ||
251 | silent = true, | ||
252 | buffer = bufnr, | ||
253 | desc = "rust-analyzer move item up", | ||
254 | } | ||
255 | ) | ||
256 | |||
257 | vim.keymap.set( | ||
258 | "n", | ||
259 | "<M-Down>", | ||
260 | function() vim.cmd.RustLsp({ "moveItem", "down" }) end, | ||
261 | { | ||
262 | silent = true, | ||
263 | buffer = bufnr, | ||
264 | desc = "rust-analyzer move item down", | ||
265 | } | ||
266 | ) | ||
267 | |||
268 | vim.keymap.set( | ||
269 | "n", | ||
270 | "<leader>sR", | ||
271 | function() vim.cmd.RustLsp('runnables') end, | ||
272 | { | ||
273 | silent = true, | ||
274 | buffer = bufnr, | ||
275 | desc = "rust-analyzer runnables", | ||
276 | } | ||
277 | ) | ||
278 | |||
279 | vim.keymap.set( | ||
280 | "n", | ||
281 | "<leader>sx", | ||
282 | function() vim.cmd.RustLsp('explainError') end, | ||
283 | { | ||
284 | silent = true, | ||
285 | buffer = bufnr, | ||
286 | desc = "rust-analyzer explain error", | ||
287 | } | ||
288 | ) | ||
289 | end | ||
290 | ''; | ||
291 | # TODO? | ||
292 | # settings.rust-analyzer = { | ||
293 | # checkOnSave.command = "clippy"; | ||
294 | # experimental.procAttrMacros = true; | ||
295 | # }; | ||
296 | }; | ||
297 | }; | ||
298 | }; | ||
299 | }; | ||
300 | } | ||