lib: make toHyprconf support strings and attrs in sections

Adds support for

    section = [
      "abc"
      { a = 123; }
    ];

Which gets generated to

    section=abc

    section {
      a=123
    }

This is very useful with the new windowrule syntax, where you can
create anonymous window rules as strings and named rules as attribute
sets. See <https://wiki.hypr.land/Configuring/Window-Rules/>.
This commit is contained in:
PerchunPak
2026-01-02 08:58:42 +01:00
committed by Robert Helgesson
parent e4e78a2cbe
commit d4e4d5cfa3
9 changed files with 197 additions and 22 deletions

View File

@@ -21,6 +21,7 @@
isList isList
mapAttrsToList mapAttrsToList
replicate replicate
attrNames
; ;
initialIndent = concatStrings (replicate indentLevel " "); initialIndent = concatStrings (replicate indentLevel " ");
@@ -28,31 +29,36 @@
toHyprconf' = toHyprconf' =
indent: attrs: indent: attrs:
let let
sections = filterAttrs (n: v: isAttrs v || (isList v && all isAttrs v)) attrs; isImportantField =
n: _: foldl (acc: prev: if hasPrefix prev n then true else acc) false importantPrefixes;
importantFields = filterAttrs isImportantField attrs;
withoutImportantFields = fields: removeAttrs fields (attrNames importantFields);
allSections = filterAttrs (n: v: isAttrs v || isList v) attrs;
sections = withoutImportantFields allSections;
mkSection = mkSection =
n: attrs: n: attrs:
if lib.isList attrs then if isList attrs then
(concatMapStringsSep "\n" (a: mkSection n a) attrs) let
else separator = if all isAttrs attrs then "\n" else "";
in
(concatMapStringsSep separator (a: mkSection n a) attrs)
else if isAttrs attrs then
'' ''
${indent}${n} { ${indent}${n} {
${toHyprconf' " ${indent}" attrs}${indent}} ${toHyprconf' " ${indent}" attrs}${indent}}
''; ''
else
toHyprconf' indent { ${n} = attrs; };
mkFields = generators.toKeyValue { mkFields = generators.toKeyValue {
listsAsDuplicateKeys = true; listsAsDuplicateKeys = true;
inherit indent; inherit indent;
}; };
allFields = filterAttrs (n: v: !(isAttrs v || (isList v && all isAttrs v))) attrs; allFields = filterAttrs (n: v: !(isAttrs v || isList v)) attrs;
fields = withoutImportantFields allFields;
isImportantField =
n: _: foldl (acc: prev: if hasPrefix prev n then true else acc) false importantPrefixes;
importantFields = filterAttrs isImportantField allFields;
fields = builtins.removeAttrs allFields (mapAttrsToList (n: _: n) importantFields);
in in
mkFields importantFields mkFields importantFields
+ concatStringsSep "\n" (mapAttrsToList mkSection sections) + concatStringsSep "\n" (mapAttrsToList mkSection sections)

View File

@@ -1,4 +1,5 @@
{ {
generators-hyprconf = ./tohyprconf.nix;
generators-tokdl = ./tokdl.nix; generators-tokdl = ./tokdl.nix;
generators-toscfg-empty = ./toscfg-empty.nix; generators-toscfg-empty = ./toscfg-empty.nix;
generators-toscfg-example = ./toscfg-example.nix; generators-toscfg-example = ./toscfg-example.nix;

View File

@@ -0,0 +1,93 @@
$important=123
attrs-section {
bool=true
float=0.800000
int=5
null=null
string=abc
}
combined-attrs-nested-section {
a {
a=123
}
a {
b=123
}
a {
c=123
}
b {
a=123
}
b {
b=123
}
b {
c=123
}
}
combined-list-nested-section {
b {
c {
abc=123
}
}
}
combined-list-nested-section {
bar {
baz {
aaa=111
}
}
}
list-section=foo
list-section=bar
list-section=baz
list-with-strings-and-attrs=abc
list-with-strings-and-attrs {
a=123
}
list-with-strings-and-attrs=foo
list-with-strings-and-attrs {
b=321
}
nested-attrs-section {
a {
b {
c {
abc=123
}
}
}
foo {
bar {
baz {
aaa=111
}
}
}
}
nested-list-section {
a=123
}
nested-list-section {
b=123
}
nested-list-section {
c=123
}

View File

@@ -0,0 +1,70 @@
{ lib, ... }:
{
home.file."tohyprconf-result.txt".text = lib.hm.generators.toHyprconf {
attrs = rec {
"$important" = 123;
list-section = [
"foo"
"bar"
"baz"
];
attrs-section = {
string = "abc";
int = 5;
float = 0.8;
bool = true;
null = null;
};
nested-attrs-section = {
a = {
b = {
c = {
abc = 123;
};
};
};
foo = {
bar = {
baz = {
aaa = 111;
};
};
};
};
nested-list-section = [
{ a = 123; }
{ b = 123; }
{ c = 123; }
];
combined-list-nested-section = [
nested-attrs-section.a
nested-attrs-section.foo
];
combined-attrs-nested-section = {
a = nested-list-section;
b = nested-list-section;
};
list-with-strings-and-attrs = [
"abc"
{ a = 123; }
"foo"
{ b = 321; }
];
};
};
nmt.script = ''
assertFileContent \
home-files/tohyprconf-result.txt \
${./tohyprconf-result.txt}
'';
}

View File

@@ -13,6 +13,10 @@ animations {
enabled=true enabled=true
} }
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
decoration { decoration {
col.shadow=rgba(00000099) col.shadow=rgba(00000099)
shadow_offset=0 5 shadow_offset=0 5
@@ -45,9 +49,6 @@ plugin {
dummy=plugin setting dummy=plugin setting
} }
} }
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
# window resize # window resize
bind = $mod, S, submap, resize bind = $mod, S, submap, resize

View File

@@ -13,6 +13,10 @@ animations {
enabled=true enabled=true
} }
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
decoration { decoration {
col.shadow=rgba(00000099) col.shadow=rgba(00000099)
shadow_offset=0 5 shadow_offset=0 5
@@ -48,9 +52,6 @@ plugin {
dummy=plugin setting dummy=plugin setting
} }
} }
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
# window resize # window resize
bind = $mod, S, submap, resize bind = $mod, S, submap, resize

View File

@@ -10,4 +10,5 @@ input {
follow_mouse=1 follow_mouse=1
kb_layout=ro kb_layout=ro
} }
source=sourced.conf source=sourced.conf

View File

@@ -17,6 +17,7 @@ submap = reset
submap = resize submap = resize
bind=, escape, submap, reset bind=, escape, submap, reset
bind=, return, submap, reset bind=, return, submap, reset
binde=, right, resizeactive, 10 0 binde=, right, resizeactive, 10 0
binde=, left, resizeactive, -10 0 binde=, left, resizeactive, -10 0
binde=, up, resizeactive, 0 -10 binde=, up, resizeactive, 0 -10

View File

@@ -1,7 +1,8 @@
ipc=on
preload=/share/wallpapers/buttons.png preload=/share/wallpapers/buttons.png
preload=/share/wallpapers/cat_pacman.png preload=/share/wallpapers/cat_pacman.png
splash=false
splash_offset=2.000000
wallpaper=DP-3,/share/wallpapers/buttons.png wallpaper=DP-3,/share/wallpapers/buttons.png
wallpaper=DP-1,/share/wallpapers/cat_pacman.png wallpaper=DP-1,/share/wallpapers/cat_pacman.png
ipc=on
splash=false
splash_offset=2.000000