mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-04-03 07:15:44 -04:00
refactor(nix): add structured config support to home-manager module
Convert settings from raw text to structured Nix attrs, following Hyprland's module pattern. Implementation based 1:1 on Hyprland's design - all credit to the Hyprland project. - Add nix/lib.nix with toMango conversion function - Support nested attrs, lists for duplicate keys - Add extraConfig, topPrefixes, bottomPrefixes options - Auto-add exec-once for autostart.sh Adapted for mangowc syntax (underscore separators vs colons).
This commit is contained in:
parent
62ab00a7a3
commit
9773b43592
2 changed files with 393 additions and 25 deletions
257
nix/lib.nix
Normal file
257
nix/lib.nix
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
lib:
|
||||
let
|
||||
inherit (lib)
|
||||
attrNames
|
||||
filterAttrs
|
||||
foldl
|
||||
generators
|
||||
partition
|
||||
;
|
||||
|
||||
inherit (lib.strings)
|
||||
concatMapStrings
|
||||
hasPrefix
|
||||
;
|
||||
|
||||
/**
|
||||
Convert a structured Nix attribute set into Mango's configuration format.
|
||||
|
||||
This function takes a nested attribute set and converts it into Mango-compatible
|
||||
configuration syntax, supporting top, bottom, and regular command sections.
|
||||
|
||||
Commands are flattened using the `flattenAttrs` function, and attributes are formatted as
|
||||
`key = value` pairs. Lists are expanded as duplicate keys to match Mango's expected format.
|
||||
|
||||
Configuration:
|
||||
|
||||
* `topCommandsPrefixes` - A list of prefixes to define **top** commands (default: `[]`).
|
||||
* `bottomCommandsPrefixes` - A list of prefixes to define **bottom** commands (default: `[]`).
|
||||
|
||||
Attention:
|
||||
|
||||
- The function ensures top commands appear **first** and bottom commands **last**.
|
||||
- The generated configuration is a **single string**, suitable for writing to a config file.
|
||||
- Lists are converted into multiple entries, ensuring compatibility with Mango.
|
||||
|
||||
# Inputs
|
||||
|
||||
Structured function argument:
|
||||
|
||||
: topCommandsPrefixes (optional, default: `[]`)
|
||||
: A list of prefixes that define **top** commands. Any key starting with one of these
|
||||
prefixes will be placed at the beginning of the configuration.
|
||||
: bottomCommandsPrefixes (optional, default: `[]`)
|
||||
: A list of prefixes that define **bottom** commands. Any key starting with one of these
|
||||
prefixes will be placed at the end of the configuration.
|
||||
|
||||
Value:
|
||||
|
||||
: The attribute set to be converted to Hyprland configuration format.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
toMango :: AttrSet -> AttrSet -> String
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
|
||||
## Basic mangowc configuration
|
||||
|
||||
```nix
|
||||
let
|
||||
config = {
|
||||
blur = 1;
|
||||
blur_params_radius = 5;
|
||||
border_radius = 6;
|
||||
animations = 1;
|
||||
animation_duration_open = 400;
|
||||
};
|
||||
in lib.toMango {} config
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
animations = 1
|
||||
animation_duration_open = 400
|
||||
blur = 1
|
||||
blur_params_radius = 5
|
||||
border_radius = 6
|
||||
```
|
||||
|
||||
## Using nested attributes
|
||||
|
||||
```nix
|
||||
let
|
||||
config = {
|
||||
blur = 1;
|
||||
blur_params = {
|
||||
radius = 5;
|
||||
num_passes = 2;
|
||||
noise = 0.02;
|
||||
};
|
||||
animation_curve = {
|
||||
open = "0.46,1.0,0.29,1";
|
||||
close = "0.08,0.92,0,1";
|
||||
};
|
||||
};
|
||||
in lib.toMango {} config
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
animation_curve_close = 0.08,0.92,0,1
|
||||
animation_curve_open = 0.46,1.0,0.29,1
|
||||
blur = 1
|
||||
blur_params_noise = 0.02
|
||||
blur_params_num_passes = 2
|
||||
blur_params_radius = 5
|
||||
```
|
||||
|
||||
## Using lists for duplicate keys
|
||||
|
||||
```nix
|
||||
let
|
||||
config = {
|
||||
bind = [
|
||||
"SUPER,r,reload_config"
|
||||
"Alt,space,spawn,rofi -show drun"
|
||||
"Alt,Return,spawn,foot"
|
||||
];
|
||||
tagrule = [
|
||||
"id:1,layout_name:tile"
|
||||
"id:2,layout_name:scroller"
|
||||
];
|
||||
};
|
||||
in lib.toMango {} config
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
bind = SUPER,r,reload_config
|
||||
bind = Alt,space,spawn,rofi -show drun
|
||||
bind = Alt,Return,spawn,foot
|
||||
tagrule = id:1,layout_name:tile
|
||||
tagrule = id:2,layout_name:scroller
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
toMango =
|
||||
{
|
||||
topCommandsPrefixes ? [ ],
|
||||
bottomCommandsPrefixes ? [ ],
|
||||
}:
|
||||
attrs:
|
||||
let
|
||||
toMango' =
|
||||
attrs:
|
||||
let
|
||||
# Specially configured `toKeyValue` generator with support for duplicate keys
|
||||
# and a legible key-value separator.
|
||||
mkCommands = generators.toKeyValue {
|
||||
mkKeyValue = generators.mkKeyValueDefault { } " = ";
|
||||
listsAsDuplicateKeys = true;
|
||||
indent = ""; # No indent, since we don't have nesting
|
||||
};
|
||||
|
||||
# Flatten the attrset, combining keys in a "path" like `"a_b_c" = "x"`.
|
||||
# Uses `flattenAttrs` with an underscore separator.
|
||||
commands = flattenAttrs (p: k: "${p}_${k}") attrs;
|
||||
|
||||
# General filtering function to check if a key starts with any prefix in a given list.
|
||||
filterCommands = list: n: foldl (acc: prefix: acc || hasPrefix prefix n) false list;
|
||||
|
||||
# Partition keys into top commands and the rest
|
||||
result = partition (filterCommands topCommandsPrefixes) (attrNames commands);
|
||||
topCommands = filterAttrs (n: _: builtins.elem n result.right) commands;
|
||||
remainingCommands = removeAttrs commands result.right;
|
||||
|
||||
# Partition remaining commands into bottom commands and regular commands
|
||||
result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong;
|
||||
bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands;
|
||||
regularCommands = removeAttrs remainingCommands result2.right;
|
||||
in
|
||||
# Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands.
|
||||
concatMapStrings mkCommands [
|
||||
topCommands
|
||||
regularCommands
|
||||
bottomCommands
|
||||
];
|
||||
in
|
||||
toMango' attrs;
|
||||
|
||||
/**
|
||||
Flatten a nested attribute set into a flat attribute set, using a custom key separator function.
|
||||
|
||||
This function recursively traverses a nested attribute set and produces a flat attribute set
|
||||
where keys are joined using a user-defined function (`pred`). It allows transforming deeply
|
||||
nested structures into a single-level attribute set while preserving key-value relationships.
|
||||
|
||||
Configuration:
|
||||
|
||||
* `pred` - A function `(string -> string -> string)` defining how keys should be concatenated.
|
||||
|
||||
# Inputs
|
||||
|
||||
Structured function argument:
|
||||
|
||||
: pred (required)
|
||||
: A function that determines how parent and child keys should be combined into a single key.
|
||||
It takes a `prefix` (parent key) and `key` (current key) and returns the joined key.
|
||||
|
||||
Value:
|
||||
|
||||
: The nested attribute set to be flattened.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
flattenAttrs :: (String -> String -> String) -> AttrSet -> AttrSet
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
|
||||
```nix
|
||||
let
|
||||
nested = {
|
||||
a = "3";
|
||||
b = { c = "4"; d = "5"; };
|
||||
};
|
||||
|
||||
separator = (prefix: key: "${prefix}.${key}"); # Use dot notation
|
||||
in lib.flattenAttrs separator nested
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```nix
|
||||
{
|
||||
"a" = "3";
|
||||
"b.c" = "4";
|
||||
"b.d" = "5";
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
flattenAttrs =
|
||||
pred: attrs:
|
||||
let
|
||||
flattenAttrs' =
|
||||
prefix: attrs:
|
||||
builtins.foldl' (
|
||||
acc: key:
|
||||
let
|
||||
value = attrs.${key};
|
||||
newKey = if prefix == "" then key else pred prefix key;
|
||||
in
|
||||
acc // (if builtins.isAttrs value then flattenAttrs' newKey value else { "${newKey}" = value; })
|
||||
) { } (builtins.attrNames attrs);
|
||||
in
|
||||
flattenAttrs' "" attrs;
|
||||
in
|
||||
{
|
||||
inherit flattenAttrs toMango;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue