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
//! tmux status bar UI using egui
//!
//! Displays the tmux status bar at the bottom of the terminal when connected
//! to a tmux session. Supports configurable format strings for customizing
//! the status bar content.
//!
//! ## Format Variables
//!
//! The following variables can be used in `tmux_status_bar_left` and
//! `tmux_status_bar_right` configuration options:
//!
//! - `{session}` - Session name
//! - `{windows}` - Window list with active marker (*)
//! - `{pane}` - Focused pane ID (e.g., "%0")
//! - `{time:FORMAT}` - Current time with strftime format (e.g., `{time:%H:%M}`)
//! - `{hostname}` - Machine hostname
//! - `{user}` - Current username
//!
//! ## Example Configuration
//!
//! ```yaml
//! tmux_status_bar_left: "[{session}] {windows}"
//! tmux_status_bar_right: "{user}@{hostname} | {time:%H:%M}"
//! ```
use crate::config::Config;
use crate::tmux::{FormatContext, TmuxSession, expand_format};
/// tmux status bar UI state
pub struct TmuxStatusBarUI {
/// Cached left side content
cached_left: String,
/// Cached right side content
cached_right: String,
/// Last time the status bar was refreshed
last_refresh: std::time::Instant,
}
impl TmuxStatusBarUI {
/// Create a new tmux status bar UI
pub fn new() -> Self {
Self {
cached_left: String::new(),
cached_right: String::new(),
last_refresh: std::time::Instant::now(),
}
}
/// Check if a refresh is needed based on the configured interval
pub fn needs_refresh(&self, refresh_interval_ms: u64) -> bool {
self.last_refresh.elapsed().as_millis() >= refresh_interval_ms as u128
}
/// Get the height of the status bar (0 if not visible)
pub fn height(config: &Config, is_connected: bool) -> f32 {
if config.tmux_show_status_bar && is_connected {
24.0 // Fixed height for status bar
} else {
0.0
}
}
/// Update cached content from session state using configurable format strings
pub fn update_from_session(
&mut self,
config: &Config,
session: &TmuxSession,
session_name: Option<&str>,
) {
// Create format context with session data
let ctx = FormatContext::new(Some(session), session_name);
// Expand format strings from config
self.cached_left = expand_format(&config.tmux_status_bar_left, &ctx);
self.cached_right = expand_format(&config.tmux_status_bar_right, &ctx);
self.last_refresh = std::time::Instant::now();
}
/// Render the status bar
///
/// Returns the height consumed by the status bar.
pub fn render(
&mut self,
ctx: &egui::Context,
config: &Config,
session: Option<&TmuxSession>,
session_name: Option<&str>,
) -> f32 {
// Don't show if not configured or not connected
let is_connected = session.is_some_and(|s| {
use crate::tmux::SessionState;
s.state() == SessionState::Connected
});
if !config.tmux_show_status_bar || !is_connected {
return 0.0;
}
// Update content if needed
if let Some(session) = session
&& self.needs_refresh(config.tmux_status_bar_refresh_ms)
{
self.update_from_session(config, session, session_name);
}
let bar_height = 24.0;
// Status bar at the bottom
egui::TopBottomPanel::bottom("tmux_status_bar")
.exact_height(bar_height)
.frame(
egui::Frame::NONE
.fill(egui::Color32::from_rgb(30, 40, 30)) // Dark green-ish background (tmux style)
.inner_margin(egui::Margin::symmetric(8, 4)),
)
.show(ctx, |ui| {
ui.horizontal(|ui| {
// Left side - session and windows
let left_text = if !self.cached_left.is_empty() {
&self.cached_left
} else {
"tmux"
};
ui.label(
egui::RichText::new(left_text)
.color(egui::Color32::from_rgb(100, 200, 100)) // Green text
.size(12.0)
.monospace(),
);
// Right side - pane info and time (right-aligned)
if !self.cached_right.is_empty() {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.label(
egui::RichText::new(&self.cached_right)
.color(egui::Color32::from_rgb(150, 200, 150)) // Light green text
.size(12.0)
.monospace(),
);
});
}
});
});
bar_height
}
}
impl Default for TmuxStatusBarUI {
fn default() -> Self {
Self::new()
}
}