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