Skip to content

Commit

Permalink
packageDefinitions.packagename = {}:{ extra } and toLua implementatio…
Browse files Browse the repository at this point in the history
…n improvements (#63)

having everyone put all the values in categories and use the category fetcher for values is probably confusing.

It still works the same way, I just added an optional extra set to packageDefinitions named extra.

```nix
categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@pkgDef: {
};
packageDefinitions = {
  packagename = { pkgs, ... }: {
    settings = {};
    categories = {};
    extra = {};
  };
};
```

Like the other tables, you can use `nixCats.extra("path.to.val")` as an alias for fetching with `vim.tbl_get` to protect against nil table access errors, which is different from how the main `nixCats('path.to.cat')` works in that, if it does not find the value, it will always return nil, rather than returning an indicator of whether it was enabled or not. You can also use `:NixCats extra` to view the table

utils.mkLuaInline has been renamed to utils.n2l.types.inline-safe.mk

Extra utils.n2l functions added documented at [:help nixCats.flake.outputs.utils.n2l](https://nixcats.org/nixCats_format.html#nixCats.flake.outputs.utils.n2l)
  • Loading branch information
BirdeeHub authored Nov 15, 2024
1 parent febf1cf commit 3714989
Show file tree
Hide file tree
Showing 22 changed files with 307 additions and 127 deletions.
6 changes: 5 additions & 1 deletion builder/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ let
extraCats = {};
} // (categoryDefinitions {
# categories depends on extraCats
extra = extraTableLua;
inherit categories settings pkgs name;
}));
inherit (final_cat_defs_set)
Expand All @@ -78,6 +79,7 @@ let
optionalLuaPreInit bashBeforeWrapper;

categories = ncTools.applyExtraCats (thisPackage.categories or {}) final_cat_defs_set.extraCats;
extraTableLua = thisPackage.extra or {};

in
let
Expand All @@ -99,7 +101,7 @@ in
isStdCfgPath = settings.wrapRc == false && ! builtins.isString settings.unwrappedCfgPath;

nixCats_config_location = if isUnwrappedCfgPath then "${settings.unwrappedCfgPath}"
else if isStdCfgPath then ncTools.mkLuaInline ''vim.fn.stdpath("config")''
else if isStdCfgPath then ncTools.types.inline-unsafe.mk { body = ''vim.fn.stdpath("config")''; }
else "${LuaConfig}";

categoriesPlus = categories // {
Expand All @@ -117,6 +119,7 @@ in
settingsTable = ncTools.mkLuaFileWithMeta "settings" settingsPlus;
petShop = ncTools.mkLuaFileWithMeta "petShop" all_def_names;
depsTable = ncTools.mkLuaFileWithMeta "pawsible" allPluginDeps;
extraItems = ncTools.mkLuaFileWithMeta "extra" extraTableLua;
in {
name = "nixCats";
builder = pkgs.writeText "builder.sh" /*bash*/ ''
Expand All @@ -129,6 +132,7 @@ in
cp ${settingsTable} $out/lua/nixCats/settings.lua
cp ${depsTable} $out/lua/nixCats/pawsible.lua
cp ${petShop} $out/lua/nixCats/petShop.lua
cp ${extraItems} $out/lua/nixCats/extra.lua
cp -r ${../nixCatsHelp}/* $out/doc/
'';
});
Expand Down
124 changes: 25 additions & 99 deletions builder/ncTools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,107 +3,33 @@
{ lib, writeText, ... }: with builtins; rec {
# NIX CATS INTERNAL UTILS:

mkLuaFileWithMeta = modname: table: writeText "${modname}.lua" /*lua*/''
local ${modname} = ${toLua table};
return setmetatable(${modname}, {
__call = function(self, attrpath)
local strtable = {}
if type(attrpath) == "table" then
strtable = attrpath
elseif type(attrpath) == "string" then
for key in attrpath:gmatch("([^%.]+)") do
table.insert(strtable, key)
end
else
print("function requires a table of strings or a dot separated string")
return
end
if #strtable == 0 then return nil end
local tbl = ${modname};
for _, key in ipairs(strtable) do
if type(tbl) ~= "table" then return nil end
tbl = tbl[key]
end
return tbl
inherit (import ../utils/n2l.nix) toLua types;

mkLuaFileWithMeta = modname: table: writeText "${modname}.lua" /*lua*/ ''
local ${modname} = ${toLua table};
return setmetatable(${modname}, {
__call = function(self, attrpath)
local strtable = {}
if type(attrpath) == "table" then
strtable = attrpath
elseif type(attrpath) == "string" then
for key in attrpath:gmatch("([^%.]+)") do
table.insert(strtable, key)
end
else
print('function requires a { "list", "of", "strings" } or a "dot.separated.string"')
return
end
if #strtable == 0 then return nil end
local tbl = ${modname};
for _, key in ipairs(strtable) do
if type(tbl) ~= "table" then return nil end
tbl = tbl[key]
end
})
return tbl
end
})
'';

mkLuaInline = expr: { __type = "nix-to-lua-inline"; inherit expr; };

toLua = toLuaInternal {};

toLuaInternal = {
pretty ? true,
indentSize ? 2,
# adds indenting to multiline strings
# and multiline lua expressions
formatstrings ? false, # <-- only active if pretty is true
...
}: input: let

genStr = str: num: concatStringsSep "" (genList (_: str) num);

isLuaInline = toCheck: toCheck.__type or "" == "nix-to-lua-inline" && toCheck ? expr;

luaToString = LI: "assert(loadstring(${luaEnclose "return ${LI.expr}"}))()";

luaEnclose = inString: let
measureLongBois = inString: let
normalize_split = list: filter (x: x != null && x != "")
(concatMap (x: if isList x then x else [ ]) list);
splitter = str: normalize_split (split "(\\[=*\\[)|(]=*])" str);
counter = str: map stringLength (splitter str);
getMax = str: foldl' (max: x: if x > max then x else max) 0 (counter str);
getEqSigns = str: (getMax str) - 2;
longBoiLength = getEqSigns inString;
in
if longBoiLength >= 0 then longBoiLength + 1 else 0;

eqNum = measureLongBois inString;
eqStr = genStr "=" eqNum;
bL = "[" + eqStr + "[";
bR = "]" + eqStr + "]";
in
bL + inString + bR;

nl_spc = level: if pretty == true
then "\n${genStr " " (level * indentSize)}" else " ";

doSingleLuaValue = level: value: let
replacer = str: if pretty && formatstrings then replaceStrings [ "\n" ] [ "${nl_spc level}" ] str else str;
in
if value == true then "true"
else if value == false then "false"
else if value == null then "nil"
else if isFloat value || isInt value then toString value
else if isList value then "${luaListPrinter level value}"
else if isLuaInline value then replacer (luaToString value)
else if value ? outPath then luaEnclose "${value.outPath}"
else if lib.isDerivation value then luaEnclose "${value}"
else if isAttrs value then "${luaTablePrinter level value}"
else replacer (luaEnclose (toString value));

luaTablePrinter = level: attrSet: let
nameandstringmap = mapAttrs (n: value: let
name = "[ " + (luaEnclose "${n}") + " ]";
in
"${name} = ${doSingleLuaValue (level + 1) value}") attrSet;
resultList = attrValues nameandstringmap;
catset = concatStringsSep ",${nl_spc (level + 1)}" resultList;
LuaTable = "{${nl_spc (level + 1)}" + catset + "${nl_spc level}}";
in
LuaTable;

luaListPrinter = level: theList: let
stringlist = map (doSingleLuaValue (level + 1)) theList;
catlist = concatStringsSep ",${nl_spc (level + 1)}" stringlist;
LuaList = "{${nl_spc (level + 1)}" + catlist + "${nl_spc level}}";
in
LuaList;

in
doSingleLuaValue 0 input;

# returns a flattened list with only those lists
# whose name was associated with a true value within the categories set
Expand Down
4 changes: 3 additions & 1 deletion builder/nixCats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ M.cats = require('nixCats.cats')
M.pawsible = require('nixCats.pawsible')
M.settings = require('nixCats.settings')
M.petShop = require('nixCats.petShop')
M.extra = require('nixCats.extra')
M.configDir = M.settings.nixCats_config_location
-- NOTE: nixCats is inside of these and thus they could not be written into nixCats
-- due to infinite recursion, so they are variables instead.
Expand All @@ -22,7 +23,7 @@ function M.get(category)
table.insert(strtable, key)
end
else
print("get function requires a table of strings or a dot separated string")
print([[function requires a { "list", "of", "strings" } or a "dot.separated.string"]])
return
end
---@type any
Expand All @@ -48,6 +49,7 @@ function M.addGlobals()
"settings",
"pawsible",
"petShop",
"extra",
"vimPackDir",
"configDir",
"nixCatsPath",
Expand Down
3 changes: 3 additions & 0 deletions builder/nixCatsMeta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ error("Cannot import a meta module")
---See :h nixCats.flake.outputs.settings
---Function form will return vim.tbl_get for the attrpath
---@field settings table|fun(attrpath: string|string[]): any
---See :h nixCats.flake.outputs.packageDefinitions
---Function form will return vim.tbl_get for the attrpath
---@field extra table|fun(attrpath: string|string[]): any
---Contains the final set of plugins added for this package
---Function form will return vim.tbl_get for the attrpath
---@field pawsible table|fun(attrpath: string|string[]): any
Expand Down
7 changes: 3 additions & 4 deletions builder/vim-pack-dir.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
, python3
, symlinkJoin
, linkFarm
, callPackage
, collate_grammars ? false
}: let
# NOTE: define helpers for packDir function here:
Expand Down Expand Up @@ -36,10 +35,10 @@
, ...
}:
let
inherit (callPackage ./ncTools.nix { }) mkLuaInline;
inherit (import ../utils/n2l.nix) types;
# lazy.nvim wrapper uses this value to add the parsers back.
ts_grammar_path = if collate_grammars then ts_grammar_plugin_combined else
mkLuaInline "vim.g[ [[nixCats-special-rtp-entry-vimPackDir]] ] .. [[/pack/${grammarPackName}/start/*]]";
types.inline-unsafe.mk { body = "vim.g[ [[nixCats-special-rtp-entry-vimPackDir]] ] .. [[/pack/${grammarPackName}/start/*]]"; };

mkEntryFromDrv = drv: { name = "${lib.getName drv}"; value = drv; };
fullDeps = {
Expand All @@ -61,7 +60,7 @@
destination = "/lua/nixCats/saveTheCats.lua";
});
nixCatsFinal = nixCats fullDeps;
in # we add the plugin with ALL the parsers if its the old way, if its the new way, it will be in our packpath already
in # add fully called nixCats plugin along with another to save its path.
[ nixCatsFinal (nixCatsDir nixCatsFinal) ];

# gets plugin.dependencies from
Expand Down
114 changes: 104 additions & 10 deletions nixCatsHelp/nixCats_format.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ which allows categoryDefinitions to be much more dynamic.

These are the things you can return:
>nix
categoryDefinitions = { pkgs, settings, categories, name, ... }@packageDef: {
categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@packageDef: {
<
<lspsAndRuntimeDeps>
a flexible set of categories, each containing LSP's or
Expand Down Expand Up @@ -485,7 +485,7 @@ included the go category, it could then enable debug.go and lsp.go for you.
But in addition to that, it can be combined with the implicit form of creating
default values above in an interesting way.
>nix
categoryDefinitions = { pkgs, settings, categories, name, ... }@packageDef: {
categoryDefinitions = { pkgs, settings, categories, extra, name, ... }@packageDef: {
lspsAndRuntimeDeps = {
debug = with pkgs; {
go = [ delve ];
Expand Down Expand Up @@ -574,7 +574,19 @@ an example package definition:
# builtins.toString on it and passes it in as a string
theBestCat = "says meow!!!";
# maybe you need to pass a port or path in or something idk.
# you could :lua print(require('nixCats').theBestCat)
# you could :lua =nixCats("theBestCat")
# this nixCats("path.to.val") is the main category check function
# and it is built to mirror the nix category scheme as much as possible
};
extra = {
there_is = "also";
an_extra = "table";
for = ''if you dont want the main subcategory get function
to apply to something, or think it all being in categories is too
messy
'';
you_can = ''nixCats.extra("path.to.val")'';
for_safer = ''table access via vim.tbl_get'';
};
};
};
Expand Down Expand Up @@ -872,6 +884,7 @@ They look something like this:
inherit (utils) templates;
};
<
*nixCats.flake.outputs.utils*

We also export the <utils> set so we can get it easier later,
along with <templates> which are inside it.
Expand Down Expand Up @@ -1024,15 +1037,96 @@ whole outputs section instead of eachSystem, it would add the
It is the same thing as `nixpkgs.lib.genAttrs`, renamed so that people know
how to use it.

<mkLuaInline> luaCode:
This helper can be used in the `packageDefinitions` set in order to write
unescaped lua code into the nixCats plugin.
*nixCats.flake.outputs.utils.n2l*
<n2l> This is the nix to lua library nixCats
uses to create the nixCats lua plugin
You may wish to use some functions from it.

It contains <toLua> and <prettyLua> and <uglyLua> which convert nix to lua.

it contains a <member> function to determine if a value is a special "inline lua" type
it contains a <typeof> function to determine which special "inline lua" type it is
it contains a <resolve> function which knows how to resolve the types to a string of code
it contains the <default_subtype> name as well.

But of much more interest to you is the types you may declare.

Everything being passed through settings, categories, and extra in packageDefinitions
will be properly escaped. But this also means that
you cannot write any lua code there.

Luckily, we have some types we can declare that will allow you to do this.

For example, if `settings.wrapRc = false;` and `settings.unwrappedCfgPath`
is NOT set, nixCats uses this function to make
your config path default to the value of:
`nixCats_config_location = utils.mkLuaInline "vim.fn.stdpath('config')"`
To declare that an item is a lua value rather than a hard coded one,
you may choose one of these types. To do this, call its constructor!

for example, `types.inline-unsafe` has 1 field, `body`.

To declare one in our settings, categories, and extra sets, it would look
something like this:
>nix
categories = {
somecat = utils.n2l.types.inline-unsafe.mk {body = "vim.fn.stdpath('data')"; }`
}
<
`inline-safe` is the default type, and it gets to define a shorthand form.
>nix
categories = {
somecat = utils.n2l.types.inline-safe.mk "vim.fn.stdpath('data')";`
}
<
These are all the types, each one has an associated `mk`
function to create a value of that type,
which accepts the fields listed here, defined with default values.
>nix
# creates an inline lua value in a way that cant break the table
inline-safe = {
default = (v: if v ? body then v else { body = v; });
fields = { body = "nil"; };
format = LI: "assert(loadstring(${luaEnclose "return ${LI.expr.body or LI.expr or "nil"}"}))()";
};
# iterpolates whatever string you provide into the table raw
inline-unsafe = {
fields = { body = "nil"; };
format = LI: "${LI.expr.body or "nil"}";
};
# creates a function with args of the names given in args list
# does so in a way where you cannot accidentally break the table
function-safe = {
fields = { body = "return nil"; args = []; };
format = LI:
''assert(loadstring(${luaEnclose ''return (function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)''}))()'';
};
# creates a function with args of the names given in args list
# interpolates the body segment raw, just like inline-unsafe, but in a function
function-unsafe = {
fields = { body = "return nil"; args = []; };
format = LI: ''(function(${fixargs (LI.expr.args or [])}) ${LI.expr.body or "return nil"} end)'';
};
<

Some more useage examples:
>nix
exampleSafeFunc = utils.n2l.types.function-safe.mk {
args = [ "hello" ];
body = /*lua*/ ''
print(hello)
return hi
'';
};
exampleUnsafeFunc = utils.n2l.types.function-unsafe.mk {
args = [ "hi" "hello" ];
body = /*lua*/ ''
print(hi)
print(hello)
return hi .. hello
'';
};
};
funcResults = {
test1 = utils.n2l.types.inline-safe.mk ''${utils.n2l.resolve exampleSafeFunc}("Hello World!")'';
};
<
---------------------------------------------------------------------------------------
Nix OS Module *nixCats.flake.outputs.exports.mkNixosModules*
*nixCats.flake.outputs.exports.mkHomeModules*
Expand Down
3 changes: 3 additions & 0 deletions nixCatsHelp/nixCats_plugin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ has the `cat` subcommand to preview the value from `nixCats("catname")`,
---See :h nixCats.flake.outputs.settings
---Function form will return vim.tbl_get for the attrpath
---@field settings table|fun(attrpath: string|string[]): any
---See :h nixCats.flake.outputs.packageDefinitions
---Function form will return vim.tbl_get for the attrpath
---@field extra table|fun(attrpath: string|string[]): any
---Contains the final set of plugins added for this package
---Function form will return vim.tbl_get for the attrpath
---@field pawsible table|fun(attrpath: string|string[]): any
Expand Down
Loading

0 comments on commit 3714989

Please sign in to comment.