HOME TOC REPO
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 ok, 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 if
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! Its the same one from
147  pkgs = import nixpkgs { inherit system; overlays = []; config = {}; }
148  
149    outputs = { self, nixpkgs, ... }@inputs: let
150      # In the templates, this is inherit (inputs.nixCats) utils;
151      inherit (inputs.nixCats) utils;
152      # path the the store path to be loaded as neovim config directory
153      luaPath = "${./.}";
154      # used when initializing the nixpkgs instance
155      extra_pkg_config = {
156        # allowUnfree = true;
157      };
158  
159                                             nixCats.flake.outputs.getOverlays
160  We call flake utils to get system variable for all default systems.
161  It simply calls the function with each system value, and maps the resulting
162  set from { mySet = {}; } to { mySet.${system} = {}; }
163  Many overlays require being accessed via ${system} variable in this manner,
164  and thus there is a method for handling it in nixCats.
165  
166  No overlays SHOULD be exported requiring the ${system} variable to access.
167  However, some are (such as codeium, a free ai plugin) and thus, we will wrap this anyway.
168  
169    inherit (utils.eachSystem nixpkgs.lib.platforms.all (system: let
170                    /* utils.eachSystem is just flake-utils.lib.eachSystem */
171           /* list of overlays from ./overlays is added to the rest of the list */
172      dependencyOverlays = (import ./overlays inputs) ++ [
173        # This overlay grabs all the inputs named in the format
174        # `plugins-<pluginName>`
175        # Once we add this overlay to our nixpkgs, we are able to
176        # use `pkgs.neovimPlugins`, which is a set of our plugins.
177        (utils.standardPluginOverlay inputs)
178        # add any flake overlays here.
179        inputs.neorg-overlay.overlays.default
180        inputs.lz-n.overlays.default
181        # stuff like this is why this part is done this way.
182        inputs.codeium.overlays.${system}.default
183      ];
184      # these overlays will be wrapped with ${system}
185      # and we will call the same utils.eachSystem function
186      # later on to access them.
187    in { inherit dependencyOverlays; })) dependencyOverlays;
188  
189  This will allow us to pass system independent overlays to our module options,
190  even when importing overlays from improperly formed flakes.
191  
192  Managing the system variable in combination with overlays
193  can be one of the hardest parts of flake usage.
194  This flake resolves our pkgs instance for neovim itself to help with this,
195  and takes care of passing the correct pkgs instance
196  to the categoryDefinitions for use in defining your plugins.
197  
198  ALTERNATIVELY
199  
200  They could also just be a list of overlays!
201  
202    dependencyOverlays = (import ./overlays inputs) ++ [
203      (utils.standardPluginOverlay inputs)
204      inputs.neorg-overlay.overlays.default
205      inputs.lz-n.overlays.default
206  
207      # when other people mess up their overlays by wrapping them,
208      # you may instead call this function on their overlay.
209      # it will check if it has the system in it.
210      # if so, it will call the function with the system
211      # and return the desired overlay
212      (utils.fixSystemizedOverlay inputs.codeium.overlays
213        (system: inputs.codeium.overlays.${system}.default)
214      )
215    ];
216  
217  
218                                                 nixCats.flake.outputs.overlays
219  The two major things of note in this overlays section.
220  Regardless of which above method you choose. 
221    (utils.standardPluginOverlay inputs) # return type: a single overlay
222    # and
223    (import ./overlays inputs) # type: List of Overlays
224  
225  <1>
226  -- The first to explain is utils.standardPluginOverlay:
227  You do not need to edit it to use it.
228  Usage of this overlay is described in:
229  :h nixCats.flake.inputs
230  along with its friend, utils.sanitizedPluginOverlay
231  
232  It takes all the inputs named in the format
233  plugins-somepluginname and makes them into plugins. 
234  If the plugin doesn't have a build step,
235  and it wasnt on nixpkgs, then use this method.
236  Access them to add them to a category of the builder function 
237  with pkgs.neovimPlugins.somepluginname
238  
239  <2>
240  -- The second is overlays/customBuildsOverlay.nix:
241  
242  It is imported via overlays/default.nix above
243  
244  If you need to interact with one of these overlays, it will be this one.
245  You should not need to do it much.
246  overlays/default.nix imports this overlay and any others like it.
247  see :help nixCats.flake.nixperts.overlays
248  
249  It is used for defining plugins with build steps that 
250  were not well handled by nixpkgs.
251  It is passed flake inputs, and super is pkgs.
252  Define the things within the file. 
253  Then, access plugins defined there later 
254  with 'pkgs.nixCatsBuilds.somepluginname'
255  
256  If you decide you wish to split your customBuildsOverlay up, 
257  see :help nixCats.flake.nixperts.overlays
258  or look at the overlays/default.nix file.
259  
260  <IMPORTANT> When defining your overlays, they will be
261  defined in a SEPARATE LIST named <dependencyOverlays>.
262  You will need <dependencyOverlays> later.
263  
264  ---------------------------------------------------------------------------------------
265                                              nixCats.flake.outputs.categories
266  Then we define what is in our categories!
267  This section is a function that takes the package definition for this
268  particular package as an argument.
269  The builder will call it with that argument, you may use it.
270  This allows categoryDefinitions to access their packages categories and settings,
271  which allows categoryDefinitions to be much more dynamic.
272  
273  It also gets mkNvimPlugin = src: name: as an argument. mkNvimPlugin takes a src, either flake input
274  or fetched drv, and then a name, and it returns a nvim plugin that can be further
275  overriden via overrideAttrs if desired.
276  There is an overlay to do this automatically from flake inputs, mentioned
277  above. But sometimes it can be advantageous to do one of them individually.
278  
279  These are the things you can return:
280  
281    categoryDefinitions = { pkgs, settings, categories, extra, name, mkNvimPlugin, ... }@packageDef: {
282  
283  <lspsAndRuntimeDeps>
284    a flexible set of categories, each containing LSP's or 
285    other internal runtime dependencies such as ctags or debuggers
286    these are available to the PATH while within the neovim program.
287    this includes the neovim terminal.
288  
289  <startupPlugins>
290    a flexible set of categories, each containing startup plugins.
291    Startup plugins are loaded and can be required. 
292  
293  <optionalPlugins>
294    a flexible set of categories, each containing optional plugins.
295    Optional plugins need to be added with packadd before being required.
296    Use :NixCats pawsible to see the names to use for packadd
297  
298  <sharedLibraries>
299    a flexible set of categories, each containing a derivation for
300    a runtime shared library. Will be prepended to the LD_LIBRARY_PATH variable.
301  
302  <environmentVariables>
303    a flexible set of categories, each containing an ATTRIBUTE SET of 
304    EnvironmentVariableName = "EnvironmentVariableValue";
305  
306  <extraWrapperArgs>
307    a flexible set of categories, each containing extra wrapper arguments.
308    If you don't know what that is, see here:
309  github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh
310  
311  <extraLuaPackages>
312    a flexible set of categories, each containing FUNCTIONS 
313    that return lists of extra Lua packages.
314    These functions are the same thing that you would pass to lua.withPackages.
315    Is used to populate $LUA_PATH and $LUA_CPATH
316  
317  <extraPython3Packages> 
318    a flexible set of categories, each containing FUNCTIONS
319    that return lists of python packages.
320    These functions are the same thing that you would pass to python.withPackages.
321    You may get the path to this python environment in your lua config via
322    vim.g.python3_host_prog
323    or run from nvim terminal via :!<packagename>-python3
324  
325  <extraPython3wrapperArgs>
326    the same as extraWrapperArgs but for bundled python3 executable
327  
328  <propagatedBuildInputs> 
329    a flexible set of categories, each containing internal BUILD dependencies.
330    Will not be available to the PATH unless in a devShell.
331    USING THIS OPTION WILL CAUSE NVIM TO BUILD FROM SOURCE.
332  
333  <optionalLuaPreInit>
334    a flexible set of categories, each containing a lua string
335    that will be ran before sourcing your init.lua
336    Yes it can access nixCats.
337    It is not the recommended way to create lua for this flake, 
338    but it may be useful in editing flake imports 
339    of other already configured setups following the nixCats format.
340  <optionalLuaAdditions>
341    a flexible set of categories, each containing a lua string
342    that will be ran after sourcing your init.lua
343    Yes it can access nixCats.
344    It is not the recommended way to create lua for this flake, 
345    but it may be useful in editing flake imports 
346    of other already configured setups following the nixCats format.
347  <bashBeforeWrapper>
348    a flexible set of categories, each containing arbitrary bash code
349    to run before the wrapper starts within the wrapper's bash environment.
350    CAUTION: only use this if you know what you are doing and why you need
351    to do it. Whenever possible, use extraWrapperArgs instead.
352  <extraCats>
353    a flexible set of categories, each containing a list of attribute paths,
354    specified as lists of strings. Thus each category would contain a list of
355    lists of strings.
356    Allows inclusion of extra categories contingent on each lists inclusion in the package,
357    and is useful for creating default values for subcategories.
358    For more info, see below at
359    :h nixCats.flake.outputs.categoryDefinitions.default_values
360    # WARNING: use of categories argument in this set will cause infinite recursion
361    # The categories argument of this function is the FINAL value.
362    # You may use it in any of the other sets.
363  }
364  
365  In essence, the contents of each set listed here are filtered
366  based on the packageDefinitions set you provide, 
367  whereby including categoryname = true; you enable that category.
368  :help nixCats.flake.outputs.packageDefinitions
369  
370  It will remove duplicate items, so feel free to include the same thing in
371  multiple categories if it suits your purposes.
372  
373  It does this recursively. (explained below)
374  
375  If, inside one of these main sets, you had another set,
376  it would consider that a subcategory, and you could enable it
377  just like you do with a normal category, by setting a value with the
378  corresponding attribute path to true in the category
379  set of nixCats.flake.outputs.packageDefinitions.
380  You can nest them as much as you like, or just have a category that is a
381  single derivation.
382  
383                              nixCats.flake.outputs.categoryDefinitions.schemas
384  
385   You may also use the variables passed to your categoryDefinitions function
386   to get access to the set of categories and settings that are being
387   used to define the current package being built!
388  
389      themer = with pkgs.vimPlugins;
390        (builtins.getAttr packageDef.categories.colorscheme {
391            # Theme switcher without creating a new category
392            "onedark" = onedark-vim;
393            "catppuccin" = catppuccin-nvim;
394          }
395        );
396  
397    In addition to all this, if a plugin is defined within a list, it may
398    instead be defined within an attribute set that also contains config
399    to be ran after sourcing init.lua and optionalLuaAdditions
400    to do this, you may use the following syntax in opt or start sections: 
401      [
402        # you may add a plugin to a category list in any of these ways
403        { plugin = derivation; config.lua = ""; config.vim = "";}
404        { plugin = derivation; config = ""; type = "<viml or lua>"; }
405        { plugin = derivation; config = ""; } # defaults to viml
406        { plugin = derivation; }
407        # all the above options can also accept an optional = bool;
408        # to override its presence in either startupPlugins or optionalPlugins
409        # and they can also accept a name = string; to override its name
410        derivation
411        # plain derivation does not need to be in a list, but it should be
412        # anyway. It could be on its own though and would act as its own
413        # category.
414      ]
415  
416                              nixCats.flake.outputs.categoryDefinitions.default_values
417  
418  There are 2 ways of creating default values in nixCats.
419  
420  #1 Implicit: when value is in another section of categoryDefinitions
421  
422  If in your categoryDefinitions you had the following:
423  
424      environmentVariables = {
425        test = {
426          subtest1 = {
427            CATTESTVAR = "It worked!";
428          };
429          subtest2 = {
430            CATTESTVAR3 = "It didn't work!";
431          };
432        };
433      };
434      extraWrapperArgs = {
435        test = [
436          '' --set CATTESTVAR2 "It worked again!"''
437        ];
438      };
439  
440  And in your packageDefinitions set, under categories, you had the following:
441  
442      test = {
443        subtest1 = true;
444      };
445  
446  you could echo $CATTESTVAR and $CATTESTVAR2 in your terminal to see them.
447  However you could not echo $CATTESTVAR3.
448  
449  All items that are not attributes of the parent set will be included
450  when you enable a subcategory. This includes lists, strings, functions, etc...
451  
452  However, attributes will not and you must explicitly enable all attributes of
453  a subcategory if you set even 1 explicitly.
454  
455  Thus to include CATTESTVAR3, you would have to enable it like so: 
456      test = {
457        subtest1 = true;
458        subtest2 = true;
459      };
460   However, those are all the items in the test category.
461  So instead we can do this to enable all the subcategories in test. 
462      test = true;
463  
464  This applies in many situations. Take this one for example.
465  
466      lspsAndRuntimeDeps = {
467        neonixdev = {
468          inherit (pkgs)
469            nix-doc nil lua-language-server nixd; 
470        };
471      };
472      startupPlugins = {
473        neonixdev = with pkgs.vimPlugins; [
474          neodev-nvim
475          neoconf-nvim
476        ];
477      };
478  
479   If you were to put the following in your packageDefinitions: 
480      neonixdev.nix-doc = true;
481  
482  neodev-nvim and neoconf-nvim would still be included.
483  However, nil, lua-language-server, and nixd would not be!
484  You would need to pick which of those you wanted separately.
485  Sometimes this is the desired behavior.
486  Sometimes it is not and a list of packages would be better suited.
487  
488  This leads us to our second way to make a default value:
489  
490  #2 Explicit: using extraCats section of categoryDefinitions.
491  
492  extraCats section of categoryDefinitions contains categories of attribute
493  paths. If that category is defined, the categories specified by the attribute
494  paths will also be enabled. This means you could make it so that if you
495  included the go category, it could then enable debug.go and lsp.go for you.
496  But in addition to that, it can be combined with the implicit form of creating
497  default values above in an interesting way.
498  
499    categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@packageDef: {
500      lspsAndRuntimeDeps = {
501        debug = with pkgs; {
502          go = [ delve ];
503        };
504        go = with pkgs; [
505          gopls
506          gotools
507          go-tools
508          gccgo
509        ];
510      };
511      startupPlugins = {
512        debug = with pkgs.vimPlugins; {
513          default = [
514            nvim-dap
515            nvim-dap-ui
516            nvim-dap-virtual-text
517          ];
518          go = [ nvim-dap-go ];
519        };
520      };
521      # WARNING: use of categories argument in this set will cause infinite recursion
522      # The categories argument of this function is the FINAL value.
523      # You may use it in any of the other sets.
524      extraCats = {
525        # due to the implicit form of default values in different sections,
526        # this will enable debug.default
527        # if any subcategory of debug is enabled
528        # thus, enabling debug.go would also enable debug.default
529        debug = [
530          [ "debug" "default" ]
531        ];
532        # and if go is enabled, it enables debug.go
533        # which then enables debug.default
534        go = [
535          [ "debug" "go" ] # yes it has to be a list of lists
536        ];
537      };
538    };
539  
540  ---------------------------------------------------------------------------------------
541  Package Generation:                           nixCats.flake.outputs.packageDefinitions
542  
543  generate packages by calling that builder function we just created.
544  Place them in the packageDefinitions set.
545  
546  First, pick the set of settings you wish to include.
547  
548  Then, pass it a set of named boolean values like this:
549  { categoryname1 = true; categoryname2 = false; etc... }
550  False may be omitted. True may not.
551  Only true matters for what plugins will be added.
552  
553  These categories are defined in the Builder function above 
554  by placing named lists of plugins in the flexible sets provided.
555  The category names are the names of those lists. 
556  Add a new list, then enable the category here.
557  
558  If you have categories with the same name in 
559  multiple different sets outlined above in the builder,
560  all plugins in those categories will be
561  included when you set "thatname = true;" here.
562  hence, general = true; will include the general lspsAndDeps category,
563  as well as the general startupPlugins category.
564  
565  an example package definition:
566  
567    packageDefinitions = {
568      nixCats = { pkgs, ... }: {
569        setting = {
570          wrapRc = true;
571          # nvimSRC = inputs.neovim;
572          aliases = [ "viCat" ];
573        };
574        categories = {
575          custom = true;
576          gitPlugins = true;
577          general = true;
578          neonixdev = true;
579  
580          # this does not have an associated category of plugins, 
581          # but lua can still check for it
582          lspDebugMode = false;
583  
584          # you could also pass something else and it calls 
585          # builtins.toString on it and passes it in as a string
586          theBestCat = "says meow!!!";
587          # maybe you need to pass a port or path in or something idk.
588          # you could :lua =nixCats("theBestCat")
589          # this nixCats("path.to.val") is the main category check function
590          # and it is built to mirror the nix category scheme as much as possible
591        };
592        extra = {
593          there_is = "also";
594          an_extra = "table";
595          for = ''if you dont want the main subcategory get function
596            to apply to something, or think it all being in categories is too
597            messy
598          '';
599          you_can = ''nixCats.extra("path.to.val")'';
600          for_safer = ''table access via vim.tbl_get'';
601        };
602      };
603    };
604  
605  You can use the nixCats plugin for the set you define here in your lua
606  It returns a lua table of the same format.
607  
608  see :help nixCats
609  
610  For more nuances on enabling categories and subcategories, see above at
611  :help nixCats.flake.outputs.categoryDefinitions.default_values
612  and
613  :help nixCats.flake.outputs.categoryDefinitions.schemas
614  
615  ----------------------------------------------------------------------------------------
616  Settings                                       nixCats.flake.outputs.settings
617  
618  These are the defaults:
619  
620      default_settings = {
621        # YOU ARE IN CHARGE OF MAKING SURE THESE ALIASES DO NOT COLLIDE WITH
622        # ANYTHING ELSE
623        # [ "takes" "a" "list" "of" "strings" "and" "makes" "an" "alias" "for" "each" ];
624        aliases = null;
625        viAlias = false;
626        vimAlias = false;
627  
628        # so that you can see it in the store
629        extraName = "";
630  
631        withRuby = true;
632        withPython3 = true;
633        withNodeJs = false;
634        withPerl = false;
635  
636        # do you want to package the lua from this flake in the store?
637        # or would you rather it just read it in your .config/<configDirName>?
638        # nixCats and this help will work either way.
639        # packages with wrapRc = false are for quick changes to lua.
640        # it is not for being ran from anywhere via nix run, because the config
641        # was not wrapped with the program.
642        wrapRc = true;
643  
644        # What should the name of the folder within standard directories
645        # i.e. .config, .local/share, .local/state, .cache, etc... be?
646        # This option is very useful when you want 
647        # to clone an unwrapped config straight to the .config dir.
648        # It is also helpful to prevent other nvim packages sharing data folders.
649        # see :help `$NVIM_APPNAME`
650        configDirName = "nvim";
651  
652        # Only active when wrapRc = false, this option allows you to specify
653        # an absolute path to the unwrapped config directory.
654        # This is not a nix path. This is the unwrapped config directory.
655        # This means you are going to need to make
656        # sure that it points the right place on the current machine.
657        unwrappedCfgPath = null;
658        # Will not change anything other than config directory, configDirName
659        # is still needed for .local/share or .cache and the like
660  
661        # use this to pin a specific neovim version.
662        # This one will specify the base neovim derivation to use.
663        neovim-unwrapped = null;
664        # This one will just override the src value of the neovim in nixpkgs
665        # import it in flake inputs with flake = false,
666        # It will also obviously cause neovim to build from source.
667        nvimSRC = null;
668  
669        # These 2 options are useful for when you want to allow your dev shells
670        # to override things such as lsps and shared libraries that you have
671        # already in your configuration.
672        suffix-path = false;
673        # causes lspsAndDeps to be added to the END of
674        # PATH instead of the start
675        suffix-LD = false;
676        # causes sharedLibraries to be added to the END of
677        # LD_LIBRARY_PATH instead of the start
678  
679        # whether to group up treesitter grammars into a single directory,
680        # or leave them as separate plugins.
681        # Defaults to true as it results in
682        # a significant startup time performance boost
683        # Works only on grammars that have been passed through
684        # pkgs.neovimUtils.grammarToPlugin
685        # or pkgs.vimPlugins.nvim-treesitter.withPlugins
686        collate_grammars = true;
687  
688        # unsets PYTHONSAFEPATH variable.
689        # Can cause issues with reproducibility,
690        # can fix some stuff
691        disablePythonSafePath = false;
692  
693        # optional, specify custom store path gemdir
694        # must contain a gemset.nix like one generated by bundix
695        # must contain the neovim gem
696        # for further info, see
697        # https://github.com/NixOS/nixpkgs/tree/74ad6cb1d2b14edb4ad1fffc0791e94910c61453/pkgs/applications/editors/neovim/ruby_provider
698        # https://github.com/BirdeeHub/neovim_ruby_updater
699        gem_path = null;
700        # If you are using neovim-unwrapped from nixpkgs itself,
701        # there is a good chance your neovim
702        # will not be able to find it regardless of settings.
703        # thus withRuby and gem_path options may not work
704        # It works great using https://github.com/nix-community/neovim-nightly-overlay
705        # so this seems to be an upstream issue, as all the expected variables
706        # are still being set correctly.
707  
708        # each package outputs a module via passthru.
709        # this will set the namespace for the module options
710        # by default will be at config.${packagename}
711        moduleNamespace = [ <packagename> ];
712      };
713  
714  
715  QUICK TIP: wrapRc
716  
717  The wrapRc option is very useful for testing lua changes.
718  It removes the need to stage and rebuild to see your lua changes reflected.
719  You will still need to rebuild when making changes to nix regardless of the
720  value of wrapRc
721  
722  However it also means that the lua isn't going run if it isn't in the right
723  folder, i.e. when installed and ran from github with nix run
724  
725  If the lua is not in vim.fn.stdpath('config'), wrapRc = false will not work.
726  By default this is ~/.config/nvim on linux systems, although we can
727  change nvim to whatever we wish via the configDirName setting.
728  
729  Alternatively, you can set the unwrappedCfgPath option to allow the
730  configuration to be set to an absolute path. You still may want to set
731  the configDirName option anyway to change the data directories,
732  or explicitly keep it the same on both so that they share stuff like auths.
733  
734  The most convenient way to use this is the following:
735  Make a second identical packageDefinition, but with wrapRc disabled.
736  Then install both the wrapped one and unwrapped one with different aliases.
737  When you want to hack in lua, use unwrapped! When you're done, just rebuild
738  and go back to the wrapped one.
739  
740  The templates/example/flake.nix file from the example config template
741  has an example of this with nixCats and regularCats.
742  
743  Then, when testing lua changes, you run the other package and have a vanilla
744  neovim experience, only rebuilding when you install new packages.
745  
746  When you are satisfied, simply rebuild and go back to using the main package,
747  as it was the same except for the single option!
748  
749  --------------------------------------------------------------------------------------
750  Neovim Builder Creation:                        nixCats.flake.outputs.builder
751  
752  Now we define our builder function.
753  We inherit utils.baseBuilder which is
754  a function that takes 5 arguments. It is defined in ./builder
755  Right now we are going to call it with just the first 4 of them. This will
756  leave us with a function that takes 1 argument.
757  That argument is the name of the neovim package to be packaged.
758  
759  1. The path to the lua to include (in the flake, we use the self variable to get
760       this path and wrap the lua when wrapRc = true)
761  
762  2. A set containing:
763    The dependencyOverlays set or list,
764    extra_pkg_config, nixpkgs, nixCats_passthru, and system so it can
765    resolve pkgs and pass it where it needs to go.
766  
767  3. our function that takes an individual package definition
768       and returns a set of categoryDefinitions.
769  
770  4. our set of packageDefinitions see: nixCats.flake.outputs.packageDefinitions
771  
772  It is now a function that takes a name, and returns your chosen neovim package.
773  
774    # It requires the system variable to build a package.
775    utils.eachSystem nixpkgs.lib.platforms.all (system: let
776      # create our builder for our exports
777      inherit (utils) baseBuilder;
778      nixCatsBuilder = baseBuilder luaPath {
779        inherit nixpkgs system dependencyOverlays extra_pkg_config;
780      } categoryDefinitions packageDefinitions;
781      # it can take a name of a package in packageDefinitions
782      # and return the package!
783      defaultPackage = nixCatsBuilder defaultPackageName;
784      # ... rest of the outputs section explained
785      # below in :h nixCats.flake.outputs.exports ...
786  
787  If you use it wrong, you will most likely get this error message:
788  
789    The following arguments are accepted:
790  
791    # -------------------------------------------------------- #
792  
793    # the path to your ~/.config/nvim replacement within your nix config.
794    luaPath: # <-- must be a store path
795  
796    { # set of items for building the pkgs that builds your neovim
797  
798      , nixpkgs # <-- required
799      , system # <-- required
800  
801      # type: (attrsOf listOf overlays) or (listOf overlays) or null
802      , dependencyOverlays ? null 
803  
804      # import nixpkgs { config = extra_pkg_config; inherit system; }
805      , extra_pkg_config ? {} # type: attrs
806  
807      # any extra stuff for finalPackage.passthru
808      , nixCats_passthru ? {} # type: attrs
809    }:
810  
811    # type: function with args { pkgs, settings, categories, name, ... }:
812    # returns: set of sets of categories
813    # see :h nixCats.flake.outputs.categories
814    categoryDefinitions: 
815  
816    # type: function with args { pkgs, ... }:
817    # returns: { settings = {}; categories = {}; }
818    packageDefinitions: 
819    # see :h nixCats.flake.outputs.packageDefinitions
820    # see :h nixCats.flake.outputs.settings
821  
822    # name of the package to built from packageDefinitions
823    name: 
824  
825    # -------------------------------------------------------- #
826  
827    # Note:
828    When using override, all values shown above will
829    be top level attributes of prev, none will be nested.
830    i.e. 
831    finalPackage.override (prev: { inherit (prev) dependencyOverlays; })
832        NOT prev.pkgsargs.dependencyOverlays or something like that
833  
834  ---------------------------------------------------------------------------------------
835  Flake Exports and Export options               nixCats.flake.outputs.exports
836  
837  They look something like this:
838  
839    # this first section is the outputs we
840    # want to wrap with the ${system} variable
841    utils.eachSystem nixpkgs.lib.platforms.all (system: let
842      # this is the builder (see :h nixCats.flake.outputs.builder above):
843      nixCatsBuilder = utils.baseBuilder luaPath {
844        inherit nixpkgs system dependencyOverlays extra_pkg_config;
845      } categoryDefinitions packageDefinitions;
846      # then it takes our categoryDefinitions and packageDefinitions
847  
848      # then we build a package to serve as the default one by providing its name.
849      defaultPackage = nixCatsBuilder defaultPackageName;
850  
851      # this is just for using utils in the following section such as pkgs.mkShell
852      # The one used to build neovim is resolved inside the builder
853      # and is passed to our categoryDefinitions and packageDefinitions
854      pkgs = import nixpkgs { inherit system; };
855      # as you can see, "resolve pkgs" does not mean anything fancy.
856      # however, with overlays and system variable,
857      # sometimes you can get yourself in a loop when
858      # doing more advanced things. So this flake takes care of that for you.
859      # it will make sure pkgs is passed to the categoryDefinitions and packageDefinitions
860    in
861    {
862      # these outputs will be wrapped with ${system} by utils.eachSystem
863  
864      # this will make a package out of each of the packageDefinitions defined above
865      # and set the default package to the one passed in here.
866      packages = utils.mkAllWithDefault defaultPackage;
867  
868      # choose your package for devShell
869      # and add whatever else you want in it.
870      devShells = {
871        default = pkgs.mkShell {
872          name = defaultPackageName;
873          packages = [ defaultPackage ];
874          inputsFrom = [ ];
875          shellHook = ''
876          '';
877        };
878      };
879  
880    }) // {
881  
882      # these outputs will be NOT wrapped with ${system}
883  
884      # now we can export some things that can be imported in other
885      # flakes, WITHOUT needing to use a system variable to do it.
886      # and update them into the rest of the outputs returned by the
887      # eachSystem function.
888  
889      # this will make an overlay out of each of the packageDefinitions defined
890      # and set the default overlay to the one named here.
891      overlays = utils.makeOverlays luaPath {
892        # we pass in the things to make a pkgs variable to build nvim with later
893        inherit nixpkgs dependencyOverlays extra_pkg_config;
894        # and also our categoryDefinitions
895      } categoryDefinitions packageDefinitions defaultPackageName;
896  
897      # we export a nixos module to allow configuration from configuration.nix
898      # allows you to either inherit values from your main flake, or start fresh
899      nixosModules.default = utils.mkNixosModules {
900        inherit dependencyOverlays luaPath defaultPackageName
901          categoryDefinitions packageDefinitions nixpkgs;
902      };
903      # and the same for home manager
904      homeModule = utils.mkHomeModules {
905        inherit dependencyOverlays luaPath defaultPackageName
906          categoryDefinitions packageDefinitions nixpkgs;
907      };
908      inherit utils;
909      inherit (utils) templates;
910    };
911  
912                                    nixCats.flake.outputs.utils
913  
914  We also export the <utils> set so we can get it easier later,
915  along with <templates> which are inside it.
916  The <utils> is also exported by the passthru of all packages based on nixCats
917  but exporting it separately makes it easier to get again later.
918  
919  It also contains all the other functions used in creating the format in the
920  templates, including the main builder!
921  (see :h nixCats.flake.outputs.builder for builder explanation)
922  
923  In addition to the templates and the builder function, the utils set contains:
924  
925  <standardPluginOverlay> inputs:
926  allows for inputs named plugins-something to be
927  turned into an overlay containing them as plugins automatically
928  
929  <sanitizedPluginOverlay> inputs:
930  optional replacement for utils.standardPluginOverlay.
931  If you give it an input named plugins-foo.bar
932  you can get it at pkgs.neovimPlugins.foo-bar
933  and still packadd foo.bar because it keeps the folder name the same.
934  To use, in your overlays section:
935  Replace (utils.standardPluginOverlay inputs)
936  with (utils.sanitizedPluginOverlay inputs)
937  
938  <fixSystemizedOverlay> overlaysSet: outfunc:
939  takes 2 arguments.
940  a set of system-wrapped overlays,
941  and a function (system: overlays.${system}.<desired_overlay>)
942  returns the desired overlay, with the system resolved.
943  
944  <mergeCatDefs> oldCats: newCats:
945  for merging categoryDefinitions and individual packages in packageDefinitions,
946  will recursively update up to the first thing not an attrset.
947  For our purposes, we do not consider derivations to be attrsets.
948  It takes 2 functions that return sets and returns
949  a function which calls them both and merges the result as desired above.
950  
951  <deepmergeCats> oldCats: newCats:
952  same as utils.mergeCatDefs except will merge duplicate
953  category lists together instead of replacing them
954  
955  <mergeOverlayLists> oldOverlist: newOverlist: self: super:
956  for merging lists of overlays together properly
957  to avoid naming conflict issues.
958  Takes 2 lists of overlays, returns a single merged overlay.
959  Merging logic is the same as mergeCatDefs
960  
961  <safeOversList> { dependencyOverlays, system ? null }:
962  Simple helper function for mergeOverlayLists
963  Pass it the inherited dependencyOverlays, always recieve a list back.
964  Then feed it to mergeOverlayLists.
965  If dependencyOverlays is an attrset, system string is required.
966  If dependencyOverlays is a list, system string is ignored
967  If invalid type or system, returns an empty list
968  
969  <mkNixosModules> {
970      defaultPackageName = "nixCats";
971      luaPath = "${./.}";
972      inherit nixpkgs dependencyOverlays
973        categoryDefinitions packageDefinitions extra_pkg_config;
974  };
975  Will create a nixos module that you can import in configuration.nix
976  If you do not have a luaPath, you may pass it a keepLua builder
977  See :help nixCats.flake.outputs.exports.mkNixosModules
978  The packages also export a module with defaultPackageName
979  set to THEIR package name via their passthru variable using this function.
980  
981  <mkHomeModules>
982  The same as mkNixosModules above, but for home manager.
983  
984  <mkAllWithDefault> package:
985  makes each package in the packageDefinitions this package was made from
986  and also a default one out of the one passed in.
987  
988  <mkAllPackages> package:
989  makes each package in the packageDefinitions this package was made from
990  
991  <mkPackages> finalBuilder: packageDefinitions: defaultName:
992  makes each package in packageDefinitions and also a default one
993  where finalBuilder is the builder function with all but the name applied
994  
995  <mkExtraPackages> finalBuilder: packageDefinitions:
996  mkPackages just calls this and adds a default one.
997  where finalBuilder is the builder function with all but the name applied
998  
999  <makeOverlays> luaPath: {
1000         nixpkgs
1001         , extra_pkg_config ? {}
1002         , dependencyOverlays ? null
1003         , nixCats_passthru ? {}
1004         , ...
1005       }@pkgsParams: categoryDefFunction: packageDefinitions:
1006       defaultName:
1007 makes an overlay for each package and also a default one
1008 These are basically the same as the arguments to utils.baseBuilder
1009 dependencyOverlays may be dependencyOverlays.${system} = [ list of overlays ];
1010 or simply dependencyOverlays = [ list of overlays ];
1011 
1012 <makeMultiOverlay> <same args as makeOverlays BUT with the following 2 args INSTEAD of defaultName>:
1013             importName: namesIncList:
1014 Instead of taking a defaultName, it takes an importName and a list of names.
1015 It will output them in an overlay where they will be accessible by pkgs.${importName}.${name}
1016 
1017 <makeOverlaysWithMultiDefault> utils.makeOverlays but the default overlay
1018 uses makeMultiOverlay. So that after adding it, all your packages from packageDefinitions will
1019 be accessible at pkgs.${defaultPackageName}.${packageName}
1020 Can be swapped out 1 for 1 with utils.makeOverlays if preferred
1021 
1022 <easyMultiOverlay> package:
1023 i.e. if you had a package named nvim1 and a package named nvim2,
1024 would output an overlay containing both pkgs.nvim1 and pkgs.nvim2
1025 
1026 Takes as its argument only a finished nixCats package.
1027 Utilizes override to avoid wrapping the overlay with ${system} variable.
1028 
1029 Slightly different from makeMultiOverlay in that
1030 makeMultiOverlay would output at pkgs.${importName}.nvim1
1031 instead of pkgs.nvim1 like this one does.
1032 
1033 <easyMultiOverlayNamespaced> package: importName:
1034 If you had a package named nvim1 and a package named nvim2,
1035 would output an overlay containing
1036 both pkgs.${importName}.nvim1 and pkgs.${importName}.nvim2
1037 
1038 Takes as its argument only a finished nixCats package.
1039 Utilizes override to avoid wrapping the overlay with ${system} variable.
1040 
1041 identical output to makeMultiOverlay
1042 
1043 <easyNamedOvers> package:
1044 Same output as makeOverlays except without a default package.
1045 i.e. if you had a package named nvim1 and a package named nvim2,
1046 would make an overlay named nvim1 and an overlay named nvim2
1047 
1048 Takes as its argument only a finished nixCats package.
1049 Utilizes override to avoid wrapping the overlay with ${system} variable
1050 
1051 <eachSystem> systems: f:
1052 just flake-utils.lib.eachSystem copied here to remove the final input outside
1053 of nixpkgs itself.
1054 
1055 <bySystem> systems: f:
1056 similar to flake-utils.lib.eachSystem but for only 1 variable. If used for the
1057 whole outputs section instead of eachSystem, it would add the
1058 ${system} to the start like ${system}.packages.default and not
1059 packages.${system}.default so instead it is used for only a single output like:
1060 { packages = utils.bySystem nixpkgs.lib.platforms.all (system: { default = ...; }) }
1061 
1062 It is the same thing as nixpkgs.lib.genAttrs, renamed so that people know
1063 how to use it.
1064 
1065                                   nixCats.flake.outputs.utils.n2l
1066 <n2l> This is the nix to lua library nixCats
1067 uses to create the nixCats lua plugin
1068 You may wish to use some functions from it.
1069 
1070 It contains <toLua> and <prettyLua> and <uglyLua> which convert nix to lua.
1071 
1072 it contains a <member> function to determine if a value is a special "inline lua" type
1073 it contains a <typeof> function to determine which special "inline lua" type it is
1074 it contains a <resolve> function which knows how to resolve the types to a string of code
1075 it contains the <default_subtype> name as well.
1076 
1077 But of much more interest to you is the types you may declare.
1078 
1079 Everything being passed through settings, categories, and extra in packageDefinitions
1080 will be properly escaped. But this also means that
1081 you cannot write any lua code there.
1082 
1083 Luckily, we have some types we can declare that will allow you to do this.
1084 
1085 To declare that an item is a lua value rather than a hard coded one,
1086 you may choose one of these types. To do this, call its constructor!
1087 
1088 for example, types.inline-unsafe has 1 field, body.
1089 
1090 To declare one in our settings, categories, and extra sets, it would look
1091 something like this:
1092 
1093   categories = {
1094     somecat = utils.n2l.types.inline-unsafe.mk {body = "vim.fn.stdpath('data')"; }`
1095   }
1096 
1097 inline-safe is the default type, and it gets to define a shorthand form.
1098 
1099   categories = {
1100     somecat = utils.n2l.types.inline-safe.mk "vim.fn.stdpath('data')";`
1101   }
1102 
1103 These are all the types, each one has an associated mk
1104 function to create a value of that type,
1105 which accepts the fields listed here, defined with default values.
1106 
1107   # creates an inline lua value in a way that cant break the table
1108   inline-safe = {
1109     default = (v: if v ? body then v else { body = v; });
1110     fields = { body = "nil"; };
1111     format = LI: "assert(loadstring(${luaEnclose "return ${LI.expr.body or LI.expr or "nil"}"}))()";
1112   };
1113   # iterpolates whatever string you provide into the table raw
1114   inline-unsafe = {
1115     fields = { body = "nil"; };
1116     format = LI: "${LI.expr.body or "nil"}";
1117   };
1118   # creates a function with args of the names given in args list
1119   # does so in a way where you cannot accidentally break the table
1120   function-safe = {
1121     fields = { body = "return nil"; args = []; };
1122     format = LI: 
1123       ''assert(loadstring(${luaEnclose ''return (function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)''}))()'';
1124   };
1125   # creates a function with args of the names given in args list
1126   # interpolates the body segment raw, just like inline-unsafe, but in a function
1127   function-unsafe = {
1128     fields = { body = "return nil"; args = []; };
1129     format = LI: ''(function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)'';
1130   };
1131   with-meta = {
1132     fields = {
1133       table = {}; # <- the table you are adding
1134       meta = {}; # <- the metatable you want to add to it (in nix)
1135       newtable = null; # <- if you want to specify a different first arg to setmetatable
1136       tablevar = "tbl_in"; # <- varname to refer to the table, to avoid translating multiple times
1137     };
1138     format = LI: opts: let
1139       metaarg1 = if LI.expr.newtable or null == null then LI.expr.tablevar or "{}" else toLuaFull opts LI.expr.newtable;
1140       result = inline.types.function-unsafe.mk {
1141         args = [ (LI.expr.tablevar or "tbl_in") ];
1142         body = ''return setmetatable(${metaarg1}, ${toLuaFull opts LI.expr.meta})'';
1143       };
1144     in "${toLuaFull opts result}(${toLuaFull opts LI.expr.table})";
1145   };
1146 
1147 
1148 Some more useage examples:
1149 
1150   exampleSafeFunc = utils.n2l.types.function-safe.mk {
1151     args = [ "hello" ];
1152     body = /*lua*/ ''
1153       print(hello)
1154       return hi
1155     '';
1156   };
1157   exampleUnsafeFunc = utils.n2l.types.function-unsafe.mk {
1158     args = [ "hi" "hello" ];
1159     body = /*lua*/ ''
1160       print(hi)
1161       print(hello)
1162       return hi .. hello
1163     '';
1164   };
1165   };
1166   funcResults = {
1167     test1 = utils.n2l.types.inline-safe.mk ''${utils.n2l.resolve exampleSafeFunc}("Hello World!")'';
1168   };
1169   lua_table_with_meta = utils.n2l.types.with-meta.mk (let
1170     tablevar = "tbl_in";
1171   in {
1172     table = {
1173       this = "is a test table";
1174       inatesttable = "that will be translated to a lua table with a metatable";
1175     };
1176     # to avoid translating the table multiple times,
1177     # define a variable name for it in lua. Defaults to "tbl_in"
1178     inherit tablevar;
1179     meta = {
1180       # __call in lua lets us also call it like a function
1181       __call = utils.n2l.types.function-unsafe.mk {
1182         args = [ "self" "..." ];
1183         body = ''
1184           print("This table is named ${tablevar}")
1185           return ${tablevar}.this
1186         '';
1187       };
1188     };
1189     # you can change it to set the metatable of
1190     # and return a different table instead.
1191     # sometimes done so that access always uses __index function
1192     newtable = null; # <- default val, sets metatable of tablevar
1193   });
1194 
1195 ---------------------------------------------------------------------------------------
1196 Nix OS Module                     nixCats.flake.outputs.exports.mkNixosModules
1197                                   nixCats.flake.outputs.exports.mkHomeModules
1198 
1199 We create the module by exporting the following in our flake outputs.
1200 More information on the modules can be found at :h nixCats.module
1201 
1202 <mkNixosModules> {
1203     defaultPackageName = "nixCats";
1204     luaPath = "${./.}";
1205     inherit nixpkgs dependencyOverlays
1206       categoryDefinitions packageDefinitions extra_pkg_config;
1207 };
1208 
1209 <mkHomeModules> {
1210     defaultPackageName = "nixCats";
1211     luaPath = "${./.}";
1212     inherit nixpkgs dependencyOverlays
1213       categoryDefinitions packageDefinitions extra_pkg_config;
1214 };
1215 
1216 dependencyOverlays may be dependencyOverlays.${system} = [ list of overlays ];
1217 or simply dependencyOverlays = [ list of overlays ];
1218 
1219 IMPORTANT
1220 By default, the module inherits your flake or nixExpressionFlakeOutputs nixpkgs object,
1221 and its overlays, and everything else.
1222 It will still inherit your system overlays and config set and system value,
1223 but your system will not inherit overlays added to the nixCats module option.
1224 
1225 More information on the modules can be found at :h nixCats.module
1226 
1227 ---------------------------------------------------------------------------------------
1228 vim:tw=78:ts=8:ft=help:norl: