1{ lib, pkgs, config, ... }:
2
3let
4 cfg = config.programs.yabar;
5
6 mapExtra = v: lib.concatStringsSep "\n" (lib.mapAttrsToList (
7 key: val: "${key} = ${if (builtins.isString val) then "\"${val}\"" else "${builtins.toString val}"};"
8 ) v);
9
10 listKeys = r: builtins.concatStringsSep "," (builtins.map (n: "\"${n}\"") (builtins.attrNames r));
11
12 configFile = let
13 bars = lib.mapAttrsToList (
14 name: cfg: ''
15 ${name}: {
16 font: "${cfg.font}";
17 position: "${cfg.position}";
18
19 ${mapExtra cfg.extra}
20
21 block-list: [${listKeys cfg.indicators}]
22
23 ${builtins.concatStringsSep "\n" (lib.mapAttrsToList (
24 name: cfg: ''
25 ${name}: {
26 exec: "${cfg.exec}";
27 align: "${cfg.align}";
28 ${mapExtra cfg.extra}
29 };
30 ''
31 ) cfg.indicators)}
32 };
33 ''
34 ) cfg.bars;
35 in pkgs.writeText "yabar.conf" ''
36 bar-list = [${listKeys cfg.bars}];
37 ${builtins.concatStringsSep "\n" bars}
38 '';
39in
40 {
41 options.programs.yabar = {
42 enable = lib.mkEnableOption "yabar, a status bar for X window managers";
43
44 package = lib.mkOption {
45 default = pkgs.yabar-unstable;
46 defaultText = lib.literalExpression "pkgs.yabar-unstable";
47 example = lib.literalExpression "pkgs.yabar";
48 type = lib.types.package;
49
50 # `yabar-stable` segfaults under certain conditions.
51 apply = x: if x == pkgs.yabar-unstable then x else lib.flip lib.warn x ''
52 It's not recommended to use `yabar' with `programs.yabar', the (old) stable release
53 tends to segfault under certain circumstances:
54
55 * https://github.com/geommer/yabar/issues/86
56 * https://github.com/geommer/yabar/issues/68
57 * https://github.com/geommer/yabar/issues/143
58
59 Most of them don't occur on master anymore, until a new release is published, it's recommended
60 to use `yabar-unstable'.
61 '';
62
63 description = ''
64 The package which contains the `yabar` binary.
65
66 Nixpkgs provides the `yabar` and `yabar-unstable`
67 derivations since 18.03, so it's possible to choose.
68 '';
69 };
70
71 bars = lib.mkOption {
72 default = {};
73 type = lib.types.attrsOf(lib.types.submodule {
74 options = {
75 font = lib.mkOption {
76 default = "sans bold 9";
77 example = "Droid Sans, FontAwesome Bold 9";
78 type = lib.types.str;
79
80 description = ''
81 The font that will be used to draw the status bar.
82 '';
83 };
84
85 position = lib.mkOption {
86 default = "top";
87 example = "bottom";
88 type = lib.types.enum [ "top" "bottom" ];
89
90 description = ''
91 The position where the bar will be rendered.
92 '';
93 };
94
95 extra = lib.mkOption {
96 default = {};
97 type = lib.types.attrsOf lib.types.str;
98
99 description = ''
100 An attribute set which contains further attributes of a bar.
101 '';
102 };
103
104 indicators = lib.mkOption {
105 default = {};
106 type = lib.types.attrsOf(lib.types.submodule {
107 options.exec = lib.mkOption {
108 example = "YABAR_DATE";
109 type = lib.types.str;
110 description = ''
111 The type of the indicator to be executed.
112 '';
113 };
114
115 options.align = lib.mkOption {
116 default = "left";
117 example = "right";
118 type = lib.types.enum [ "left" "center" "right" ];
119
120 description = ''
121 Whether to align the indicator at the left or right of the bar.
122 '';
123 };
124
125 options.extra = lib.mkOption {
126 default = {};
127 type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.int);
128
129 description = ''
130 An attribute set which contains further attributes of a indicator.
131 '';
132 };
133 });
134
135 description = ''
136 Indicators that should be rendered by yabar.
137 '';
138 };
139 };
140 });
141
142 description = ''
143 List of bars that should be rendered by yabar.
144 '';
145 };
146 };
147
148 config = lib.mkIf cfg.enable {
149 systemd.user.services.yabar = {
150 description = "yabar service";
151 wantedBy = [ "graphical-session.target" ];
152 partOf = [ "graphical-session.target" ];
153
154 script = ''
155 ${cfg.package}/bin/yabar -c ${configFile}
156 '';
157
158 serviceConfig.Restart = "always";
159 };
160 };
161 }