1 =======================================================================================
2 Flake Help nixCats.flake
3
4 A Lua-natic's Neovim flake, with extra cats! nixCats!
5
6 This is the documentation for the flake itself.
7 This flake uses Nix for importing plugins, LSPs, dependencies, and more,
8 in place of usual nvim package managers such as packer, lazy or Mason.
9
10 Everything else is done in a regular Lua config style.
11 Download in flake.nix and then, simply pretend the root of the flake
12 is the root of your Lua config.
13
14 *******************************************************
15 AN IMPORTANT NOTE:
16
17 <1> When editing the files within the flake directory,
18 Nix will not package a new file if it isn't staged in git.
19 run git add before rebuilding it whenever adding a new file.
20 Using wrapRc = true would mean this also applies to Lua files.
21 Only tracked files will recieve their updates when
22 rebuilt without git add being ran first. New files need to be added.
23 *******************************************************
24
25 Related:
26 For detecting what was included by
27 the flake in your Lua, see:
28 :help nixCats
29
30 stdpath('config') will still point to ~/.config/<configDirName>.
31 But your Lua config will be in the store.
32 This is okay, because most of the reason for a plugin to use
33 it would be to write to it, and we cant write to store paths anyway.
34 You could use require('nixCats').configDir,
35 or nixCats('nixCats_config_location')
36 to get current config directory for your uses, if ever necessary.
37 It will be present and correct regardless of settings.
38
39 However if you did not use Nix at all and did not run the setup
40 function, of course the nixCats plugin wont be there to ask.
41
42 The setup function from require('nixCatsUtils').setup
43 will provide a mock nixCats plugin with SOME values
44 and empty tables to prevent accidental indexing errors.
45 You could instead do require('nixCatsUtils').isNixCats to default to
46 vim.fn.stdpath('config') if all you wanted was this path though.
47
48 Keep in mind they will be read-only if in the store!
49
50 =======================================================================================
51 Flake Inputs: nixCats.flake.inputs
52
53 If a plugin does not have an extra build step, and are not on nixpkgs,
54 you may use this format to import them, replacing the fields marked with <>
55
56 "plugins-<pluginName>" = {
57 url = "github:<userName>/<repositoryName>";
58 flake = false;
59 };
60
61 More info on flake url syntax at:
62 https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#examples
63 You may also use this syntax to pin the version of a plugin regardless of whether
64 you ran nix flake update or not.
65 You may choose the directory, branch, commit, tag, or even directory
66 imported.
67
68 All inputs named in the plugins-<pluginName> format will be added to pkgs
69 at pkgs.neovimPlugins.<pluginName> for you to add to your configuration.
70
71 If the plugin has a dot . character in it's name, you should name it something else
72 because . is not a valid character in an identifier in Nix.
73
74 The name here only affects the filename of the overall plugin, and should
75 only affect things like vim.cmd("packadd <filename>") that refer to
76 the actual filename of the plugin. Usually I would replace it with -
77 You will then add it to categoryDefinitions later with the NEW name.
78
79 If you use this method to import a plugin, and really dont
80 want to change the filename of the plugin when they have a
81 dot in their name, you may
82 swap the call to (utils.standardPluginOverlay inputs)
83 with (utils.sanitizedPluginOverlay inputs)
84 and then plugins-plugin.name would become pkgs.neovimPlugins.plugin-name
85 but Neovim would see it as vim.cmd("packadd plugin.name") still
86
87 If they have a build step or are not a plugin,
88 i.e. an LSP, or if they are a plugin from a flake,
89 dont name them in that format.
90 If they are a plugin from a flake, they can be added directly,
91 or they may be added as an overlay if offered.
92 If they are anything else they arent a plugin at all and obviously
93 should not be added as a plugin via plugins-<pluginName>
94
95 If they are on nixpkgs, you dont need to put them in inputs,
96 because you will be able to access them through pkgs.vimPlugins variable.
97 Most plugins will not require you to use the inputs section due to being on nixpkgs.
98 But you may still use it to pin the plugin to a specific version.
99
100 If you decided not to use utils.sanitizedPluginOverlay
101 and wanted to do it with utils.standardPluginOverlay:
102 If in your inputs you had:
103
104 "plugins-<plugin-name>" = {
105 url = "github:<userName>/<repository.name>";
106 flake = false;
107 };
108
109 Where you put plugins in your categoryDefinitions, instead of:
110
111 pkgs.neovimPlugins.<plugin-name>
112
113 You could put this:
114
115 { name = "<plugin.name>"; plugin = pkgs.neovimPlugins.<plugin-name>; }
116
117 You can also override them instead of (or before/during) the above:
118
119 (pkgs.neovimPlugins.<plugin-name>.overrideAttrs { pname = "<plugin.name>"; })
120
121 overrideAttrs can be used for a lot more than just fixing the name of the
122 imported plugin. See:
123 https://ryantm.github.io/nixpkgs/using/overrides/
124
125 If they have a build step and are not on nixpkgs,
126 you will deal with them in overlays/customBuildsOverlay.nix
127 then import them into a category of the builder.
128 Alternatively you may use overrideAttrs as mentioned above instead of an
129 overlay for these sorts of packages, but this would possibly get messy if the
130 build step were complex.
131
132 =======================================================================================
133 Flake Outputs Introduction nixCats.flake.outputs
134
135 With our inputs to our flake taken care of:
136 First, we take care of importing our utils set from nixCats.
137 The reason we are doing this now, is so that it can be defined outside of
138 the utils.eachSystem function, and thus we can export it
139 without having to include a system variable when we import it somewhere else.
140
141 We also define our luaPath, which is the path to be loaded into the store as
142 your new Neovim config directory. (see :help 'rtp' for the directories
143 available for you to use!)
144
145 We also define our extra_pkg_config, which is used when initializing the
146 nixpkgs instance that will build your Neovim! It's the same one from
147
148 pkgs = import nixpkgs { inherit system; overlays = []; config = {}; }
149
150 That is,
151
152 outputs = { self, nixpkgs, ... }@inputs: let
153
154 inherit (inputs.nixCats) utils;
155
156 luaPath = "${./.}";
157
158 extra_pkg_config = {
159
160 };
161
162 nixCats.flake.outputs.getOverlays
163
164 Managing the system variable in combination with overlays
165 can be one of the hardest parts of flake usage.
166 This flake resolves our pkgs instance for Neovim itself to help with this,
167 and takes care of passing the correct pkgs instance
168 to the relevant locations later for use in defining your dependencies.
169
170
171 dependencyOverlays = (import ./overlays inputs) ++ [
172 (utils.standardPluginOverlay inputs)
173 inputs.neorg-overlay.overlays.default
174 inputs.lz-n.overlays.default
175
176
177
178
179
180
181
182
183
184
185 (utils.fixSystemizedOverlay inputs.codeium.overlays
186 (system: inputs.codeium.overlays.${system}.default)
187 )
188 ];
189
190
191 nixCats.flake.outputs.overlays
192 utils.standardPluginOverlay
193 Usage of this function to create an overlay is described in:
194 :h nixCats.flake.inputs
195 along with its friend, utils.sanitizedPluginOverlay
196
197 It takes all the inputs named in the format
198 plugins-somepluginname and makes them into plugins.
199 Access them to add them to a category of the builder function
200 with pkgs.neovimPlugins.somepluginname
201
202 If the plugin doesn't have a build step,
203 and it wasnt on nixpkgs, then use this method.
204
205 If the plugin does have a build step and isn't on nixpkgs,
206 then you can either make your own overlay from scratch,
207 or you can call overrideAttrs on the generated plugin
208 to add the required items to it.
209 more info at :h nixCats.flake.inputs
210
211 If you decide you wish to split your customBuildsOverlay up,
212 see :help nixCats.flake.nixperts.overlays
213 or look at the overlays/default.nix file for advice on how to do that.
214
215 ---------------------------------------------------------------------------------------
216 nixCats.flake.outputs.categories
217 Then we define what is in our categories!
218 This section is a function that takes the package definition for this
219 particular package as an argument.
220 The builder will call it with that argument, you may use it.
221 This allows categoryDefinitions to access their packages categories and settings,
222 which allows categoryDefinitions to be much more dynamic.
223
224 It also gets mkPlugin = name: src: as an argument. mkPlugin takes a name,
225 and then a src which is any flake input or fetched drv,
226 and it returns a nvim plugin that can be further overriden via overrideAttrs if desired.
227 There is an overlay to do this automatically from flake inputs, mentioned
228 above. But sometimes it can be advantageous to do one of them individually.
229
230 It also recieves a mkNvimPlugin = src: name: which does the same thing, but
231 with the arguments the wrong way around.
232 It is still present for backwards compatibility.
233
234 These are the things you can return:
235
236 categoryDefinitions = { pkgs, settings, categories, extra, name, mkPlugin, mkNvimPlugin, ... }@packageDef: {
237
238 <startupPlugins>
239 a flexible set of categories, each containing startup plugins.
240 Startup plugins are loaded and can be required.
241 In addition, this can also recieve a superset of the home manager syntax for
242 plugins. see :help nixCats.flake.outputs.categoryDefinitions.schemas below
243 for info
244
245 <optionalPlugins>
246 a flexible set of categories, each containing optional plugins.
247 Optional plugins need to be added with packadd before being required.
248 Use :NixCats pawsible to see the names to use for packadd
249 In addition, this can also recieve a superset of the home manager syntax for
250 plugins. see :help nixCats.flake.outputs.categoryDefinitions.schemas below
251 for info
252
253 <lspsAndRuntimeDeps>
254 a flexible set of categories, each containing LSPs or
255 other internal runtime dependencies such as ctags or debuggers.
256 These are appended to the PATH (by default) while within
257 the Neovim program, including the Neovim terminal.
258 lspsAndRuntimeDeps = {
259
260 general = with pkgs; [
261 universal-ctags
262 ripgrep
263 fd
264 ];
265 go = with pkgs; [
266 { pre = true; value = gopls; }
267 gotools
268 go-tools
269 gccgo
270 ];
271 };
272
273 <sharedLibraries>
274 a flexible set of categories, each containing a derivation for
275 a runtime shared library. Will be appended to the LD_LIBRARY_PATH variable.
276 sharedLibraries = {
277 general = {
278 myGitStuff = with pkgs; [
279 libgit2
280
281
282
283 { value = libpng; pre = true; }
284 ];
285 };
286 };
287
288 <environmentVariables>
289 a flexible set of categories, each containing an ATTRIBUTE SET of
290 EnvironmentVariableName = "EnvironmentVariableValue";
291 environmentVariables = {
292 general = {
293 CATTESTVARDEFAULT = "It worked!";
294 };
295 };
296
297 <wrapperArgs>
298 a flexible set of categories, each containing escaped lists of wrapper arguments.
299 wrapperArgs = {
300 yourCategory = [
301 [ "--set" "MYVAR" "test value" ]
302 {
303 value = [ "--set" "MYVAR2" "test value 2" ];
304 priority = 150;
305 }
306 ];
307 another = [
308 "--suffix"
309 "PATH"
310 "${pkgs.lib.makeBinPath [ pkgs.something ]}"
311 ];
312 };
313 If you don't know what that is, see here:
314 https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh
315
316 <extraWrapperArgs>
317 a flexible set of categories, each containing unescaped wrapper arguments.
318 extraWrapperArgs = {
319 yourCategory = [
320 "--set MYVAR 'test value'"
321 {
322 value = "--set MYVAR2 'test value 2'";
323 priority = 150;
324 }
325 ];
326 };
327
328 <extraLuaPackages>
329 a flexible set of categories, each containing FUNCTIONS
330 that return lists of extra Lua packages.
331 These functions are the same thing that you would pass to lua.withPackages.
332 Is used to populate $LUA_PATH and $LUA_CPATH
333 extraLuaPackages = {
334 general = [ (lp: [ lp.magick ]) ];
335 };
336
337 <optionalLuaPreInit>
338 a flexible set of categories, each containing a list of lua strings,
339 or a LIST of sets containing a priority and a string of the format:
340 catname = [ "require('athing')" { config = "require('something')"; priority = 150; } ];
341 (150 is default priority)
342 These will be ran before sourcing your init.lua
343 It is not the recommended way to create Lua for this flake,
344 but it may be useful in editing flake imports
345 of other already configured setups following the nixCats format.
346
347 <optionalLuaAdditions>
348 a flexible set of categories, each containing a list of lua strings,
349 or a LIST of sets containing a priority and a string of the format:
350 catname = [ "require('athing')" { config = "require('something')"; priority = 150; } ];
351 (150 is default priority)
352 These will be ran after sourcing your init.lua
353 It is not the recommended way to create Lua for this flake,
354 but it may be useful in editing flake imports
355 of other already configured setups following the nixCats format.
356
357 <bashBeforeWrapper>
358 a flexible set of categories, each containing arbitrary Bash code
359 to run before the wrapper starts within the wrapper's Bash environment.
360 # WARNING: only use this if you know what you are doing and why you need
361 to do it. This section works the same as extraWrapperArgs but for bash.
362 # WARNING: This section is disabled when useBinaryWrapper setting is
363 enabled.
364
365 <extraCats>
366 a flexible set of categories, each containing a list of attribute paths,
367 specified as lists of strings. Thus each category would contain a list of
368 lists of strings.
369 Allows inclusion of extra categories contingent on each lists inclusion in the package,
370 and is useful for creating default values for subcategories.
371 For more info, see below at
372 :h nixCats.flake.outputs.categoryDefinitions.default_values
373 # WARNING: use of categories argument in this set will cause infinite recursion
374 # The categories argument of this function is the FINAL value.
375 # You may use it in any of the other sets.
376
377 <propagatedBuildInputs>
378 a flexible set of categories, each containing internal BUILD dependencies.
379 Will not be available to the PATH unless in a devShell.
380 # WARNING: USING THIS SECTION WILL CAUSE NVIM TO BUILD FROM SOURCE.
381 }
382
383 In essence, the contents of each set listed here are filtered
384 based on the packageDefinitions set you provide,
385 whereby including categoryname = true; you enable that category.
386 :help nixCats.flake.outputs.packageDefinitions
387
388 It will remove duplicate items, so feel free to include the same thing in
389 multiple categories if it suits your purposes.
390
391 It does this recursively. (explained below)
392
393 If, inside one of these main sets, you had another set,
394 it would consider that a subcategory, and you could enable it
395 just like you do with a normal category, by setting a value with the
396 corresponding attribute path to true in the category
397 set of nixCats.flake.outputs.packageDefinitions.
398 You can nest them as much as you like, or just have a category that is a
399 single derivation.
400
401 nixCats.flake.outputs.categoryDefinitions.schemas
402
403 You may also use the variables passed to your categoryDefinitions function
404 to get access to the set of categories and settings that are being
405 used to define the current package being built!
406
407 themer = with pkgs.vimPlugins;
408 (builtins.getAttr packageDef.categories.colorscheme {
409
410 "onedark" = onedark-vim;
411 "catppuccin" = catppuccin-nvim;
412 }
413 );
414
415 In addition to all this, if a plugin is defined within a list, it may
416 instead be defined within an attribute set that also contains config
417 to be ran after sourcing init.lua and optionalLuaAdditions
418 to do this, you may use the following syntax in opt or start sections:
419 [
420
421 { plugin = derivation; config.lua = ""; config.vim = "";}
422 { plugin = derivation; config = ""; type = "<viml or lua>"; }
423 { plugin = derivation; config = ""; }
424 { plugin = derivation; }
425
426
427
428
429
430
431
432
433
434
435
436
437 derivation
438
439
440
441 ]
442
443 nixCats.flake.outputs.categoryDefinitions.default_values
444
445 There are 2 ways of creating default values in nixCats.
446
447 #1 Implicit: when value is in another section of categoryDefinitions
448
449 If in your categoryDefinitions you had the following:
450
451 environmentVariables = {
452 test = {
453 subtest1 = {
454 CATTESTVAR = "It worked!";
455 };
456 subtest2 = {
457 CATTESTVAR3 = "It didn't work!";
458 };
459 };
460 };
461 extraWrapperArgs = {
462 test = [
463 '' --set CATTESTVAR2 "It worked again!"''
464 ];
465 };
466
467 And in your packageDefinitions set, under categories, you had the following:
468
469 test = {
470 subtest1 = true;
471 };
472
473 you could echo $CATTESTVAR and $CATTESTVAR2 in your terminal to see them.
474 However you could not echo $CATTESTVAR3.
475
476 All items that are not attributes of the parent set will be included
477 when you enable a subcategory. This includes lists, strings, functions, etc...
478
479 However, attributes will not and you must explicitly enable all attributes of
480 a subcategory if you set even 1 explicitly.
481
482 Thus to include CATTESTVAR3, you would have to enable it like so:
483 test = {
484 subtest1 = true;
485 subtest2 = true;
486 };
487 However, those are all the items in the test category.
488 So instead we can do this to enable all the subcategories in test.
489 test = true;
490
491 This applies in many situations. Take this one for example.
492
493 lspsAndRuntimeDeps = {
494 neonixdev = {
495 inherit (pkgs)
496 nix-doc nil lua-language-server nixd;
497 };
498 };
499 startupPlugins = {
500 neonixdev = with pkgs.vimPlugins; [
501 neodev-nvim
502 neoconf-nvim
503 ];
504 };
505
506 If you were to put the following in your packageDefinitions:
507 neonixdev.nix-doc = true;
508
509 neodev-nvim and neoconf-nvim would still be included.
510 However, nil, lua-language-server, and nixd would not be!
511 You would need to pick which of those you wanted separately.
512 Sometimes this is the desired behavior.
513 Sometimes it is not and a list of packages would be better suited.
514
515 This leads us to our second way to make a default value:
516
517 #2 Explicit: using extraCats section of categoryDefinitions.
518
519 The extraCats section of categoryDefinitions contains categories of attribute
520 paths. If that category is defined, the categories specified by the attribute
521 paths will also be enabled. This means you could make it so that if you
522 included the go category, it could then enable debug.go and lsp.go for you.
523 But in addition to that, it can be combined with the implicit form of creating
524 default values above in an interesting way.
525
526 categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@packageDef: {
527 lspsAndRuntimeDeps = {
528 debug = with pkgs; {
529 go = [ delve ];
530 };
531 go = with pkgs; [
532 gopls
533 gotools
534 go-tools
535 gccgo
536 ];
537 };
538 startupPlugins = {
539 debug = with pkgs.vimPlugins; {
540 default = [
541 nvim-dap
542 nvim-dap-ui
543 nvim-dap-virtual-text
544 ];
545 go = [ nvim-dap-go ];
546 };
547 };
548
549
550
551 extraCats = {
552
553
554
555
556 debug = [
557 [ "debug" "default" ]
558 ];
559
560
561 go = [
562 [ "debug" "go" ]
563 ];
564 };
565 };
566
567 If you wish to only enable a value via extraCats if multiple other categories
568 are enabled, the categories in extraCats also accept a set form!
569
570 extraCats = {
571
572 target.cat = [
573
574 [ "to" "enable" ]
575
576 {
577 cat = [ "other" "toenable" ];
578
579
580
581 when = [
582 [ "another" "cat" ]
583 ];
584
585 cond = [
586 [ "other" "category" ]
587 ];
588 }
589 ];
590 };
591
592 ---------------------------------------------------------------------------------------
593 Package Generation: nixCats.flake.outputs.packageDefinitions
594
595 generate packages by calling that builder function we just created.
596 Place them in the packageDefinitions set.
597
598 First, pick the set of settings you wish to include.
599
600 Then, pass it a set of named boolean values like this:
601 { categoryname1 = true; categoryname2 = false; etc... }
602 False may be omitted. True may not.
603 Only true matters for what plugins will be added.
604
605 These categories are defined in the Builder function above
606 by placing named lists of plugins in the flexible sets provided.
607 The category names are the names of those lists.
608 Add a new list, then enable the category here.
609
610 If you have categories with the same name in
611 multiple different sets outlined above in the builder,
612 all plugins in those categories will be
613 included when you set "thatname = true;" here.
614 hence, general = true; will include the general lspsAndDeps category,
615 as well as the general startupPlugins category.
616
617 an example package definition:
618
619 packageDefinitions = {
620
621
622 nixCats = { pkgs, name, mkPlugin, luaPath, this, ... }: {
623 setting = {
624 wrapRc = true;
625
626 aliases = [ "viCat" ];
627 };
628 categories = {
629 custom = true;
630 gitPlugins = true;
631 general = true;
632 neonixdev = true;
633
634
635
636 lspDebugMode = false;
637
638
639
640 theBestCat = "says meow!!!";
641
642
643
644
645 };
646 extra = {
647 there_is = "also";
648 an_extra = "table";
649 for = ''if you dont want the main subcategory get function
650 to apply to something, or think it all being in categories is too
651 messy
652 '';
653 you_can = ''nixCats.extra("path.to.val")'';
654 for_safer = ''table access via vim.tbl_get'';
655 };
656 };
657 };
658
659 You can use the nixCats plugin for the set you define here in your Lua
660 It returns a Lua table of the same format.
661
662 see :help nixCats
663
664 For more nuances on enabling categories and subcategories, see above at
665 :help nixCats.flake.outputs.categoryDefinitions.default_values
666 and
667 :help nixCats.flake.outputs.categoryDefinitions.schemas
668
669 ----------------------------------------------------------------------------------------
670 Settings nixCats.flake.outputs.settings
671
672 These are the defaults:
673
674 default_settings = {
675
676
677
678 aliases = null;
679
680
681 extraName = "";
682
683
684 hosts = {};
685
686
687
688
689
690
691
692 wrapRc = true;
693
694
695
696
697
698
699
700
701
702
703
704
705 configDirName = "nvim";
706
707
708
709
710
711
712 unwrappedCfgPath = null;
713
714
715
716
717 wrappedCfgPath = null;
718
719
720
721
722
723
724
725
726 neovim-unwrapped = null;
727
728
729
730 nvimSRC = null;
731
732
733
734
735 suffix-path = true;
736
737
738 suffix-LD = true;
739
740
741
742
743
744
745
746
747 autowrapRuntimeDeps = "suffix";
748
749
750
751
752
753
754
755 autoconfigure = "prefix";
756
757
758
759
760
761
762
763
764 collate_grammars = true;
765
766
767
768
769 autoPluginDeps = true;
770
771
772
773
774 useBinaryWrapper = false;
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793 moduleNamespace = [ <packagename> ];
794 };
795
796 QUICK TIP: wrapRc
797
798 The wrapRc option is very useful for testing Lua changes.
799 It removes the need to stage and rebuild to see your Lua changes reflected.
800 You will still need to rebuild when making changes to Nix regardless of the
801 value of wrapRc.
802
803 However it also means that the Lua isn't going run if it isn't in the right
804 folder, i.e. when installed and run from GitHub with nix run.
805
806 If the Lua is not in vim.fn.stdpath('config'), wrapRc = false will not work.
807 By default this is ~/.config/nvim on Linux systems, although we can
808 change nvim to whatever we wish via the configDirName setting.
809
810 Alternatively, you can set the unwrappedCfgPath option to allow the
811 configuration to be set to an absolute path. You still may want to set
812 the configDirName option anyway to change the data directories,
813 or explicitly keep it the same on both so that they share stuff like auths.
814
815 The most convenient way to use this is the following:
816 Make a second identical packageDefinition, but with wrapRc disabled.
817 Then install both the wrapped one and unwrapped one with different aliases.
818 When you want to hack in Lua, use unwrapped! When you're done, just rebuild
819 and go back to the wrapped one.
820
821 The templates/example/flake.nix file from the example config template
822 has an example of this with nixCats and regularCats.
823
824 Then, when testing Lua changes, you run the other package and have a vanilla
825 Neovim experience, only rebuilding when you install new packages.
826
827 When you are satisfied, simply rebuild and go back to using the main package,
828 as it was the same except for the single option!
829
830 --------------------------------------------------------------------------------------
831 Remote Host Providers: nixCats.flake.outputs.settings.hosts
832
833 You can bundle anything with nixCats as a host/provider!
834 Each "host" defined in the hosts set will
835 create a new section in categoryDefinitions,
836 and a global variable of your choosing will be set to the path of the host.
837
838 Each defined host will also be added to your path as ${nvimname}-${hostname}
839
840 So if your package was named mynvim,
841 enabling the python3 host will add mynvim-python3 to your path.
842
843 There are some with builtin defaults.
844 For those, unless you wish to redefine them, you only need to enable them.
845 hosts.python3.enable = true
846 hosts.node.enable = true
847 hosts.ruby.enable = true
848 hosts.perl.enable = true
849
850 Lets use python3, as an example of a host definition.
851
852 It will create a section in categoryDefinitions called python3 you can use.
853 The things defined within it will wrap only that host.
854
855 categoryDefinitions = { pkgs, settings, categories, name, ... }@packageDef: {
856 python3 = {
857 wrapperArgs = {
858 somecatname = [
859 [ "--unset" "PYTHONSAFEPATH" ]
860 ];
861 };
862 extraWrapperArgs = {
863 somecatname = [
864 "--prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.vulkan-loader ]}"
865 ];
866 };
867 envVars = {
868 somecatname = {
869 MY_VAR = "somevalue";
870 };
871 };
872
873
874
875
876 libraries = {
877 somecatname = [
878 (p: [p.pytest])
879 ];
880 };
881 };
882 }
883
884 The definition for the python3 host would look like this when fully spelled out:
885
886 packageDefinitions = {
887 somename = {pkgs, name, ...}: {
888 settings = {
889 hosts = {
890 python3 = {
891 enable = true;
892
893
894
895
896
897
898
899 path = depfn: {
900 value = (pkgs.python3.withPackages (p: depfn p ++ [p.pynvim])).interpreter;
901 args = [ "--unset" "PYTHONPATH" ];
902 };
903
904
905
906
907 global = "python3_host_prog";
908
909
910
911
912
913
914
915 pluginAttr = "python3Dependencies";
916
917
918
919
920
921
922
923
924 disabled = "loaded_python3_provider";
925
926
927
928 };
929 };
930 };
931 };
932 };
933
934 You can bundle and wrap anything this way!
935
936 packageDefinitions = {
937 packagename = { pkgs, name, ... }: {
938 categories = {
939 };
940 settings = {
941 hosts = {
942 neovide = {
943
944
945 enable = true;
946 path = {
947 value = "${pkgs.neovide}/bin/neovide";
948 args = [ "--add-flags" "--neovim-bin ${name}" ];
949 };
950 };
951 };
952 };
953 extra = {};
954 };
955 };
956
957 Defaults:
958
959 defaults = {
960 python3 = {
961 path = depfn: {
962 value = (pkgs.python3.withPackages (p: depfn p ++ [p.pynvim])).interpreter;
963 args = [ "--unset" "PYTHONPATH" ];
964 };
965 pluginAttr = "python3Dependencies";
966 };
967 node = {
968 path = {
969 value = "${pkgs.neovim-node-client or pkgs.nodePackages.neovim}/bin/neovim-node-host";
970 nvimArgs = [ "--suffix" "PATH" ":" "${pkgs.nodejs}/bin" ];
971 };
972 };
973 perl = {
974 path = depfn: "${pkgs.perl.withPackages (p: depfn p ++ [ p.NeovimExt p.Appcpanminus ])}/bin/perl";
975 };
976 ruby = {
977 path = let
978 rubyEnv = pkgs.bundlerEnv {
979 name = "neovim-ruby-env";
980 postBuild = "ln -sf ${pkgs.ruby}/bin/* $out/bin";
981 gemdir = "${pkgs.path}/pkgs/applications/editors/neovim/ruby_provider";
982 };
983 in {
984 value = "${rubyEnv}/bin/neovim-ruby-host";
985 nvimArgs = [
986 "--set" "GEM_HOME" "${rubyEnv}/${rubyEnv.ruby.gemPath}"
987 "--suffix" "PATH" ":" "${rubyEnv}/bin"
988 ];
989 };
990 };
991 };
992
993 --------------------------------------------------------------------------------------
994 Neovim Builder Creation: nixCats.flake.outputs.builder
995
996 Now we define our builder function.
997 We inherit utils.baseBuilder which is
998 a function that takes five arguments. It is defined in ./builder.
999 Right now we are going to call it with just the first four arguments. This will
1000 leave us with a function that takes 1 argument.
1001 That argument is the name of the Neovim package to be packaged.
1002
1003 1. The path to the Lua to include (in the flake, we use the self variable to get
1004 this path and wrap the Lua when wrapRc = true)
1005
1006 2. A set containing parameters for the pkgs to be used:
1007 It takes 2 forms. You can either pass it a nixpkgs and a system and it
1008 will resolve the pkgs for you and pass it to your categoryDefinitions and
1009 packageDefinitions,
1010 or you can pass it a pkgs instead to inherit the values and do the same.
1011
1012 You may also provide a dependencyOverlays list to add overlays for nvim only,
1013 extra_pkg_config (maps to the config argument to import nixpkgs { ... }),
1014 nixCats_passthru (extra items to put into passthru in the final drv),
1015 and extra_pkg_params (contains any fields in import nixpkgs { ... } not mentioned).
1016
1017 3. our function that takes an individual package definition
1018 and returns a set of categoryDefinitions.
1019
1020 4. our set of packageDefinitions see: nixCats.flake.outputs.packageDefinitions
1021
1022 It is now a function that takes a name, and returns your chosen Neovim package.
1023
1024 packages = nixpkgs.lib.genAttrs nixpkgs.lib.platforms.all (system: let
1025
1026 nixCatsBuilder = utils.baseBuilder luaPath {
1027 inherit nixpkgs system dependencyOverlays extra_pkg_config;
1028 } categoryDefinitions packageDefinitions;
1029 in {
1030
1031
1032 default = nixCatsBuilder defaultPackageName;
1033 });
1034
1035
1036 packages = nixpkgs.lib.genAttrs nixpkgs.lib.platforms.all (system: let
1037
1038 pkgs = import nixpkgs {
1039 inherit system;
1040 overlays = dependencyOverlays;
1041 config = extra_pkg_config;
1042 };
1043
1044 nixCatsBuilder = utils.baseBuilder luaPath {
1045
1046 inherit pkgs;
1047 } categoryDefinitions packageDefinitions;
1048 in {
1049
1050
1051 default = nixCatsBuilder defaultPackageName;
1052 });
1053
1054 ---------------------------------------------------------------------------------------
1055 Flake Exports and Export options nixCats.flake.outputs.exports
1056
1057 They look something like this:
1058
1059
1060
1061 utils.eachSystem nixpkgs.lib.platforms.all (system: let
1062
1063 nixCatsBuilder = utils.baseBuilder luaPath {
1064 inherit nixpkgs system dependencyOverlays extra_pkg_config;
1065 } categoryDefinitions packageDefinitions;
1066
1067
1068
1069 defaultPackage = nixCatsBuilder defaultPackageName;
1070
1071
1072
1073
1074 pkgs = import nixpkgs { inherit system; };
1075
1076
1077
1078
1079
1080 in
1081 {
1082
1083
1084
1085
1086 packages = utils.mkAllWithDefault defaultPackage;
1087
1088
1089
1090 devShells = {
1091 default = pkgs.mkShell {
1092 name = defaultPackageName;
1093 packages = [ defaultPackage ];
1094 inputsFrom = [ ];
1095 shellHook = ''
1096 '';
1097 };
1098 };
1099
1100 }) // {
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111 overlays = utils.makeOverlays luaPath {
1112
1113 inherit nixpkgs dependencyOverlays extra_pkg_config;
1114
1115 } categoryDefinitions packageDefinitions defaultPackageName;
1116
1117
1118
1119
1120 nixosModules.default = utils.mkNixosModules {
1121 inherit dependencyOverlays luaPath defaultPackageName
1122 categoryDefinitions packageDefinitions nixpkgs;
1123 };
1124
1125 homeModule = utils.mkHomeModules {
1126 inherit dependencyOverlays luaPath defaultPackageName
1127 categoryDefinitions packageDefinitions nixpkgs;
1128 };
1129
1130 inherit utils;
1131 inherit (utils) templates;
1132 };
1133
1134 nixCats.flake.outputs.utils
1135
1136 The <utils> set exports all the functions used in creating the format in the
1137 templates, including the main builder!
1138 (see :h nixCats.flake.outputs.builder for builder explanation)
1139
1140 In the interests of not repeating ourselves,
1141 a list of most functions exported in the <utils> set
1142 can be found here:
1143 https://nixcats.org/nixCats_utils.html
1144
1145 Missing from that list however,
1146 is an explanation of the internal <n2l> library
1147 nixCats uses to create the nixCats Lua plugin!
1148
1149 The library fully escapes all items passed to it,
1150 so usually you can't execute lua code in them.
1151 But you may still explicitly pass it lua code to execute at runtime
1152 by declaring them as inline lua types!
1153
1154 An intricate explanation of the full set
1155 of features the <n2l> library contains are below.
1156
1157 All other functions made available by
1158 the <utils> set are explained in the documentation
1159 at https://nixcats.org/nixCats_utils.html
1160
1161 nixCats.flake.outputs.utils.n2l
1162 <n2l> This is the Nix to Lua library nixCats
1163 uses to create the nixCats Lua plugin
1164 You may wish to use some functions from it.
1165
1166 The library is exported from the <utils> set as utils.n2l
1167
1168 It contains <toLua> and <prettyLua> and <uglyLua> which convert Nix values to Lua.
1169 It also contains a <toUnpacked> which converts a nix list
1170 to comma separated lua values for function arguments.
1171
1172 it contains a <member> function to determine if a value is a special "inline lua" type
1173 it contains a <typeof> function to determine which special "inline lua" type it is
1174 it contains a <resolve> function which knows how to resolve the types to a string of code
1175 it contains the <default_subtype> name as well.
1176
1177 But of much more interest to you is the types you may declare.
1178
1179 Everything being passed through settings, categories, and extra in packageDefinitions
1180 will be properly escaped. But this also means that
1181 you cannot write any Lua code there.
1182
1183 Luckily, we have some types we can declare that will allow you to do this.
1184
1185 To declare that an item is a Lua value rather than a hard coded one,
1186 you may choose one of these types. To do this, call its constructor!
1187
1188 for example, types.inline-unsafe has 1 field, body.
1189
1190 To declare one in our settings, categories, and extra sets, it would look
1191 something like this:
1192
1193 categories = {
1194 somecat = utils.n2l.types.inline-unsafe.mk {body = "vim.fn.stdpath('data')"; }`
1195 }
1196
1197 inline-safe is the default type, and it gets to define a shorthand form.
1198
1199 categories = {
1200 somecat = utils.n2l.types.inline-safe.mk "vim.fn.stdpath('data')";`
1201 }
1202
1203 These are all the types, each one has an associated mk
1204 function to create a value of that type,
1205 which accepts the fields listed here, defined with default values.
1206
1207
1208 inline-safe = {
1209 default = (v: if v ? body then v else { body = v; });
1210 fields = { body = "nil"; };
1211 format = LI: "assert(loadstring(${luaEnclose "return ${LI.expr.body or LI.expr or "nil"}"}))()";
1212 };
1213
1214 inline-unsafe = {
1215 fields = { body = "nil"; };
1216 format = LI: "${LI.expr.body or "nil"}";
1217 };
1218
1219
1220 function-safe = {
1221 fields = { body = "return nil"; args = []; };
1222 format = LI:
1223 ''assert(loadstring(${luaEnclose ''return (function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)''}))()'';
1224 };
1225
1226
1227 function-unsafe = {
1228 fields = { body = "return nil"; args = []; };
1229 format = LI: ''(function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)'';
1230 };
1231 with-meta = {
1232 fields = {
1233 table = {};
1234 meta = {};
1235 newtable = null;
1236 tablevar = "tbl_in";
1237 };
1238 format = LI: opts: let
1239 metaarg1 = if LI.expr.newtable or null == null then LI.expr.tablevar or "{}" else toLuaFull opts LI.expr.newtable;
1240 result = inline.types.function-unsafe.mk {
1241 args = [ (LI.expr.tablevar or "tbl_in") ];
1242 body = ''return setmetatable(${metaarg1}, ${toLuaFull opts LI.expr.meta})'';
1243 };
1244 in "${toLuaFull opts result}(${toLuaFull opts LI.expr.table})";
1245 };
1246
1247
1248 Some more useage examples:
1249
1250 exampleSafeFunc = utils.n2l.types.function-safe.mk {
1251 args = [ "hello" ];
1252 body = ''
1253 print(hello)
1254 return hi
1255 '';
1256 };
1257 exampleUnsafeFunc = utils.n2l.types.function-unsafe.mk {
1258 args = [ "hi" "hello" ];
1259 body = ''
1260 print(hi)
1261 print(hello)
1262 return hi .. hello
1263 '';
1264 };
1265 };
1266 funcResults = {
1267 test1 = utils.n2l.types.inline-safe.mk ''${utils.n2l.resolve exampleSafeFunc}("Hello World!")'';
1268 };
1269 lua_table_with_meta = utils.n2l.types.with-meta.mk (let
1270 tablevar = "tbl_in";
1271 in {
1272 table = {
1273 this = "is a test table";
1274 inatesttable = "that will be translated to a Lua table with a metatable";
1275 };
1276
1277
1278 inherit tablevar;
1279 meta = {
1280
1281 __call = utils.n2l.types.function-unsafe.mk {
1282 args = [ "self" "..." ];
1283 body = ''
1284 print("This table is named ${tablevar}")
1285 return ${tablevar}.this
1286 '';
1287 };
1288 };
1289
1290
1291
1292 newtable = null;
1293 });
1294
1295 ---------------------------------------------------------------------------------------
1296 vim:tw=78:ts=8:ft=help:norl: