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  
709  
710  QUICK TIP: wrapRc
711  
712  The wrapRc option is very useful for testing lua changes.
713  It removes the need to stage and rebuild to see your lua changes reflected.
714  You will still need to rebuild when making changes to nix regardless of the
715  value of wrapRc
716  
717  However it also means that the lua isn't going run if it isn't in the right
718  folder, i.e. when installed and ran from github with nix run
719  
720  If the lua is not in vim.fn.stdpath('config'), wrapRc = false will not work.
721  By default this is ~/.config/nvim on linux systems, although we can
722  change nvim to whatever we wish via the configDirName setting.
723  
724  Alternatively, you can set the unwrappedCfgPath option to allow the
725  configuration to be set to an absolute path. You still may want to set
726  the configDirName option anyway to change the data directories,
727  or explicitly keep it the same on both so that they share stuff like auths.
728  
729  The most convenient way to use this is the following:
730  Make a second identical packageDefinition, but with wrapRc disabled.
731  Then install both the wrapped one and unwrapped one with different aliases.
732  When you want to hack in lua, use unwrapped! When you're done, just rebuild
733  and go back to the wrapped one.
734  
735  The templates/example/flake.nix file from the example config template
736  has an example of this with nixCats and regularCats.
737  
738  Then, when testing lua changes, you run the other package and have a vanilla
739  neovim experience, only rebuilding when you install new packages.
740  
741  When you are satisfied, simply rebuild and go back to using the main package,
742  as it was the same except for the single option!
743  
744  --------------------------------------------------------------------------------------
745  Neovim Builder Creation:                        nixCats.flake.outputs.builder
746  
747  Now we define our builder function.
748  We inherit utils.baseBuilder which is
749  a function that takes 5 arguments. It is defined in ./builder
750  Right now we are going to call it with just the first 4 of them. This will
751  leave us with a function that takes 1 argument.
752  That argument is the name of the neovim package to be packaged.
753  
754  1. The path to the lua to include (in the flake, we use the self variable to get
755       this path and wrap the lua when wrapRc = true)
756  
757  2. A set containing:
758    The dependencyOverlays set or list,
759    extra_pkg_config, nixpkgs, nixCats_passthru, and system so it can
760    resolve pkgs and pass it where it needs to go.
761  
762  3. our function that takes an individual package definition
763       and returns a set of categoryDefinitions.
764  
765  4. our set of packageDefinitions see: nixCats.flake.outputs.packageDefinitions
766  
767  It is now a function that takes a name, and returns your chosen neovim package.
768  
769    # It requires the system variable to build a package.
770    utils.eachSystem nixpkgs.lib.platforms.all (system: let
771      # create our builder for our exports
772      inherit (utils) baseBuilder;
773      nixCatsBuilder = baseBuilder luaPath {
774        inherit nixpkgs system dependencyOverlays extra_pkg_config;
775      } categoryDefinitions packageDefinitions;
776      # it can take a name of a package in packageDefinitions
777      # and return the package!
778      defaultPackage = nixCatsBuilder defaultPackageName;
779      # ... rest of the outputs section explained
780      # below in :h nixCats.flake.outputs.exports ...
781  
782  If you use it wrong, you will most likely get this error message:
783  
784    The following arguments are accepted:
785  
786    # -------------------------------------------------------- #
787  
788    # the path to your ~/.config/nvim replacement within your nix config.
789    luaPath: # <-- must be a store path
790  
791    { # set of items for building the pkgs that builds your neovim
792  
793      , nixpkgs # <-- required
794      , system # <-- required
795  
796      # type: (attrsOf listOf overlays) or (listOf overlays) or null
797      , dependencyOverlays ? null 
798  
799      # import nixpkgs { config = extra_pkg_config; inherit system; }
800      , extra_pkg_config ? {} # type: attrs
801  
802      # any extra stuff for finalPackage.passthru
803      , nixCats_passthru ? {} # type: attrs
804    }:
805  
806    # type: function with args { pkgs, settings, categories, name, ... }:
807    # returns: set of sets of categories
808    # see :h nixCats.flake.outputs.categories
809    categoryDefinitions: 
810  
811    # type: function with args { pkgs, ... }:
812    # returns: { settings = {}; categories = {}; }
813    packageDefinitions: 
814    # see :h nixCats.flake.outputs.packageDefinitions
815    # see :h nixCats.flake.outputs.settings
816  
817    # name of the package to built from packageDefinitions
818    name: 
819  
820    # -------------------------------------------------------- #
821  
822    # Note:
823    When using override, all values shown above will
824    be top level attributes of prev, none will be nested.
825    i.e. 
826    finalPackage.override (prev: { inherit (prev) dependencyOverlays; })
827        NOT prev.pkgsargs.dependencyOverlays or something like that
828  
829  ---------------------------------------------------------------------------------------
830  Flake Exports and Export options               nixCats.flake.outputs.exports
831  
832  They look something like this:
833  
834    # this first section is the outputs we
835    # want to wrap with the ${system} variable
836    utils.eachSystem nixpkgs.lib.platforms.all (system: let
837      # this is the builder (see :h nixCats.flake.outputs.builder above):
838      nixCatsBuilder = utils.baseBuilder luaPath {
839        inherit nixpkgs system dependencyOverlays extra_pkg_config;
840      } categoryDefinitions packageDefinitions;
841      # then it takes our categoryDefinitions and packageDefinitions
842  
843      # then we build a package to serve as the default one by providing its name.
844      defaultPackage = nixCatsBuilder defaultPackageName;
845  
846      # this is just for using utils in the following section such as pkgs.mkShell
847      # The one used to build neovim is resolved inside the builder
848      # and is passed to our categoryDefinitions and packageDefinitions
849      pkgs = import nixpkgs { inherit system; };
850      # as you can see, "resolve pkgs" does not mean anything fancy.
851      # however, with overlays and system variable,
852      # sometimes you can get yourself in a loop when
853      # doing more advanced things. So this flake takes care of that for you.
854      # it will make sure pkgs is passed to the categoryDefinitions and packageDefinitions
855    in
856    {
857      # these outputs will be wrapped with ${system} by utils.eachSystem
858  
859      # this will make a package out of each of the packageDefinitions defined above
860      # and set the default package to the one passed in here.
861      packages = utils.mkAllWithDefault defaultPackage;
862  
863      # choose your package for devShell
864      # and add whatever else you want in it.
865      devShells = {
866        default = pkgs.mkShell {
867          name = defaultPackageName;
868          packages = [ defaultPackage ];
869          inputsFrom = [ ];
870          shellHook = ''
871          '';
872        };
873      };
874  
875    }) // {
876  
877      # these outputs will be NOT wrapped with ${system}
878  
879      # now we can export some things that can be imported in other
880      # flakes, WITHOUT needing to use a system variable to do it.
881      # and update them into the rest of the outputs returned by the
882      # eachSystem function.
883  
884      # this will make an overlay out of each of the packageDefinitions defined
885      # and set the default overlay to the one named here.
886      overlays = utils.makeOverlays luaPath {
887        # we pass in the things to make a pkgs variable to build nvim with later
888        inherit nixpkgs dependencyOverlays extra_pkg_config;
889        # and also our categoryDefinitions
890      } categoryDefinitions packageDefinitions defaultPackageName;
891  
892      # we export a nixos module to allow configuration from configuration.nix
893      # allows you to either inherit values from your main flake, or start fresh
894      nixosModules.default = utils.mkNixosModules {
895        inherit dependencyOverlays luaPath defaultPackageName
896          categoryDefinitions packageDefinitions nixpkgs;
897      };
898      # and the same for home manager
899      homeModule = utils.mkHomeModules {
900        inherit dependencyOverlays luaPath defaultPackageName
901          categoryDefinitions packageDefinitions nixpkgs;
902      };
903      inherit utils;
904      inherit (utils) templates;
905    };
906  
907                                    nixCats.flake.outputs.utils
908  
909  We also export the <utils> set so we can get it easier later,
910  along with <templates> which are inside it.
911  The <utils> is also exported by the passthru of all packages based on nixCats
912  but exporting it separately makes it easier to get again later.
913  
914  It also contains all the other functions used in creating the format in the
915  templates, including the main builder!
916  (see :h nixCats.flake.outputs.builder for builder explanation)
917  
918  In addition to the templates and the builder function, the utils set contains:
919  
920  <standardPluginOverlay> inputs:
921  allows for inputs named plugins-something to be
922  turned into an overlay containing them as plugins automatically
923  
924  <sanitizedPluginOverlay> inputs:
925  optional replacement for utils.standardPluginOverlay.
926  If you give it an input named plugins-foo.bar
927  you can get it at pkgs.neovimPlugins.foo-bar
928  and still packadd foo.bar because it keeps the folder name the same.
929  To use, in your overlays section:
930  Replace (utils.standardPluginOverlay inputs)
931  with (utils.sanitizedPluginOverlay inputs)
932  
933  <fixSystemizedOverlay> overlaysSet: outfunc:
934  takes 2 arguments.
935  a set of system-wrapped overlays,
936  and a function (system: overlays.${system}.<desired_overlay>)
937  returns the desired overlay, with the system resolved.
938  
939  <mergeCatDefs> oldCats: newCats:
940  for merging categoryDefinitions and individual packages in packageDefinitions,
941  will recursively update up to the first thing not an attrset.
942  For our purposes, we do not consider derivations to be attrsets.
943  It takes 2 functions that return sets and returns
944  a function which calls them both and merges the result as desired above.
945  
946  <deepmergeCats> oldCats: newCats:
947  same as utils.mergeCatDefs except will merge duplicate
948  category lists together instead of replacing them
949  
950  <mergeOverlayLists> oldOverlist: newOverlist: self: super:
951  for merging lists of overlays together properly
952  to avoid naming conflict issues.
953  Takes 2 lists of overlays, returns a single merged overlay.
954  Merging logic is the same as mergeCatDefs
955  
956  <safeOversList> { dependencyOverlays, system ? null }:
957  Simple helper function for mergeOverlayLists
958  Pass it the inherited dependencyOverlays, always recieve a list back.
959  Then feed it to mergeOverlayLists.
960  If dependencyOverlays is an attrset, system string is required.
961  If dependencyOverlays is a list, system string is ignored
962  If invalid type or system, returns an empty list
963  
964  <mkNixosModules> {
965      defaultPackageName = "nixCats";
966      luaPath = "${./.}";
967      inherit nixpkgs dependencyOverlays
968        categoryDefinitions packageDefinitions extra_pkg_config;
969  };
970  Will create a nixos module that you can import in configuration.nix
971  If you do not have a luaPath, you may pass it a keepLua builder
972  See :help nixCats.flake.outputs.exports.mkNixosModules
973  The packages also export a module with defaultPackageName
974  set to THEIR package name via their passthru variable using this function.
975  
976  <mkHomeModules>
977  The same as mkNixosModules above, but for home manager.
978  
979  <mkAllWithDefault> package:
980  makes each package in the packageDefinitions this package was made from
981  and also a default one out of the one passed in.
982  
983  <mkAllPackages> package:
984  makes each package in the packageDefinitions this package was made from
985  
986  <mkPackages> finalBuilder: packageDefinitions: defaultName:
987  makes each package in packageDefinitions and also a default one
988  where finalBuilder is the builder function with all but the name applied
989  
990  <mkExtraPackages> finalBuilder: packageDefinitions:
991  mkPackages just calls this and adds a default one.
992  where finalBuilder is the builder function with all but the name applied
993  
994  <makeOverlays> luaPath: {
995          nixpkgs
996          , extra_pkg_config ? {}
997          , dependencyOverlays ? null
998          , nixCats_passthru ? {}
999          , ...
1000       }@pkgsParams: categoryDefFunction: packageDefinitions:
1001       defaultName:
1002 makes an overlay for each package and also a default one
1003 These are basically the same as the arguments to utils.baseBuilder
1004 dependencyOverlays may be dependencyOverlays.${system} = [ list of overlays ];
1005 or simply dependencyOverlays = [ list of overlays ];
1006 
1007 <makeMultiOverlay> <same args as makeOverlays BUT with the following 2 args INSTEAD of defaultName>:
1008             importName: namesIncList:
1009 Instead of taking a defaultName, it takes an importName and a list of names.
1010 It will output them in an overlay where they will be accessible by pkgs.${importName}.${name}
1011 
1012 <makeOverlaysWithMultiDefault> utils.makeOverlays but the default overlay
1013 uses makeMultiOverlay. So that after adding it, all your packages from packageDefinitions will
1014 be accessible at pkgs.${defaultPackageName}.${packageName}
1015 Can be swapped out 1 for 1 with utils.makeOverlays if preferred
1016 
1017 <easyMultiOverlay> package:
1018 i.e. if you had a package named nvim1 and a package named nvim2,
1019 would output an overlay containing both pkgs.nvim1 and pkgs.nvim2
1020 
1021 Takes as its argument only a finished nixCats package.
1022 Utilizes override to avoid wrapping the overlay with ${system} variable.
1023 
1024 Slightly different from makeMultiOverlay in that
1025 makeMultiOverlay would output at pkgs.${importName}.nvim1
1026 instead of pkgs.nvim1 like this one does.
1027 
1028 <easyMultiOverlayNamespaced> package: importName:
1029 If you had a package named nvim1 and a package named nvim2,
1030 would output an overlay containing
1031 both pkgs.${importName}.nvim1 and pkgs.${importName}.nvim2
1032 
1033 Takes as its argument only a finished nixCats package.
1034 Utilizes override to avoid wrapping the overlay with ${system} variable.
1035 
1036 identical output to makeMultiOverlay
1037 
1038 <easyNamedOvers> package:
1039 Same output as makeOverlays except without a default package.
1040 i.e. if you had a package named nvim1 and a package named nvim2,
1041 would make an overlay named nvim1 and an overlay named nvim2
1042 
1043 Takes as its argument only a finished nixCats package.
1044 Utilizes override to avoid wrapping the overlay with ${system} variable
1045 
1046 <eachSystem> systems: f:
1047 just flake-utils.lib.eachSystem copied here to remove the final input outside
1048 of nixpkgs itself.
1049 
1050 <bySystem> systems: f:
1051 similar to flake-utils.lib.eachSystem but for only 1 variable. If used for the
1052 whole outputs section instead of eachSystem, it would add the
1053 ${system} to the start like ${system}.packages.default and not
1054 packages.${system}.default so instead it is used for only a single output like:
1055 { packages = utils.bySystem nixpkgs.lib.platforms.all (system: { default = ...; }) }
1056 
1057 It is the same thing as nixpkgs.lib.genAttrs, renamed so that people know
1058 how to use it.
1059 
1060                                   nixCats.flake.outputs.utils.n2l
1061 <n2l> This is the nix to lua library nixCats
1062 uses to create the nixCats lua plugin
1063 You may wish to use some functions from it.
1064 
1065 It contains <toLua> and <prettyLua> and <uglyLua> which convert nix to lua.
1066 
1067 it contains a <member> function to determine if a value is a special "inline lua" type
1068 it contains a <typeof> function to determine which special "inline lua" type it is
1069 it contains a <resolve> function which knows how to resolve the types to a string of code
1070 it contains the <default_subtype> name as well.
1071 
1072 But of much more interest to you is the types you may declare.
1073 
1074 Everything being passed through settings, categories, and extra in packageDefinitions
1075 will be properly escaped. But this also means that
1076 you cannot write any lua code there.
1077 
1078 Luckily, we have some types we can declare that will allow you to do this.
1079 
1080 To declare that an item is a lua value rather than a hard coded one,
1081 you may choose one of these types. To do this, call its constructor!
1082 
1083 for example, types.inline-unsafe has 1 field, body.
1084 
1085 To declare one in our settings, categories, and extra sets, it would look
1086 something like this:
1087 
1088   categories = {
1089     somecat = utils.n2l.types.inline-unsafe.mk {body = "vim.fn.stdpath('data')"; }`
1090   }
1091 
1092 inline-safe is the default type, and it gets to define a shorthand form.
1093 
1094   categories = {
1095     somecat = utils.n2l.types.inline-safe.mk "vim.fn.stdpath('data')";`
1096   }
1097 
1098 These are all the types, each one has an associated mk
1099 function to create a value of that type,
1100 which accepts the fields listed here, defined with default values.
1101 
1102   # creates an inline lua value in a way that cant break the table
1103   inline-safe = {
1104     default = (v: if v ? body then v else { body = v; });
1105     fields = { body = "nil"; };
1106     format = LI: "assert(loadstring(${luaEnclose "return ${LI.expr.body or LI.expr or "nil"}"}))()";
1107   };
1108   # iterpolates whatever string you provide into the table raw
1109   inline-unsafe = {
1110     fields = { body = "nil"; };
1111     format = LI: "${LI.expr.body or "nil"}";
1112   };
1113   # creates a function with args of the names given in args list
1114   # does so in a way where you cannot accidentally break the table
1115   function-safe = {
1116     fields = { body = "return nil"; args = []; };
1117     format = LI: 
1118       ''assert(loadstring(${luaEnclose ''return (function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)''}))()'';
1119   };
1120   # creates a function with args of the names given in args list
1121   # interpolates the body segment raw, just like inline-unsafe, but in a function
1122   function-unsafe = {
1123     fields = { body = "return nil"; args = []; };
1124     format = LI: ''(function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)'';
1125   };
1126   with-meta = {
1127     fields = {
1128       table = {}; # <- the table you are adding
1129       meta = {}; # <- the metatable you want to add to it (in nix)
1130       newtable = null; # <- if you want to specify a different first arg to setmetatable
1131       tablevar = "tbl_in"; # <- varname to refer to the table, to avoid translating multiple times
1132     };
1133     format = LI: opts: let
1134       metaarg1 = if LI.expr.newtable or null == null then LI.expr.tablevar or "{}" else toLuaFull opts LI.expr.newtable;
1135       result = inline.types.function-unsafe.mk {
1136         args = [ (LI.expr.tablevar or "tbl_in") ];
1137         body = ''return setmetatable(${metaarg1}, ${toLuaFull opts LI.expr.meta})'';
1138       };
1139     in "${toLuaFull opts result}(${toLuaFull opts LI.expr.table})";
1140   };
1141 
1142 
1143 Some more useage examples:
1144 
1145   exampleSafeFunc = utils.n2l.types.function-safe.mk {
1146     args = [ "hello" ];
1147     body = /*lua*/ ''
1148       print(hello)
1149       return hi
1150     '';
1151   };
1152   exampleUnsafeFunc = utils.n2l.types.function-unsafe.mk {
1153     args = [ "hi" "hello" ];
1154     body = /*lua*/ ''
1155       print(hi)
1156       print(hello)
1157       return hi .. hello
1158     '';
1159   };
1160   };
1161   funcResults = {
1162     test1 = utils.n2l.types.inline-safe.mk ''${utils.n2l.resolve exampleSafeFunc}("Hello World!")'';
1163   };
1164   lua_table_with_meta = utils.n2l.types.with-meta.mk (let
1165     tablevar = "tbl_in";
1166   in {
1167     table = {
1168       this = "is a test table";
1169       inatesttable = "that will be translated to a lua table with a metatable";
1170     };
1171     # to avoid translating the table multiple times,
1172     # define a variable name for it in lua. Defaults to "tbl_in"
1173     inherit tablevar;
1174     meta = {
1175       # __call in lua lets us also call it like a function
1176       __call = utils.n2l.types.function-unsafe.mk {
1177         args = [ "self" "..." ];
1178         body = ''
1179           print("This table is named ${tablevar}")
1180           return ${tablevar}.this
1181         '';
1182       };
1183     };
1184     # you can change it to set the metatable of
1185     # and return a different table instead.
1186     # sometimes done so that access always uses __index function
1187     newtable = null; # <- default val, sets metatable of tablevar
1188   });
1189 
1190 ---------------------------------------------------------------------------------------
1191 Nix OS Module                     nixCats.flake.outputs.exports.mkNixosModules
1192                                   nixCats.flake.outputs.exports.mkHomeModules
1193 
1194 We create the module by exporting the following in our flake outputs.
1195 More information on the modules can be found at :h nixCats.module
1196 
1197 <mkNixosModules> {
1198     defaultPackageName = "nixCats";
1199     luaPath = "${./.}";
1200     inherit nixpkgs dependencyOverlays
1201       categoryDefinitions packageDefinitions extra_pkg_config;
1202 };
1203 
1204 <mkHomeModules> {
1205     defaultPackageName = "nixCats";
1206     luaPath = "${./.}";
1207     inherit nixpkgs dependencyOverlays
1208       categoryDefinitions packageDefinitions extra_pkg_config;
1209 };
1210 
1211 dependencyOverlays may be dependencyOverlays.${system} = [ list of overlays ];
1212 or simply dependencyOverlays = [ list of overlays ];
1213 
1214 IMPORTANT
1215 By default, the module inherits your flake or nixExpressionFlakeOutputs nixpkgs object,
1216 and its overlays, and everything else.
1217 It will still inherit your system overlays and config set and system value,
1218 but your system will not inherit overlays added to the nixCats module option.
1219 
1220 More information on the modules can be found at :h nixCats.module
1221 
1222 ---------------------------------------------------------------------------------------
1223 vim:tw=78:ts=8:ft=help:norl: