1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use {
paste::paste,
schemars::JsonSchema,
serde::Deserialize,
termimad::crossterm::style::Color,
};
/// Define a `BaconSkin` struct with fields being u8 with default values.
macro_rules! BaconSkin {
(
$( $(#[$meta:meta])* $name:ident: $default:literal, )*
) => {
paste! {
$(
$(#[$meta])*
#[doc=concat!(" - default value: ", stringify!($default))]
#[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, JsonSchema)]
#[serde(untagged)]
pub enum [<Defaulting$name:camel>] {
Set(u8),
#[default]
Unset,
}
impl [<Defaulting$name:camel>] {
pub fn value(self) -> u8 {
match self {
Self::Set(value) => value,
Self::Unset => $default,
}
}
pub fn apply(&mut self, other: Self) {
if let Self::Set(value) = other {
*self = Self::Set(value);
}
}
pub fn color(self) -> Color {
Color::AnsiValue(self.value())
}
}
)*
/// Collection of optional color overrides for the Bacon UI.
#[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, JsonSchema)]
pub struct BaconSkin {
$(
$(#[$meta])*
#[serde(default)]
pub $name: [<Defaulting$name:camel>],
)*
}
impl BaconSkin {
pub fn apply(&mut self, other: Self) {
$(
self.$name.apply(other.$name);
)*
}
$(
#[inline]
pub fn [<$name>](&self) -> u8 {
self.$name.value()
}
)*
}
}
}
}
// The colors of Bacon, with default values (ANSI color codes, in 0-255)
BaconSkin! {
/// Foreground color of the status line
status_fg: 252,
/// Background color of the status line
status_bg: 239,
/// Foreground color used for key shortcuts in the UI
key_fg: 204,
/// Foreground color for key shortcuts displayed in the status line
status_key_fg: 204,
/// Foreground color of the project name badge
project_name_badge_fg: 255,
/// Background color of the project name badge
project_name_badge_bg: 240,
/// Foreground color of the job label badge
job_label_badge_fg: 235,
/// Background color of the job label badge
job_label_badge_bg: 204,
/// Foreground color of the errors badge
errors_badge_fg: 235,
/// Background color of the errors badge
errors_badge_bg: 9,
/// Foreground color of the failing-tests badge
test_fails_badge_fg: 235,
/// Background color of the failing-tests badge
test_fails_badge_bg: 208,
/// Foreground color of the passing-tests badge
test_pass_badge_fg: 254,
/// Background color of the passing-tests badge
test_pass_badge_bg: 2,
/// Foreground color of the warnings badge
warnings_badge_fg: 235,
/// Background color of the warnings badge
warnings_badge_bg: 11,
/// Foreground color of the command-error badge
command_error_badge_fg: 235,
/// Background color of the command-error badge
command_error_badge_bg: 9,
/// Foreground color of the dismissed badge
dismissed_badge_fg: 235,
/// Background color of the dismissed badge
dismissed_badge_bg: 6,
/// Foreground color of the change badge
change_badge_fg: 235,
/// Background color of the change badge
change_badge_bg: 6,
/// Foreground color of the "computing..." indicator
computing_fg: 235,
/// Background color of the "computing..." indicator
computing_bg: 204,
/// Foreground color of search matches
found_fg: 208,
/// Background color of the selected search match
found_selected_bg: 208,
/// Foreground color of the '/' search prefix
search_input_prefix_fg: 208,
/// Foreground color of the search summary
search_summary_fg: 208,
/// Border color used for menus
menu_border: 234,
/// Background color used for menus
menu_bg: 235,
/// Background color of individual menu items
menu_item_bg: 235,
/// Background color of the selected menu item
menu_item_selected_bg: 239,
/// Foreground color of menu items
menu_item_fg: 250,
/// Foreground color of the selected menu item
menu_item_selected_fg: 255,
}
#[test]
fn test_bacon_skin_defaults() {
let a = r"
status_fg = 255
status_key_fg = 200
project_name_badge_fg = 0
";
let mut a = toml::from_str::<BaconSkin>(a).unwrap();
assert_eq!(a.status_fg(), 255);
assert_eq!(a.status_bg(), 239);
let b = r"
status_key_fg = 206
status_bg = 100
";
let b = toml::from_str::<BaconSkin>(b).unwrap();
a.apply(b);
assert_eq!(a.status_fg(), 255);
assert_eq!(a.status_bg(), 100);
assert_eq!(a.key_fg(), 204);
assert_eq!(a.status_key_fg(), 206);
assert_eq!(a.project_name_badge_fg(), 0);
assert_eq!(a.project_name_badge_bg(), 240);
}