From 78c6045960e4091a41d6699977d01fed658634cb Mon Sep 17 00:00:00 2001 From: LeMarsu Date: Tue, 28 May 2024 04:49:59 +0200 Subject: [PATCH] feat: generating plugins lua definition from nix --- lib/deps.nix | 34 +++++++++++++++++++++- lib/lua.nix | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/lib/deps.nix b/lib/deps.nix index c924bcb..3edfca5 100644 --- a/lib/deps.nix +++ b/lib/deps.nix @@ -6,7 +6,7 @@ types, ... }: let - inherit (builtins) isPath; + inherit (builtins) isPath foldl'; inherit (lib.attrsets) attrNames optionalAttrs; inherit (lib.lists) concatMap optional; inherit (lib.strings) concatStringsSep fileContents; @@ -98,6 +98,10 @@ cat <<'LUA' > $dir/config.lua ${lua.wrapReturnFunction (getAllLua "config")} LUA + + cat <<'LUA' > $dir/deps.lua + return ${pluginsLuaDef plugins} + LUA ''; }; @@ -105,9 +109,37 @@ if isPath content then fileContents content else content; + + pluginLuaDef = memo: plugin: let + # plugin = builtins.removeAttrs plugin ["dependencies" "plugin"]; + mkTypeFn = type: let + content = textOrContent plugin.${type}; + in + optionalAttrs (! isNull plugin.${type}) { + ${type} = with lua; lambda (raw content); + }; + pluginName = plugin: + if plugin ? pname + then plugin.pname + else plugin.name; + hasDeps = plugin ? dependencies && plugin.dependencies != []; + name = pluginName plugin.plugin; + in + memo + // { + ${name} = + {name = pluginName plugin.plugin;} + // (mkTypeFn "init") + // (mkTypeFn "config") + // (optionalAttrs hasDeps { + dependencies = map pluginName plugin.dependencies; + }); + }; + pluginsLuaDef = plugins: lua.nix2lua (foldl' pluginLuaDef {} plugins); in { inherit normalizePlugins; inherit mkSlothFlakePlugin; inherit mkRuntimePlugin; inherit textOrContent; + inherit pluginsLuaDef; } diff --git a/lib/lua.nix b/lib/lua.nix index f79ae17..3d8d227 100644 --- a/lib/lua.nix +++ b/lib/lua.nix @@ -1,6 +1,70 @@ {lib, ...}: let inherit (lib.strings) removeSuffix; + inherit (builtins) match; + handleAst = data: let + ast = data.__ast; + in + if ast == "raw" + then data.data + else if ast == "return" + # TODO nix2lua can return null + then "return ${nix2lua data.data}" + else if ast == "fn" + then "function ${data.name}()\n${nix2lua data.data}\nend" + else abort ''Unknown ast type ${ast.__ast}''; + + nix2lua = data: let + inherit (builtins) isInt isBool isNull isString isList isPath isAttrs isFunction typeOf concatStringsSep attrNames concatMap; + type = typeOf data; + condValue2list = val: value: + if isNull val + then [] + else [value]; + value2list = val: condValue2list val val; + in + if data ? __ast + then handleAst data + else if isInt data + then toString data + else if isBool data + then + if data + then "true" + else "false" + else if isString data || isPath data + then ''"${data}"'' + else if isNull data + then "nil" + else if isFunction data + then (builtins.trace "Skipping function" null) + else if isList data + then let + nix2luaList = val: value2list (nix2lua val); + listContent = concatStringsSep ", " (concatMap nix2luaList data); + in "{ ${listContent} }" + else if isAttrs data + then let + mkKeyValue = key: let + value = data.${key}; + luaKey = + if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key) + then ''["${key}"]'' + else key; + luaValue = nix2lua value; + in + # TODO Handle indentifier keys + condValue2list luaValue '' + ${luaKey} = ${luaValue}, + ''; + attrsContent = concatMap mkKeyValue (attrNames data); + in '' + { + ${concatStringsSep "" attrsContent}} + '' + else abort ''Type "${type}"''; in rec { + inherit nix2lua; + wrapFunction = content: "function()\n${content}\nend"; wrapReturnFunction = content: "return ${wrapFunction content}"; wrapSelfInvokingFunction = { @@ -11,4 +75,21 @@ in rec { (${wrapFunction (removeSuffix "\n" lua)})(); -- end ${section} ''; + + raw = data: { + inherit data; + __ast = "raw"; + }; + + function = name: data: { + inherit name data; + __ast = "fn"; + }; + + lambda = function ""; + + return = data: { + inherit data; + __ast = "return"; + }; }