1    =======================================================================================
2    Flake Help                                                      nixCats.flake
3    
4    A Lua-natic's Neovim flake, with extra cats! nixCats!
5    
6    This is the documentation for the flake itself.
7    This flake uses Nix for importing plugins, LSPs, dependencies, and more,
8    in place of usual nvim package managers such as packer, lazy or Mason.
9    
10   Everything else is done in a regular Lua config style.
11   Download in flake.nix and then, simply pretend the root of the flake 
12   is the root of your Lua config. 
13   
14   *******************************************************
15   AN IMPORTANT NOTE:
16   
17   <1> When editing the files within the flake directory,
18   Nix will not package a new file if it isn't staged in git.
19   run git add before rebuilding it whenever adding a new file.
20   Using wrapRc = true would mean this also applies to Lua files.
21   Only tracked files will recieve their updates when
22   rebuilt without git add being ran first. New files need to be added.
23   *******************************************************
24   
25   Related:
26   For detecting what was included by 
27   the flake in your Lua, see:
28   :help nixCats
29   
30   stdpath('config') will still point to ~/.config/<configDirName>.
31   But your Lua config will be in the store.
32   This is okay, because most of the reason for a plugin to use
33   it would be to write to it, and we cant write to store paths anyway. 
34   You could use require('nixCats').configDir,
35   or nixCats('nixCats_config_location')
36   to get current config directory for your uses, if ever necessary.
37   It will be present and correct regardless of settings.
38   
39   However if you did not use Nix at all and did not run the setup
40   function, of course the nixCats plugin wont be there to ask.
41   
42   The setup function from require('nixCatsUtils').setup
43   will provide a mock nixCats plugin with SOME values
44   and empty tables to prevent accidental indexing errors.
45   You could instead do require('nixCatsUtils').isNixCats to default to
46   vim.fn.stdpath('config') if all you wanted was this path though.
47   
48   Keep in mind they will be read-only if in the store!
49   
50   =======================================================================================
51   Flake Inputs:                                            nixCats.flake.inputs
52   
53   If a plugin does not have an extra build step, and are not on nixpkgs,
54   you may use this format to import them, replacing the fields marked with <>
55   
56       "plugins-<pluginName>" = {
57         url = "github:<userName>/<repositoryName>";
58         flake = false;
59       };
60   
61   More info on flake url syntax at:
62   https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#examples
63   You may also use this syntax to pin the version of a plugin regardless of whether
64   you ran nix flake update or not.
65   You may choose the directory, branch, commit, tag, or even directory
66   imported.
67   
68   All inputs named in the plugins-<pluginName> format will be added to pkgs
69   at pkgs.neovimPlugins.<pluginName> for you to add to your configuration.
70   
71   If the plugin has a dot . character in it's name, you should name it something else
72   because . is not a valid character in an identifier in Nix.
73   
74   The name here only affects the filename of the overall plugin, and should
75   only affect things like vim.cmd("packadd <filename>") that refer to
76   the actual filename of the plugin. Usually I would replace it with -
77   You will then add it to categoryDefinitions later with the NEW name.
78   
79   If you use this method to import a plugin, and really dont
80   want to change the filename of the plugin when they have a
81   dot in their name, you may
82   swap the call to (utils.standardPluginOverlay inputs)
83   with (utils.sanitizedPluginOverlay inputs)
84   and then plugins-plugin.name would become pkgs.neovimPlugins.plugin-name
85   but Neovim would see it as vim.cmd("packadd plugin.name") still
86   
87   If they have a build step or are not a plugin, 
88   i.e. an LSP, or if they are a plugin from a flake,
89   dont name them in that format.
90   If they are a plugin from a flake, they can be added directly,
91   or they may be added as an overlay if offered.
92   If they are anything else they arent a plugin at all and obviously
93   should not be added as a plugin via plugins-<pluginName>
94   
95   If they are on nixpkgs, you dont need to put them in inputs,
96   because you will be able to access them through pkgs.vimPlugins variable.
97   Most plugins will not require you to use the inputs section due to being on nixpkgs.
98   But you may still use it to pin the plugin to a specific version.
99   
100  If you decided not to use utils.sanitizedPluginOverlay
101  and wanted to do it with utils.standardPluginOverlay:
102  If in your inputs you had:
103  
104    "plugins-<plugin-name>" = {
105      url = "github:<userName>/<repository.name>";
106      flake = false;
107    };
108  
109  Where you put plugins in your categoryDefinitions, instead of:
110  
111    pkgs.neovimPlugins.<plugin-name>
112  
113  You could put this:
114  
115    { name = "<plugin.name>"; plugin = pkgs.neovimPlugins.<plugin-name>; }
116  
117  You can also override them instead of (or before/during) the above:
118  
119    (pkgs.neovimPlugins.<plugin-name>.overrideAttrs { pname = "<plugin.name>"; })
120  
121  overrideAttrs can be used for a lot more than just fixing the name of the
122  imported plugin. See:
123  https://ryantm.github.io/nixpkgs/using/overrides/
124  
125  If they have a build step and are not on nixpkgs,
126  you will deal with them in overlays/customBuildsOverlay.nix
127  then import them into a category of the builder. 
128  Alternatively you may use overrideAttrs as mentioned above instead of an
129  overlay for these sorts of packages, but this would possibly get messy if the
130  build step were complex.
131  
132  =======================================================================================
133  Flake Outputs Introduction                              nixCats.flake.outputs
134  
135  With our inputs to our flake taken care of:
136  First, we take care of importing our utils set from nixCats.
137  The reason we are doing this now, is so that it can be defined outside of
138  the utils.eachSystem function, and thus we can export it
139  without having to include a system variable when we import it somewhere else.
140  
141  We also define our luaPath, which is the path to be loaded into the store as
142  your new Neovim config directory. (see :help 'rtp' for the directories
143  available for you to use!)
144  
145  We also define our extra_pkg_config, which is used when initializing the
146  nixpkgs instance that will build your Neovim! It's the same one from
147  
148    pkgs = import nixpkgs { inherit system; overlays = []; config = {}; }
149  
150  That is,
151  
152    outputs = { self, nixpkgs, ... }@inputs: let
153      # In the templates, this is inherit (inputs.nixCats) utils;
154      inherit (inputs.nixCats) utils;
155      # path the the store path to be loaded as Neovim config directory
156      luaPath = "${./.}";
157      # used when initializing the nixpkgs instance
158      extra_pkg_config = {
159        # allowUnfree = true;
160      };
161  
162                                             nixCats.flake.outputs.getOverlays
163  We call flake utils to get system variable for all default systems.
164  It simply calls the function with each system value, and maps the resulting
165  set from { mySet = {}; } to { mySet.${system} = {}; }
166  Many overlays require being accessed via ${system} variable in this manner,
167  and thus there is a method for handling it in nixCats.
168  
169  No overlays SHOULD be exported requiring the ${system} variable to access.
170  However, some are (such as codeium, a free ai plugin) and thus, we will wrap this anyway.
171  
172    inherit (utils.eachSystem nixpkgs.lib.platforms.all (system: let
173                    /* utils.eachSystem is just flake-utils.lib.eachSystem */
174           /* list of overlays from ./overlays is added to the rest of the list */
175      dependencyOverlays = (import ./overlays inputs) ++ [
176        # This overlay grabs all the inputs named in the format
177        # `plugins-<pluginName>`
178        # Once we add this overlay to our nixpkgs, we are able to
179        # use `pkgs.neovimPlugins`, which is a set of our plugins.
180        (utils.standardPluginOverlay inputs)
181        # add any flake overlays here.
182        inputs.neorg-overlay.overlays.default
183        inputs.lz-n.overlays.default
184        # stuff like this is why this part is done this way.
185        inputs.codeium.overlays.${system}.default
186      ];
187      # these overlays will be wrapped with ${system}
188      # and we will call the same utils.eachSystem function
189      # later on to access them.
190    in { inherit dependencyOverlays; })) dependencyOverlays;
191  
192  This will allow us to pass system independent overlays to our module options,
193  even when importing overlays from improperly formed flakes.
194  
195  Managing the system variable in combination with overlays
196  can be one of the hardest parts of flake usage.
197  This flake resolves our pkgs instance for Neovim itself to help with this,
198  and takes care of passing the correct pkgs instance
199  to the categoryDefinitions for use in defining your plugins.
200  
201  ALTERNATIVELY
202  
203  They could also just be a list of overlays!
204  
205    dependencyOverlays = (import ./overlays inputs) ++ [
206      (utils.standardPluginOverlay inputs)
207      inputs.neorg-overlay.overlays.default
208      inputs.lz-n.overlays.default
209  
210      # when other people mess up their overlays by wrapping them,
211      # you may instead call this function on their overlay.
212      # it will check if it has the system in it.
213      # if so, it will call the function with the system
214      # and return the desired overlay
215      (utils.fixSystemizedOverlay inputs.codeium.overlays
216        (system: inputs.codeium.overlays.${system}.default)
217      )
218    ];
219  
220  
221                                                 nixCats.flake.outputs.overlays
222  The two major things of note in this overlays section.
223  Regardless of which above method you choose. 
224    (utils.standardPluginOverlay inputs) # return type: a single overlay
225    # and
226    (import ./overlays inputs) # type: List of Overlays
227  
228  <1>
229  -- The first to explain is utils.standardPluginOverlay:
230  You do not need to edit it to use it.
231  Usage of this overlay is described in:
232  :h nixCats.flake.inputs
233  along with its friend, utils.sanitizedPluginOverlay
234  
235  It takes all the inputs named in the format
236  plugins-somepluginname and makes them into plugins. 
237  If the plugin doesn't have a build step,
238  and it wasnt on nixpkgs, then use this method.
239  Access them to add them to a category of the builder function 
240  with pkgs.neovimPlugins.somepluginname
241  
242  <2>
243  -- The second is overlays/customBuildsOverlay.nix:
244  
245  It is imported via overlays/default.nix above
246  
247  If you need to interact with one of these overlays, it will be this one.
248  You should not need to do it much.
249  overlays/default.nix imports this overlay and any others like it.
250  see :help nixCats.flake.nixperts.overlays
251  
252  It is used for defining plugins with build steps that 
253  were not well handled by nixpkgs.
254  It is passed flake inputs, and super is pkgs.
255  Define the things within the file. 
256  Then, access plugins defined there later 
257  with 'pkgs.nixCatsBuilds.somepluginname'
258  
259  If you decide you wish to split your customBuildsOverlay up, 
260  see :help nixCats.flake.nixperts.overlays
261  or look at the overlays/default.nix file.
262  
263  <IMPORTANT> When defining your overlays, they will be
264  defined in a SEPARATE LIST named <dependencyOverlays>.
265  You will need <dependencyOverlays> later.
266  
267  ---------------------------------------------------------------------------------------
268                                              nixCats.flake.outputs.categories
269  Then we define what is in our categories!
270  This section is a function that takes the package definition for this
271  particular package as an argument.
272  The builder will call it with that argument, you may use it.
273  This allows categoryDefinitions to access their packages categories and settings,
274  which allows categoryDefinitions to be much more dynamic.
275  
276  It also gets mkNvimPlugin = src: name: as an argument. mkNvimPlugin takes a src, either flake input
277  or fetched drv, and then a name, and it returns a nvim plugin that can be further
278  overriden via overrideAttrs if desired.
279  There is an overlay to do this automatically from flake inputs, mentioned
280  above. But sometimes it can be advantageous to do one of them individually.
281  
282  These are the things you can return:
283  
284    categoryDefinitions = { pkgs, settings, categories, extra, name, mkNvimPlugin, ... }@packageDef: {
285  
286  <lspsAndRuntimeDeps>
287    a flexible set of categories, each containing LSPs or
288    other internal runtime dependencies such as ctags or debuggers
289    these are available to the PATH while within the Neovim program.
290    this includes the Neovim terminal.
291  
292  <startupPlugins>
293    a flexible set of categories, each containing startup plugins.
294    Startup plugins are loaded and can be required. 
295  
296  <optionalPlugins>
297    a flexible set of categories, each containing optional plugins.
298    Optional plugins need to be added with packadd before being required.
299    Use :NixCats pawsible to see the names to use for packadd
300  
301  <sharedLibraries>
302    a flexible set of categories, each containing a derivation for
303    a runtime shared library. Will be prepended to the LD_LIBRARY_PATH variable.
304  
305  <environmentVariables>
306    a flexible set of categories, each containing an ATTRIBUTE SET of 
307    EnvironmentVariableName = "EnvironmentVariableValue";
308  
309  <extraWrapperArgs>
310    a flexible set of categories, each containing extra wrapper arguments.
311    If you don't know what that is, see here:
312  github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh
313  
314  <extraLuaPackages>
315    a flexible set of categories, each containing FUNCTIONS 
316    that return lists of extra Lua packages.
317    These functions are the same thing that you would pass to lua.withPackages.
318    Is used to populate $LUA_PATH and $LUA_CPATH
319  
320  <extraPython3Packages> 
321    a flexible set of categories, each containing FUNCTIONS
322    that return lists of Python packages.
323    These functions are the same thing that you would pass to python.withPackages.
324    You may get the path to this Python environment in your Lua config via
325    vim.g.python3_host_prog
326    or run from nvim terminal via :!<packagename>-python3
327  
328  <extraPython3wrapperArgs>
329    the same as extraWrapperArgs but for bundled python3 executable
330  
331  <propagatedBuildInputs> 
332    a flexible set of categories, each containing internal BUILD dependencies.
333    Will not be available to the PATH unless in a devShell.
334    USING THIS OPTION WILL CAUSE NVIM TO BUILD FROM SOURCE.
335  
336  <optionalLuaPreInit>
337    a flexible set of categories, each containing a Lua string
338    that will be ran before sourcing your init.lua
339    Yes it can access nixCats.
340    It is not the recommended way to create Lua for this flake,
341    but it may be useful in editing flake imports 
342    of other already configured setups following the nixCats format.
343  <optionalLuaAdditions>
344    a flexible set of categories, each containing a Lua string
345    that will be ran after sourcing your init.lua
346    Yes it can access nixCats.
347    It is not the recommended way to create Lua for this flake,
348    but it may be useful in editing flake imports 
349    of other already configured setups following the nixCats format.
350  <bashBeforeWrapper>
351    a flexible set of categories, each containing arbitrary Bash code
352    to run before the wrapper starts within the wrapper's Bash environment.
353    CAUTION: only use this if you know what you are doing and why you need
354    to do it. Whenever possible, use extraWrapperArgs instead.
355  <extraCats>
356    a flexible set of categories, each containing a list of attribute paths,
357    specified as lists of strings. Thus each category would contain a list of
358    lists of strings.
359    Allows inclusion of extra categories contingent on each lists inclusion in the package,
360    and is useful for creating default values for subcategories.
361    For more info, see below at
362    :h nixCats.flake.outputs.categoryDefinitions.default_values
363    # WARNING: use of categories argument in this set will cause infinite recursion
364    # The categories argument of this function is the FINAL value.
365    # You may use it in any of the other sets.
366  }
367  
368  In essence, the contents of each set listed here are filtered
369  based on the packageDefinitions set you provide, 
370  whereby including categoryname = true; you enable that category.
371  :help nixCats.flake.outputs.packageDefinitions
372  
373  It will remove duplicate items, so feel free to include the same thing in
374  multiple categories if it suits your purposes.
375  
376  It does this recursively. (explained below)
377  
378  If, inside one of these main sets, you had another set,
379  it would consider that a subcategory, and you could enable it
380  just like you do with a normal category, by setting a value with the
381  corresponding attribute path to true in the category
382  set of nixCats.flake.outputs.packageDefinitions.
383  You can nest them as much as you like, or just have a category that is a
384  single derivation.
385  
386                              nixCats.flake.outputs.categoryDefinitions.schemas
387  
388   You may also use the variables passed to your categoryDefinitions function
389   to get access to the set of categories and settings that are being
390   used to define the current package being built!
391  
392      themer = with pkgs.vimPlugins;
393        (builtins.getAttr packageDef.categories.colorscheme {
394            # Theme switcher without creating a new category
395            "onedark" = onedark-vim;
396            "catppuccin" = catppuccin-nvim;
397          }
398        );
399  
400    In addition to all this, if a plugin is defined within a list, it may
401    instead be defined within an attribute set that also contains config
402    to be ran after sourcing init.lua and optionalLuaAdditions
403    to do this, you may use the following syntax in opt or start sections: 
404      [
405        # you may add a plugin to a category list in any of these ways
406        { plugin = derivation; config.lua = ""; config.vim = "";}
407        { plugin = derivation; config = ""; type = "<viml or lua>"; }
408        { plugin = derivation; config = ""; } # defaults to viml
409        { plugin = derivation; }
410  
411        # all the above options can also accept an optional = bool;
412        # to override its presence in either startupPlugins or optionalPlugins
413  
414        # they can also accept a name = string; to override its name
415  
416        # they can also accept a priority = integer; with low being first
417        # and default of 150
418        # if they contain a config value, it will be ran in that order.
419  
420        # they also may contain a pre = true in order to be ran BEFORE init.lua
421  
422        derivation
423        # plain derivation does not need to be in a list, but it should be
424        # anyway. It could be on its own though and would act as its own
425        # category.
426      ]
427  
428                              nixCats.flake.outputs.categoryDefinitions.default_values
429  
430  There are 2 ways of creating default values in nixCats.
431  
432  #1 Implicit: when value is in another section of categoryDefinitions
433  
434  If in your categoryDefinitions you had the following:
435  
436      environmentVariables = {
437        test = {
438          subtest1 = {
439            CATTESTVAR = "It worked!";
440          };
441          subtest2 = {
442            CATTESTVAR3 = "It didn't work!";
443          };
444        };
445      };
446      extraWrapperArgs = {
447        test = [
448          '' --set CATTESTVAR2 "It worked again!"''
449        ];
450      };
451  
452  And in your packageDefinitions set, under categories, you had the following:
453  
454      test = {
455        subtest1 = true;
456      };
457  
458  you could echo $CATTESTVAR and $CATTESTVAR2 in your terminal to see them.
459  However you could not echo $CATTESTVAR3.
460  
461  All items that are not attributes of the parent set will be included
462  when you enable a subcategory. This includes lists, strings, functions, etc...
463  
464  However, attributes will not and you must explicitly enable all attributes of
465  a subcategory if you set even 1 explicitly.
466  
467  Thus to include CATTESTVAR3, you would have to enable it like so: 
468      test = {
469        subtest1 = true;
470        subtest2 = true;
471      };
472   However, those are all the items in the test category.
473  So instead we can do this to enable all the subcategories in test. 
474      test = true;
475  
476  This applies in many situations. Take this one for example.
477  
478      lspsAndRuntimeDeps = {
479        neonixdev = {
480          inherit (pkgs)
481            nix-doc nil lua-language-server nixd; 
482        };
483      };
484      startupPlugins = {
485        neonixdev = with pkgs.vimPlugins; [
486          neodev-nvim
487          neoconf-nvim
488        ];
489      };
490  
491   If you were to put the following in your packageDefinitions: 
492      neonixdev.nix-doc = true;
493  
494  neodev-nvim and neoconf-nvim would still be included.
495  However, nil, lua-language-server, and nixd would not be!
496  You would need to pick which of those you wanted separately.
497  Sometimes this is the desired behavior.
498  Sometimes it is not and a list of packages would be better suited.
499  
500  This leads us to our second way to make a default value:
501  
502  #2 Explicit: using extraCats section of categoryDefinitions.
503  
504  The extraCats section of categoryDefinitions contains categories of attribute
505  paths. If that category is defined, the categories specified by the attribute
506  paths will also be enabled. This means you could make it so that if you
507  included the go category, it could then enable debug.go and lsp.go for you.
508  But in addition to that, it can be combined with the implicit form of creating
509  default values above in an interesting way.
510  
511    categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@packageDef: {
512      lspsAndRuntimeDeps = {
513        debug = with pkgs; {
514          go = [ delve ];
515        };
516        go = with pkgs; [
517          gopls
518          gotools
519          go-tools
520          gccgo
521        ];
522      };
523      startupPlugins = {
524        debug = with pkgs.vimPlugins; {
525          default = [
526            nvim-dap
527            nvim-dap-ui
528            nvim-dap-virtual-text
529          ];
530          go = [ nvim-dap-go ];
531        };
532      };
533      # WARNING: use of categories argument in this set will cause infinite recursion
534      # The categories argument of this function is the FINAL value.
535      # You may use it in any of the other sets.
536      extraCats = {
537        # due to the implicit form of default values in different sections,
538        # this will enable debug.default
539        # if any subcategory of debug is enabled
540        # thus, enabling debug.go would also enable debug.default
541        debug = [
542          [ "debug" "default" ]
543        ];
544        # and if go is enabled, it enables debug.go
545        # which then enables debug.default
546        go = [
547          [ "debug" "go" ] # yes it has to be a list of lists
548        ];
549      };
550    };
551  
552  ---------------------------------------------------------------------------------------
553  Package Generation:                           nixCats.flake.outputs.packageDefinitions
554  
555  generate packages by calling that builder function we just created.
556  Place them in the packageDefinitions set.
557  
558  First, pick the set of settings you wish to include.
559  
560  Then, pass it a set of named boolean values like this:
561  { categoryname1 = true; categoryname2 = false; etc... }
562  False may be omitted. True may not.
563  Only true matters for what plugins will be added.
564  
565  These categories are defined in the Builder function above 
566  by placing named lists of plugins in the flexible sets provided.
567  The category names are the names of those lists. 
568  Add a new list, then enable the category here.
569  
570  If you have categories with the same name in 
571  multiple different sets outlined above in the builder,
572  all plugins in those categories will be
573  included when you set "thatname = true;" here.
574  hence, general = true; will include the general lspsAndDeps category,
575  as well as the general startupPlugins category.
576  
577  an example package definition:
578  
579    packageDefinitions = {
580      nixCats = { pkgs, ... }: {
581        setting = {
582          wrapRc = true;
583          # nvimSRC = inputs.neovim;
584          aliases = [ "viCat" ];
585        };
586        categories = {
587          custom = true;
588          gitPlugins = true;
589          general = true;
590          neonixdev = true;
591  
592          # this does not have an associated category of plugins, 
593          # but Lua can still check for it
594          lspDebugMode = false;
595  
596          # you could also pass something else and it calls 
597          # builtins.toString on it and passes it in as a string
598          theBestCat = "says meow!!!";
599          # maybe you need to pass a port or path in or something idk.
600          # you could :lua =nixCats("theBestCat")
601          # this nixCats("path.to.val") is the main category check function
602          # and it is built to mirror the Nix category scheme as much as possible
603        };
604        extra = {
605          there_is = "also";
606          an_extra = "table";
607          for = ''if you dont want the main subcategory get function
608            to apply to something, or think it all being in categories is too
609            messy
610          '';
611          you_can = ''nixCats.extra("path.to.val")'';
612          for_safer = ''table access via vim.tbl_get'';
613        };
614      };
615    };
616  
617  You can use the nixCats plugin for the set you define here in your Lua
618  It returns a Lua table of the same format.
619  
620  see :help nixCats
621  
622  For more nuances on enabling categories and subcategories, see above at
623  :help nixCats.flake.outputs.categoryDefinitions.default_values
624  and
625  :help nixCats.flake.outputs.categoryDefinitions.schemas
626  
627  ----------------------------------------------------------------------------------------
628  Settings                                       nixCats.flake.outputs.settings
629  
630  These are the defaults:
631  
632      default_settings = {
633        # YOU ARE IN CHARGE OF MAKING SURE THESE ALIASES DO NOT COLLIDE WITH
634        # ANYTHING ELSE
635        # [ "takes" "a" "list" "of" "strings" "and" "makes" "an" "alias" "for" "each" ];
636        aliases = null;
637        viAlias = false;
638        vimAlias = false;
639  
640        # so that you can see it in the store
641        extraName = "";
642  
643        withRuby = true;
644        withPython3 = true;
645        withNodeJs = false;
646        withPerl = false;
647  
648        # do you want to package the Lua from this flake in the store?
649        # or would you rather it just read it in your .config/<configDirName>?
650        # nixCats and this help will work either way.
651        # packages with wrapRc = false are for quick changes to Lua.
652        # it is not for being ran from anywhere via nix run, because the config
653        # was not wrapped with the program.
654        wrapRc = true;
655  
656        # What should the name of the folder within standard directories
657        # i.e. .config, .local/share, .local/state, .cache, etc... be?
658        # This option is very useful when you want 
659        # to clone an unwrapped config straight to the .config dir.
660        # It is also helpful to prevent other nvim packages sharing data folders.
661        # see :help `$NVIM_APPNAME`
662        configDirName = "nvim";
663  
664        # Only active when wrapRc = false, this option allows you to specify
665        # an absolute path to the unwrapped config directory.
666        # This is not a Nix path. This is the unwrapped config directory.
667        # This means you are going to need to make
668        # sure that it points the right place on the current machine.
669        unwrappedCfgPath = null;
670        # Will not change anything other than config directory, configDirName
671        # is still needed for .local/share or .cache and the like
672  
673        # use this to pin a specific Neovim version.
674        # This one will specify the base Neovim derivation to use.
675        neovim-unwrapped = null;
676        # This one will just override the src value of the Neovim in nixpkgs
677        # import it in flake inputs with flake = false,
678        # It will also obviously cause Neovim to build from source.
679        nvimSRC = null;
680  
681        # These 2 options are useful for when you want to allow your dev shells
682        # to override things such as LSPs and shared libraries that you have
683        # already in your configuration.
684        suffix-path = false;
685        # causes lspsAndDeps to be added to the END of
686        # PATH instead of the start
687        suffix-LD = false;
688        # causes sharedLibraries to be added to the END of
689        # LD_LIBRARY_PATH instead of the start
690  
691        # whether to group up treesitter grammars into a single directory,
692        # or leave them as separate plugins.
693        # Defaults to true as it results in
694        # a significant startup time performance boost
695        # Works only on grammars that have been passed through
696        # pkgs.neovimUtils.grammarToPlugin
697        # or pkgs.vimPlugins.nvim-treesitter.withPlugins
698        collate_grammars = true;
699  
700        # unsets PYTHONSAFEPATH variable.
701        # Can cause issues with reproducibility,
702        # can fix some stuff
703        disablePythonSafePath = false;
704  
705        # optional, specify custom store path gemdir
706        # must contain a gemset.nix like one generated by bundix
707        # must contain the Neovim gem
708        # for further info, see
709        # https://github.com/NixOS/nixpkgs/tree/74ad6cb1d2b14edb4ad1fffc0791e94910c61453/pkgs/applications/editors/neovim/ruby_provider
710        # https://github.com/BirdeeHub/neovim_ruby_updater
711        gem_path = null;
712        # If you are using neovim-unwrapped from nixpkgs itself,
713        # there is a good chance your Neovim
714        # will not be able to find it regardless of settings.
715        # thus withRuby and gem_path options may not work
716        # It works great using https://github.com/nix-community/neovim-nightly-overlay
717        # so this seems to be an upstream issue, as all the expected variables
718        # are still being set correctly.
719  
720        # each package outputs a module via passthru.
721        # this will set the namespace for the module options
722        # by default will be at config.${packagename}
723        moduleNamespace = [ <packagename> ];
724      };
725  
726  
727  QUICK TIP: wrapRc
728  
729  The wrapRc option is very useful for testing Lua changes.
730  It removes the need to stage and rebuild to see your Lua changes reflected.
731  You will still need to rebuild when making changes to Nix regardless of the
732  value of wrapRc.
733  
734  However it also means that the Lua isn't going run if it isn't in the right
735  folder, i.e. when installed and run from GitHub with nix run.
736  
737  If the Lua is not in vim.fn.stdpath('config'), wrapRc = false will not work.
738  By default this is ~/.config/nvim on Linux systems, although we can
739  change nvim to whatever we wish via the configDirName setting.
740  
741  Alternatively, you can set the unwrappedCfgPath option to allow the
742  configuration to be set to an absolute path. You still may want to set
743  the configDirName option anyway to change the data directories,
744  or explicitly keep it the same on both so that they share stuff like auths.
745  
746  The most convenient way to use this is the following:
747  Make a second identical packageDefinition, but with wrapRc disabled.
748  Then install both the wrapped one and unwrapped one with different aliases.
749  When you want to hack in Lua, use unwrapped! When you're done, just rebuild
750  and go back to the wrapped one.
751  
752  The templates/example/flake.nix file from the example config template
753  has an example of this with nixCats and regularCats.
754  
755  Then, when testing Lua changes, you run the other package and have a vanilla
756  Neovim experience, only rebuilding when you install new packages.
757  
758  When you are satisfied, simply rebuild and go back to using the main package,
759  as it was the same except for the single option!
760  
761  --------------------------------------------------------------------------------------
762  Neovim Builder Creation:                        nixCats.flake.outputs.builder
763  
764  Now we define our builder function.
765  We inherit utils.baseBuilder which is
766  a function that takes five arguments. It is defined in ./builder.
767  Right now we are going to call it with just the first four arguments. This will
768  leave us with a function that takes 1 argument.
769  That argument is the name of the Neovim package to be packaged.
770  
771  1. The path to the Lua to include (in the flake, we use the self variable to get
772       this path and wrap the Lua when wrapRc = true)
773  
774  2. A set containing:
775    The dependencyOverlays set or list,
776    extra_pkg_config, nixpkgs, nixCats_passthru, and system so it can
777    resolve pkgs and pass it where it needs to go.
778  
779  3. our function that takes an individual package definition
780       and returns a set of categoryDefinitions.
781  
782  4. our set of packageDefinitions see: nixCats.flake.outputs.packageDefinitions
783  
784  It is now a function that takes a name, and returns your chosen Neovim package.
785  
786    # It requires the system variable to build a package.
787    utils.eachSystem nixpkgs.lib.platforms.all (system: let
788      # create our builder for our exports
789      inherit (utils) baseBuilder;
790      nixCatsBuilder = baseBuilder luaPath {
791        inherit nixpkgs system dependencyOverlays extra_pkg_config;
792      } categoryDefinitions packageDefinitions;
793      # it can take a name of a package in packageDefinitions
794      # and return the package!
795      defaultPackage = nixCatsBuilder defaultPackageName;
796      # ... rest of the outputs section explained
797      # below in :h nixCats.flake.outputs.exports ...
798  
799  If you use it wrong, you will most likely get this error message:
800  
801    The following arguments are accepted:
802  
803    # -------------------------------------------------------- #
804  
805    # the path to your ~/.config/nvim replacement within your Nix config.
806    luaPath: # <-- must be a store path
807  
808    { # set of items for building the pkgs that builds your Neovim
809  
810      , nixpkgs # <-- required
811      , system # <-- required
812  
813      # type: (attrsOf listOf overlays) or (listOf overlays) or null
814      , dependencyOverlays ? null 
815  
816      # import nixpkgs { config = extra_pkg_config; inherit system; }
817      , extra_pkg_config ? {} # type: attrs
818  
819      # any extra stuff for finalPackage.passthru
820      , nixCats_passthru ? {} # type: attrs
821    }:
822  
823    # type: function with args { pkgs, settings, categories, name, ... }:
824    # returns: set of sets of categories
825    # see :h nixCats.flake.outputs.categories
826    categoryDefinitions: 
827  
828    # type: function with args { pkgs, ... }:
829    # returns: { settings = {}; categories = {}; }
830    packageDefinitions: 
831    # see :h nixCats.flake.outputs.packageDefinitions
832    # see :h nixCats.flake.outputs.settings
833  
834    # name of the package to built from packageDefinitions
835    name: 
836  
837    # -------------------------------------------------------- #
838  
839    # Note:
840    When using override, all values shown above will
841    be top level attributes of prev, none will be nested.
842    i.e. 
843    finalPackage.override (prev: { inherit (prev) dependencyOverlays; })
844        NOT prev.pkgsargs.dependencyOverlays or something like that
845  
846  ---------------------------------------------------------------------------------------
847  Flake Exports and Export options               nixCats.flake.outputs.exports
848  
849  They look something like this:
850  
851    # this first section is the outputs we
852    # want to wrap with the ${system} variable
853    utils.eachSystem nixpkgs.lib.platforms.all (system: let
854      # this is the builder (see :h nixCats.flake.outputs.builder above):
855      nixCatsBuilder = utils.baseBuilder luaPath {
856        inherit nixpkgs system dependencyOverlays extra_pkg_config;
857      } categoryDefinitions packageDefinitions;
858      # then it takes our categoryDefinitions and packageDefinitions
859  
860      # then we build a package to serve as the default one by providing its name.
861      defaultPackage = nixCatsBuilder defaultPackageName;
862  
863      # this is just for using utils in the following section such as pkgs.mkShell
864      # The one used to build Neovim is resolved inside the builder
865      # and is passed to our categoryDefinitions and packageDefinitions
866      pkgs = import nixpkgs { inherit system; };
867      # as you can see, "resolve pkgs" does not mean anything fancy.
868      # however, with overlays and system variable,
869      # sometimes you can get yourself in a loop when
870      # doing more advanced things. So this flake takes care of that for you.
871      # it will make sure pkgs is passed to the categoryDefinitions and packageDefinitions
872    in
873    {
874      # these outputs will be wrapped with ${system} by utils.eachSystem
875  
876      # this will make a package out of each of the packageDefinitions defined above
877      # and set the default package to the one passed in here.
878      packages = utils.mkAllWithDefault defaultPackage;
879  
880      # choose your package for devShell
881      # and add whatever else you want in it.
882      devShells = {
883        default = pkgs.mkShell {
884          name = defaultPackageName;
885          packages = [ defaultPackage ];
886          inputsFrom = [ ];
887          shellHook = ''
888          '';
889        };
890      };
891  
892    }) // {
893  
894      # these outputs will be NOT wrapped with ${system}
895  
896      # now we can export some things that can be imported in other
897      # flakes, WITHOUT needing to use a system variable to do it.
898      # and update them into the rest of the outputs returned by the
899      # eachSystem function.
900  
901      # this will make an overlay out of each of the packageDefinitions defined
902      # and set the default overlay to the one named here.
903      overlays = utils.makeOverlays luaPath {
904        # we pass in the things to make a pkgs variable to build nvim with later
905        inherit nixpkgs dependencyOverlays extra_pkg_config;
906        # and also our categoryDefinitions
907      } categoryDefinitions packageDefinitions defaultPackageName;
908  
909      # we export a NixOS module to allow configuration from configuration.nix
910      # allows you to either inherit values from your main flake, or start fresh
911      nixosModules.default = utils.mkNixosModules {
912        inherit dependencyOverlays luaPath defaultPackageName
913          categoryDefinitions packageDefinitions nixpkgs;
914      };
915      # and the same for Home Manager
916      homeModule = utils.mkHomeModules {
917        inherit dependencyOverlays luaPath defaultPackageName
918          categoryDefinitions packageDefinitions nixpkgs;
919      };
920      # and we export these so its super easy to grab them later.
921      inherit utils;
922      inherit (utils) templates;
923    };
924  
925                                    nixCats.flake.outputs.utils
926  
927  The <utils> set exports all the functions used in creating the format in the
928  templates, including the main builder!
929  (see :h nixCats.flake.outputs.builder for builder explanation)
930  
931  In the interests of not repeating ourselves,
932  a list of most functions exported in the <utils> set
933  can be found here:
934  https://nixcats.org/nixCats_utils.html
935  
936  Missing from that list however,
937  is an explanation of the internal <n2l> library
938  nixCats uses to create the nixCats Lua plugin!
939  
940  The library fully escapes all items passed to it,
941  so usually you can't execute lua code in them.
942  But you may still explicitly pass it lua code to execute at runtime
943  by declaring them as inline lua types!
944  
945  An intricate explanation of the full set
946  of features the <n2l> library contains are below.
947  
948  All other functions made available by
949  the <utils> set are explained in the documentation
950  at https://nixcats.org/nixCats_utils.html
951  
952                                    nixCats.flake.outputs.utils.n2l
953  <n2l> This is the Nix to Lua library nixCats
954  uses to create the nixCats Lua plugin
955  You may wish to use some functions from it.
956  
957  The library is exported from the <utils> set as utils.n2l
958  
959  It contains <toLua> and <prettyLua> and <uglyLua> which convert Nix to Lua.
960  
961  it contains a <member> function to determine if a value is a special "inline lua" type
962  it contains a <typeof> function to determine which special "inline lua" type it is
963  it contains a <resolve> function which knows how to resolve the types to a string of code
964  it contains the <default_subtype> name as well.
965  
966  But of much more interest to you is the types you may declare.
967  
968  Everything being passed through settings, categories, and extra in packageDefinitions
969  will be properly escaped. But this also means that
970  you cannot write any Lua code there.
971  
972  Luckily, we have some types we can declare that will allow you to do this.
973  
974  To declare that an item is a Lua value rather than a hard coded one,
975  you may choose one of these types. To do this, call its constructor!
976  
977  for example, types.inline-unsafe has 1 field, body.
978  
979  To declare one in our settings, categories, and extra sets, it would look
980  something like this:
981  
982    categories = {
983      somecat = utils.n2l.types.inline-unsafe.mk {body = "vim.fn.stdpath('data')"; }`
984    }
985  
986  inline-safe is the default type, and it gets to define a shorthand form.
987  
988    categories = {
989      somecat = utils.n2l.types.inline-safe.mk "vim.fn.stdpath('data')";`
990    }
991  
992  These are all the types, each one has an associated mk
993  function to create a value of that type,
994  which accepts the fields listed here, defined with default values.
995  
996    # creates an inline Lua value in a way that cant break the table
997    inline-safe = {
998      default = (v: if v ? body then v else { body = v; });
999      fields = { body = "nil"; };
1000     format = LI: "assert(loadstring(${luaEnclose "return ${LI.expr.body or LI.expr or "nil"}"}))()";
1001   };
1002   # iterpolates whatever string you provide into the table raw
1003   inline-unsafe = {
1004     fields = { body = "nil"; };
1005     format = LI: "${LI.expr.body or "nil"}";
1006   };
1007   # creates a function with args of the names given in args list
1008   # does so in a way where you cannot accidentally break the table
1009   function-safe = {
1010     fields = { body = "return nil"; args = []; };
1011     format = LI: 
1012       ''assert(loadstring(${luaEnclose ''return (function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)''}))()'';
1013   };
1014   # creates a function with args of the names given in args list
1015   # interpolates the body segment raw, just like inline-unsafe, but in a function
1016   function-unsafe = {
1017     fields = { body = "return nil"; args = []; };
1018     format = LI: ''(function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)'';
1019   };
1020   with-meta = {
1021     fields = {
1022       table = {}; # <- the table you are adding
1023       meta = {}; # <- the metatable you want to add to it (in Nix)
1024       newtable = null; # <- if you want to specify a different first arg to setmetatable
1025       tablevar = "tbl_in"; # <- varname to refer to the table, to avoid translating multiple times
1026     };
1027     format = LI: opts: let
1028       metaarg1 = if LI.expr.newtable or null == null then LI.expr.tablevar or "{}" else toLuaFull opts LI.expr.newtable;
1029       result = inline.types.function-unsafe.mk {
1030         args = [ (LI.expr.tablevar or "tbl_in") ];
1031         body = ''return setmetatable(${metaarg1}, ${toLuaFull opts LI.expr.meta})'';
1032       };
1033     in "${toLuaFull opts result}(${toLuaFull opts LI.expr.table})";
1034   };
1035 
1036 
1037 Some more useage examples:
1038 
1039   exampleSafeFunc = utils.n2l.types.function-safe.mk {
1040     args = [ "hello" ];
1041     body = /*lua*/ ''
1042       print(hello)
1043       return hi
1044     '';
1045   };
1046   exampleUnsafeFunc = utils.n2l.types.function-unsafe.mk {
1047     args = [ "hi" "hello" ];
1048     body = /*lua*/ ''
1049       print(hi)
1050       print(hello)
1051       return hi .. hello
1052     '';
1053   };
1054   };
1055   funcResults = {
1056     test1 = utils.n2l.types.inline-safe.mk ''${utils.n2l.resolve exampleSafeFunc}("Hello World!")'';
1057   };
1058   lua_table_with_meta = utils.n2l.types.with-meta.mk (let
1059     tablevar = "tbl_in";
1060   in {
1061     table = {
1062       this = "is a test table";
1063       inatesttable = "that will be translated to a Lua table with a metatable";
1064     };
1065     # to avoid translating the table multiple times,
1066     # define a variable name for it in Lua. Defaults to "tbl_in"
1067     inherit tablevar;
1068     meta = {
1069       # __call in Lua lets us also call it like a function
1070       __call = utils.n2l.types.function-unsafe.mk {
1071         args = [ "self" "..." ];
1072         body = ''
1073           print("This table is named ${tablevar}")
1074           return ${tablevar}.this
1075         '';
1076       };
1077     };
1078     # you can change it to set the metatable of
1079     # and return a different table instead.
1080     # sometimes done so that access always uses __index function
1081     newtable = null; # <- default val, sets metatable of tablevar
1082   });
1083 
1084 ---------------------------------------------------------------------------------------
1085 vim:tw=78:ts=8:ft=help:norl: