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
mapAttrsToList
replicate
attrNames
;
initialIndent = concatStrings (replicate indentLevel " ");
@@ -28,31 +29,36 @@
toHyprconf' =
indent: attrs:
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 =
n: attrs:
if lib.isList attrs then
(concatMapStringsSep "\n" (a: mkSection n a) attrs)
else
if isList attrs then
let
separator = if all isAttrs attrs then "\n" else "";
in
(concatMapStringsSep separator (a: mkSection n a) attrs)
else if isAttrs attrs then
''
${indent}${n} {
${toHyprconf' " ${indent}" attrs}${indent}}
'';
''
else
toHyprconf' indent { ${n} = attrs; };
mkFields = generators.toKeyValue {
listsAsDuplicateKeys = true;
inherit indent;
};
allFields = 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 allFields;
fields = builtins.removeAttrs allFields (mapAttrsToList (n: _: n) importantFields);
allFields = filterAttrs (n: v: !(isAttrs v || isList v)) attrs;
fields = withoutImportantFields allFields;
in
mkFields importantFields
+ concatStringsSep "\n" (mapAttrsToList mkSection sections)

View File

@@ -1,4 +1,5 @@
{
generators-hyprconf = ./tohyprconf.nix;
generators-tokdl = ./tokdl.nix;
generators-toscfg-empty = ./toscfg-empty.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
}
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
decoration {
col.shadow=rgba(00000099)
shadow_offset=0 5
@@ -45,9 +49,6 @@ plugin {
dummy=plugin setting
}
}
bindm=$mod, mouse:272, movewindow
bindm=$mod, mouse:273, resizewindow
bindm=$mod ALT, mouse:272, resizewindow
# window resize
bind = $mod, S, submap, resize

View File

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

View File

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

View File

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

View File

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