Replaces the list attr -> KDL conversion logic with a more flexible approach,
allowing for multiple nodes with the same name in a scope. This unfortunately
also breaks the existing JSON-in-KDL semantics in favor of ergonomics. As far
as I can tell though, zellij is the only program using it, and it doesn't accept
JiK anyway.
For example, the following KDL was previously impossible to generate, since nix
attrs were mapped 1:1 to KDL nodes:
```
resize {
bind "k" "Up" { Resize "Increase Up"; }
bind "j" "Down" { Resize "Increase Down"; }
}
```
Now, this can be achieved with the nix expression:
```
resize.bind = [
{ _args = ["k" "Up"]; Resize = "Increase Up"; }
{ _args = ["j" "Down"]; Resize = "Increase Down"; }
];
```
which would previously have generated the not-very-useful:
```
resize {
bind {
- "k" "Up" { Resize "Increase Up"; }
- "j" "Down" { Resize "Increase Down"; }
}
}
```
which, in turn, can now be generated via:
```
resize.bind."-" = [
{ _args = ["k" "Up"]; Resize = "Increase Up"; }
{ _args = ["j" "Down"]; Resize = "Increase Down"; }
];
```
Added a generator for the KDL document language.
This is in order for home-manager to natively generate
the new config format for zellij, as described in nix-community#3364.
There is not a one to one mapping between KDL and nix types,
but attrset translation is heavily based on KDLs JSON-IN-KDL microsyntax.
The exception here is the `_args` and `_props` arguments, which lets you
specify arguments and properties as described in the spec.
See more here:
- https://kdl.dev/
- https://github.com/kdl-org/kdl/blob/main/SPEC.md
The generator also conforms to the interface from the nixpkgs manual:
https://nixos.org/manual/nixpkgs/stable/#sec-generators
Co-authored-by: Gaetan Lepage <gaetan@glepage.com>
Removes the `uniq` constraint on `after` and `before` so that we can
merge multiple definitions for the same DAG entry:
{
dag = mkMerge [
{
foo = lib.hm.dag.entryBefore [ "bar" ] {
# definition 1
};
}
{
foo = lib.hm.dag.entryBefore [ "qux" ] {
# definition 2
};
}
{
foo = {
# definition 3
};
}
];
}
In this example `foo` will come before `bar` and `qux`.
This makes definitions like
home.activation.foo = mkIf false "bar"
work, where previously they would complain about
`home.activation.foobar.data` being used but not defined.
The crucial part is that we don't call `convertAllToDags` in
`dagOf.merge`, because we need to process `mkIf`/`mkMerge` properties
first. So we let `attrEquivalent.merge` do its job normally, but give
it a type `dagEntryOf` that does the conversion.
Ideally this shouldn't require so much boilerplate; I'd like to
implement something like
types.changeInto dagContentType elemType dagEntryAnywhere
in Nixpkgs.
Given an inner type, the former function generates a type that expect
DAG option values. The latter function is only present to temporarily
allow the `programs.ssh.matchBlocks` to keep accepting list values.