From ea24675e4f4f4c494ccb04f6645db2a394d348ee Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sat, 12 Jul 2025 15:32:14 -0400 Subject: [PATCH] lib: Improve KDL generator (#7429) This adds support for generating ordered children and nodes with attributes and/or properties but no children. These are both needed to generate zellij keybinding configuration. --- modules/lib/generators.nix | 48 +++++++++++++-------------- tests/lib/generators/tokdl-result.txt | 5 +++ tests/lib/generators/tokdl.nix | 13 ++++++++ 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/modules/lib/generators.nix b/modules/lib/generators.nix index 5fe3d8afb..2fdbdca18 100644 --- a/modules/lib/generators.nix +++ b/modules/lib/generators.nix @@ -116,34 +116,34 @@ convertAttrsToKDL = name: attrs: let - optArgsString = lib.optionalString (attrs ? "_args") ( - lib.pipe attrs._args [ - (map literalValueToString) - (lib.concatStringsSep " ") - (s: s + " ") - ] + optArgs = map literalValueToString (attrs._args or [ ]); + optProps = lib.mapAttrsToList (name: value: "${name}=${literalValueToString value}") ( + attrs._props or { } ); - optPropsString = lib.optionalString (attrs ? "_props") ( - lib.pipe attrs._props [ - (lib.mapAttrsToList (name: value: "${name}=${literalValueToString value}")) - (lib.concatStringsSep " ") - (s: s + " ") - ] - ); + orderedChildren = lib.pipe (attrs._children or [ ]) [ + (map (child: mapAttrsToList convertAttributeToKDL child)) + lib.flatten + ]; + unorderedChildren = lib.pipe attrs [ + (lib.filterAttrs ( + name: _: + !(elem name [ + "_args" + "_props" + "_children" + ]) + )) + (mapAttrsToList convertAttributeToKDL) + ]; + children = orderedChildren ++ unorderedChildren; + optChildren = lib.optional (children != [ ]) '' + { + ${indentStrings children} + }''; - children = lib.filterAttrs ( - name: _: - !(elem name [ - "_args" - "_props" - ]) - ) attrs; in - '' - ${name} ${optArgsString}${optPropsString}{ - ${indentStrings (mapAttrsToList convertAttributeToKDL children)} - }''; + lib.concatStringsSep " " ([ name ] ++ optArgs ++ optProps ++ optChildren); # List Conversion # String -> ListOf (OneOf [Int Float String Bool Null]) -> String diff --git a/tests/lib/generators/tokdl-result.txt b/tests/lib/generators/tokdl-result.txt index 6ad2af368..ea48b7bec 100644 --- a/tests/lib/generators/tokdl-result.txt +++ b/tests/lib/generators/tokdl-result.txt @@ -1,7 +1,12 @@ a 1 +argsAndProps 1 2 a=3 b "string" bigFlatItems 23847590283751 1.239000 "multiline \" \" \"\nstring\n" null c "multiline string\nwith special characters:\n\t \n \\" \"\n" +duplicateChildren { + child 2 + child 1 +} extraAttrs 2 true arg1=1 arg2=false { nested { a 1 diff --git a/tests/lib/generators/tokdl.nix b/tests/lib/generators/tokdl.nix index abe4a9862..7bb6dc8af 100644 --- a/tests/lib/generators/tokdl.nix +++ b/tests/lib/generators/tokdl.nix @@ -38,6 +38,10 @@ [ ] [ null ] ]; + duplicateChildren._children = [ + { child = [ 2 ]; } + { child = [ 1 ]; } + ]; extraAttrs = { _args = [ 2 @@ -52,6 +56,15 @@ b = null; }; }; + argsAndProps = { + _args = [ + 1 + 2 + ]; + _props = { + a = 3; + }; + }; listInAttrsInList = { list1 = [ { a = 1; }