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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//! Status bar widget configuration types.
//!
//! Defines the widget identifiers, section layout, and per-widget configuration
//! used by the status bar system.
use serde::{Deserialize, Serialize};
/// Section of the status bar where a widget is placed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum StatusBarSection {
/// Left-aligned section (default)
#[default]
Left,
/// Center-aligned section
Center,
/// Right-aligned section
Right,
}
/// Identifier for a built-in or custom status bar widget.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum WidgetId {
/// Current time (HH:MM:SS)
Clock,
/// user@hostname
UsernameHostname,
/// Current working directory
CurrentDirectory,
/// Git branch name with icon
GitBranch,
/// CPU usage percentage
CpuUsage,
/// Memory usage (used / total)
MemoryUsage,
/// Network throughput (rx/tx rates)
NetworkStatus,
/// Bell indicator with count
BellIndicator,
/// Currently running command name
CurrentCommand,
/// Update available notification
UpdateAvailable,
/// Custom widget (user-defined via format string)
Custom(String),
}
impl WidgetId {
/// Human-readable label for UI display.
pub fn label(&self) -> &str {
match self {
WidgetId::Clock => "Clock",
WidgetId::UsernameHostname => "User@Host",
WidgetId::CurrentDirectory => "Directory",
WidgetId::GitBranch => "Git Branch",
WidgetId::CpuUsage => "CPU Usage",
WidgetId::MemoryUsage => "Memory Usage",
WidgetId::NetworkStatus => "Network Status",
WidgetId::BellIndicator => "Bell Indicator",
WidgetId::CurrentCommand => "Current Command",
WidgetId::UpdateAvailable => "Update Available",
WidgetId::Custom(name) => name.as_str(),
}
}
/// Icon/prefix character for the widget.
pub fn icon(&self) -> &str {
match self {
WidgetId::Clock => "\u{1f551}", // clock emoji
WidgetId::UsernameHostname => "\u{1f464}", // bust in silhouette
WidgetId::CurrentDirectory => "\u{1f4c2}", // open file folder
WidgetId::GitBranch => "\u{1f500}", // twisted rightwards arrows (branch)
WidgetId::CpuUsage => "\u{1f4bb}", // laptop
WidgetId::MemoryUsage => "\u{1f4be}", // floppy disk
WidgetId::NetworkStatus => "\u{1f310}", // globe with meridians
WidgetId::BellIndicator => "\u{1f514}", // bell
WidgetId::CurrentCommand => "\u{25b6}", // play button
WidgetId::UpdateAvailable => "\u{2b06}", // upwards arrow
WidgetId::Custom(_) => "\u{2699}", // gear
}
}
/// Whether this widget requires the system monitor to be running.
pub fn needs_system_monitor(&self) -> bool {
matches!(
self,
WidgetId::CpuUsage | WidgetId::MemoryUsage | WidgetId::NetworkStatus
)
}
}
/// Configuration for a single status bar widget.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StatusBarWidgetConfig {
/// Which widget to display
pub id: WidgetId,
/// Whether this widget is enabled
#[serde(default = "default_true")]
pub enabled: bool,
/// Section placement (left, center, right)
#[serde(default)]
pub section: StatusBarSection,
/// Sort order within the section (lower values first)
#[serde(default)]
pub order: i32,
/// Optional format override string with `\(variable)` interpolation
#[serde(default, skip_serializing_if = "Option::is_none")]
pub format: Option<String>,
}
fn default_true() -> bool {
true
}
/// Default widget configuration set.
///
/// Returns a sensible starting set of widgets covering common use-cases.
/// System monitor widgets (CPU, memory, network) are disabled by default
/// to avoid unnecessary resource usage.
pub fn default_widgets() -> Vec<StatusBarWidgetConfig> {
vec![
StatusBarWidgetConfig {
id: WidgetId::UsernameHostname,
enabled: true,
section: StatusBarSection::Left,
order: 0,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::CurrentDirectory,
enabled: true,
section: StatusBarSection::Left,
order: 1,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::GitBranch,
enabled: true,
section: StatusBarSection::Left,
order: 2,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::CurrentCommand,
enabled: true,
section: StatusBarSection::Center,
order: 0,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::CpuUsage,
enabled: false,
section: StatusBarSection::Right,
order: 0,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::MemoryUsage,
enabled: false,
section: StatusBarSection::Right,
order: 1,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::NetworkStatus,
enabled: false,
section: StatusBarSection::Right,
order: 2,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::BellIndicator,
enabled: true,
section: StatusBarSection::Right,
order: 3,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::Clock,
enabled: true,
section: StatusBarSection::Right,
order: 4,
format: None,
},
StatusBarWidgetConfig {
id: WidgetId::UpdateAvailable,
enabled: true,
section: StatusBarSection::Right,
order: 5,
format: None,
},
]
}