diff options
Diffstat (limited to 'src/app/mod.rs')
| -rw-r--r-- | src/app/mod.rs | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/src/app/mod.rs b/src/app/mod.rs index 15f352af..cca530ce 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -22,6 +22,7 @@ mod runtime; mod runtime_mutations; mod session; pub mod state; +mod tab_bar_status; mod terminal_targets; mod terminal_titles; mod theme_sync; @@ -139,6 +140,10 @@ pub struct App { pub(crate) session_save_deadline: Option<Instant>, pub(crate) session_save_thread: Option<std::thread::JoinHandle<()>>, pub(crate) detached_custom_command_children: Vec<std::process::Child>, + tab_bar_status_generation: u64, + tab_bar_datetimes: Vec<tab_bar_status::TabBarDatetimeRuntime>, + tab_bar_commands: Vec<tab_bar_status::TabBarCommandRuntime>, + next_tab_bar_datetime_refresh: Option<Instant>, pub(crate) persist_pane_history: bool, pub(crate) last_render_at: Option<Instant>, pub(crate) input_leases: input::InputLeaseTable, @@ -642,6 +647,8 @@ impl App { show_agent_labels_on_pane_borders: config.ui.show_agent_labels_on_pane_borders, hide_tab_bar_when_single_tab: config.ui.hide_tab_bar_when_single_tab, tab_bar_position: config.ui.tab_bar_position, + tab_bar_right: Vec::new(), + tab_bar_right_separator: String::new(), pane_history_persistence: config.experimental.pane_history, reveal_hidden_cursor_for_cjk_ime: config.experimental.reveal_hidden_cursor_for_cjk_ime, cjk_ime_agent_filter_configured: !config.experimental.cjk_ime_agents.is_empty(), @@ -723,7 +730,7 @@ impl App { .and_then(|ws| ws.focused_pane_id().map(|pane_id| (idx, pane_id))) }); - Self { + let mut app = Self { config_diagnostic_deadline: None, toast_deadline: None, copy_feedback_deadline: None, @@ -762,6 +769,10 @@ impl App { session_save_deadline: None, session_save_thread: None, detached_custom_command_children: Vec::new(), + tab_bar_status_generation: 0, + tab_bar_datetimes: Vec::new(), + tab_bar_commands: Vec::new(), + next_tab_bar_datetime_refresh: None, selection_autoscroll_deadline: None, selection_highlight_clear_deadline: None, persist_pane_history: config.experimental.pane_history, @@ -781,7 +792,9 @@ impl App { local_input_source_switch: true, config_reloaded_from_disk: false, prefix_input_source: Box::new(crate::platform::RealPrefixInputSource::default()), - } + }; + app.configure_tab_bar_status(&config.ui.tab_bar_right, &config.ui.tab_bar_right_separator); + app } #[cfg(unix)] @@ -1421,6 +1434,9 @@ impl App { diagnostics.push(format!("{diagnostic}; keeping previous [ui] settings")); } else { diagnostics.extend(config.ui.sound.diagnostics()); + diagnostics.extend(crate::config::tab_bar_right_diagnostics( + &config.ui.tab_bar_right, + )); self.state.default_sidebar_width = config.ui.sidebar_width; if self.state.sidebar_width_source == state::SidebarWidthSource::ConfigDefault { @@ -1460,6 +1476,10 @@ impl App { config.ui.show_agent_labels_on_pane_borders; self.state.hide_tab_bar_when_single_tab = config.ui.hide_tab_bar_when_single_tab; self.state.tab_bar_position = config.ui.tab_bar_position; + self.configure_tab_bar_status( + &config.ui.tab_bar_right, + &config.ui.tab_bar_right_separator, + ); self.state.agent_panel_sort = agent_panel_sort_from_config(config.ui.agent_panel_sort); self.state.status_indicators = config.ui.status_indicators; @@ -2332,6 +2352,37 @@ mod tests { } #[test] + fn tab_bar_command_events_render_only_when_visible_output_changes() { + if !crate::platform::status_commands_supported() { + return; + } + + let mut app = test_app(); + app.configure_tab_bar_status( + &[crate::config::TabBarRightEntryConfig::Command { + command: "status".into(), + interval_seconds: 5, + timeout_seconds: 2, + }], + " ", + ); + let generation = app.tab_bar_status_generation; + let event = |generation, output: Option<&str>| AppEvent::TabBarCommandFinished { + generation, + segment_index: 0, + result: Ok(output.map(str::to_string)), + }; + + assert!(!app.handle_internal_event_with_prefix_sync(event(generation, None))); + assert!(app.handle_internal_event_with_prefix_sync(event(generation, Some("ready")))); + assert!(!app.handle_internal_event_with_prefix_sync(event(generation, Some("ready")))); + assert!(!app.handle_internal_event_with_prefix_sync(event( + generation.wrapping_add(1), + Some("stale"), + ))); + } + + #[test] fn git_status_event_clears_in_flight_refresh() { let mut app = test_app(); app.git_refresh_in_flight = true; |
