polybar: allow config to be more nix-like (#1430)
Polybar's config format is a bit strange, and lists in particular are annoying to handle. This enables using normal nix lists and nested attrsets instead. This change is not backwards-compatible, because the INI converter converts lists of strings to space-separated values, and this does something else. I expect that this is only relevant for the `modules-left` etc bar setting, but that's enough to break things :(.
This commit is contained in:
parent
55030c8302
commit
da92360208
|
@ -1852,6 +1852,17 @@ in
|
|||
A new module is available: 'programs.sbt'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2021-02-20T00:00:00+00:00";
|
||||
condition = config.services.polybar.enable;
|
||||
message = ''
|
||||
The polybar configuration can now be written in a more nix-friendly format.
|
||||
The new 'services.polybar.settings' option is an alternative to
|
||||
'services.polybar.config' that supports nested keys and converts nix
|
||||
lists to polybar-style 'foo-0, foo-1, ...' lists.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,36 @@ let
|
|||
eitherStrBoolIntList = with types;
|
||||
either str (either bool (either int (listOf str)));
|
||||
|
||||
# Convert a key/val pair to the insane format that polybar uses.
|
||||
# Each input key/val pair may return several output key/val pairs.
|
||||
convertPolybarKeyVal = key: val:
|
||||
# Convert { foo = [ "a" "b" ]; }
|
||||
# to {
|
||||
# foo-0 = "a";
|
||||
# foo-1 = "b";
|
||||
# }
|
||||
if isList val then
|
||||
concatLists (imap0 (i: convertPolybarKeyVal "${key}-${toString i}") val)
|
||||
# Convert {
|
||||
# foo.text = "a";
|
||||
# foo.font = 1;
|
||||
# } to {
|
||||
# foo = "a";
|
||||
# foo-font = 1;
|
||||
# }
|
||||
else if isAttrs val && !lib.isDerivation val then
|
||||
concatLists (mapAttrsToList
|
||||
(k: convertPolybarKeyVal (if k == "text" then key else "${key}-${k}"))
|
||||
val)
|
||||
# Base case
|
||||
else
|
||||
[ (nameValuePair key val) ];
|
||||
|
||||
convertPolybarSection = _: attrs:
|
||||
listToAttrs (concatLists (mapAttrsToList convertPolybarKeyVal attrs));
|
||||
|
||||
# Converts an attrset to INI text, quoting values as expected by polybar.
|
||||
# This does no more fancy conversion.
|
||||
toPolybarIni = generators.toINI {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
|
@ -24,8 +54,11 @@ let
|
|||
in "${key}=${value'}";
|
||||
};
|
||||
|
||||
configFile = pkgs.writeText "polybar.conf"
|
||||
(toPolybarIni cfg.config + "\n" + cfg.extraConfig);
|
||||
configFile = pkgs.writeText "polybar.conf" ''
|
||||
${toPolybarIni cfg.config}
|
||||
${toPolybarIni (mapAttrs convertPolybarSection cfg.settings)}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
in {
|
||||
options = {
|
||||
|
@ -54,6 +87,7 @@ in {
|
|||
description = ''
|
||||
Polybar configuration. Can be either path to a file, or set of attributes
|
||||
that will be used to create the final configuration.
|
||||
See also <option>services.polybar.settings</option> for a more nix-friendly format.
|
||||
'';
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
|
@ -77,6 +111,56 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf types.attrs;
|
||||
description = ''
|
||||
Polybar configuration. This takes a nix attrset and converts it to the
|
||||
strange data format that polybar uses.
|
||||
Each entry will be converted to a section in the output file.
|
||||
Several things are treated specially: nested keys are converted
|
||||
to dash-separated keys; the special <literal>text</literal> key is ignored as a nested key,
|
||||
to allow mixing different levels of nesting; and lists are converted to
|
||||
polybar's <literal>foo-0, foo-1, ...</literal> format.
|
||||
</para><para>
|
||||
For example:
|
||||
<programlisting language="nix">
|
||||
"module/volume" = {
|
||||
type = "internal/pulseaudio";
|
||||
format.volume = "<ramp-volume> <label-volume>";
|
||||
label.muted.text = "🔇";
|
||||
label.muted.foreground = "#666";
|
||||
ramp.volume = ["🔈" "🔉" "🔊"];
|
||||
click.right = "pavucontrol &";
|
||||
}
|
||||
</programlisting>
|
||||
becomes:
|
||||
<programlisting language="ini">
|
||||
[module/volume]
|
||||
type=internal/pulseaudio
|
||||
format-volume=<ramp-volume> <label-volume>
|
||||
label-muted=🔇
|
||||
label-muted-foreground=#666
|
||||
ramp-volume-0=🔈
|
||||
ramp-volume-1=🔉
|
||||
ramp-volume-2=🔊
|
||||
click-right=pavucontrol &
|
||||
</programlisting>
|
||||
'';
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"module/volume" = {
|
||||
type = "internal/pulseaudio";
|
||||
format.volume = "<ramp-volume> <label-volume>";
|
||||
label.muted.text = "🔇";
|
||||
label.muted.foreground = "#666";
|
||||
ramp.volume = ["🔈" "🔉" "🔊"];
|
||||
click.right = "pavucontrol &";
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = "Additional configuration to add.";
|
||||
|
|
|
@ -12,6 +12,16 @@ label=%time% %date%
|
|||
time=%H:%M
|
||||
type=internal/date
|
||||
|
||||
[module/volume]
|
||||
click-right=pavucontrol &
|
||||
format-volume=<ramp-volume> <label-volume>
|
||||
label-muted=🔇
|
||||
label-muted-foreground=#666
|
||||
ramp-volume-0=🔈
|
||||
ramp-volume-1=🔉
|
||||
ramp-volume-2=🔊
|
||||
type=internal/pulseaudio
|
||||
|
||||
[module/date]
|
||||
type = internal/date
|
||||
interval = 5
|
||||
|
@ -19,3 +29,4 @@ date = "%d.%m.%y"
|
|||
time = %H:%M
|
||||
format-prefix-foreground = ${colors.foreground-alt}
|
||||
label = %time% %date%
|
||||
|
||||
|
|
|
@ -22,6 +22,16 @@
|
|||
label = "%time% %date%";
|
||||
};
|
||||
};
|
||||
settings = {
|
||||
"module/volume" = {
|
||||
type = "internal/pulseaudio";
|
||||
format.volume = "<ramp-volume> <label-volume>";
|
||||
label.muted.text = "🔇";
|
||||
label.muted.foreground = "#666";
|
||||
ramp.volume = [ "🔈" "🔉" "🔊" ];
|
||||
click.right = "pavucontrol &";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
[module/date]
|
||||
type = internal/date
|
||||
|
|
Loading…
Reference in a new issue