aboutsummaryrefslogtreecommitdiff
path: root/src/app/mod.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-13 03:26:03 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-13 03:30:13 +0300
commit5cfe5e5e730246948b0c9428ad876b6938590aad (patch)
tree53d4bbe1aff6887f63f279eed1b5e4e11e7331b7 /src/app/mod.rs
parent7f3364a468f7dcfd8c9c84e5737fe5699f0e3a93 (diff)
feat: add configurable sidebar metadata tokens
Diffstat (limited to 'src/app/mod.rs')
-rw-r--r--src/app/mod.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 99fc12a6..bff04c44 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -18,6 +18,7 @@ mod runtime_mutations;
mod session;
pub mod state;
mod terminal_targets;
+mod terminal_titles;
mod theme_sync;
mod worktrees;
@@ -598,6 +599,8 @@ impl App {
sidebar_collapsed_mode: config.ui.sidebar_collapsed_mode,
sidebar_section_split,
agent_panel_sort,
+ sidebar_agents: config.ui.sidebar.agents.clone(),
+ sidebar_spaces: config.ui.sidebar.spaces.clone(),
next_agent_state_change_seq: 0,
mouse_capture: config.ui.mouse_capture,
copy_on_select: config.ui.copy_on_select,
@@ -879,12 +882,19 @@ impl App {
if self.render_dirty.load(Ordering::Acquire) {
needs_render = true;
}
+ let terminal_title_changed = self.sync_terminal_titles();
+ if terminal_title_changed && self.terminal_title_sidebar_configured() {
+ needs_render = true;
+ }
// Drain a bounded internal-event batch for responsiveness. API handlers
// perform an exhaustive drain before reading pane/runtime state.
if self.drain_internal_events() {
needs_render = true;
}
+ if self.expire_due_metadata(Instant::now()) {
+ needs_render = true;
+ }
if self.drain_api_requests() {
needs_render = true;
}
@@ -1390,6 +1400,8 @@ impl App {
self.state.hide_tab_bar_when_single_tab = config.ui.hide_tab_bar_when_single_tab;
self.state.agent_panel_sort =
agent_panel_sort_from_config(config.ui.agent_panel_sort);
+ self.state.sidebar_agents = config.ui.sidebar.agents.clone();
+ self.state.sidebar_spaces = config.ui.sidebar.spaces.clone();
self.state.agent_panel_scroll = 0;
self.state.accent = crate::config::parse_color(&config.ui.accent);
if !self.state.local_sound_playback && self.state.sound != config.ui.sound {
@@ -2686,6 +2698,59 @@ mod tests {
}
#[test]
+ fn reload_config_updates_sidebar_token_rows() {
+ let _guard = config_env_lock().lock().unwrap();
+ let path = temp_config_path("reload-config-sidebar-tokens");
+ std::fs::create_dir_all(path.parent().unwrap()).unwrap();
+ std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path);
+ let mut app = test_app();
+
+ std::fs::write(
+ &path,
+ "[ui.sidebar.agents]\nrows = [[\"state_icon\", \"$summary\"]]\n\n[ui.sidebar.agents.rows_by_agent]\nclaude = [[\"terminal_title_stripped\"]]\n\n[ui.sidebar.spaces]\nrows = [[\"workspace\", \"$jj_status\"]]\n",
+ )
+ .unwrap();
+ app.state.agent_panel_scroll = 5;
+ let report = app.reload_config();
+
+ assert_eq!(report.status, crate::config::ConfigReloadStatus::Applied);
+ assert_eq!(app.state.agent_panel_scroll, 0);
+ assert_eq!(
+ app.state.sidebar_agents.rows,
+ vec![vec![
+ crate::config::AgentSidebarToken::StateIcon,
+ crate::config::AgentSidebarToken::Custom("summary".into()),
+ ]]
+ );
+ assert_eq!(
+ app.state.sidebar_agents.rows_by_agent["claude"],
+ vec![vec![
+ crate::config::AgentSidebarToken::TerminalTitleStripped,
+ ]]
+ );
+ assert_eq!(
+ app.state.sidebar_spaces.rows,
+ vec![vec![
+ crate::config::SpaceSidebarToken::Workspace,
+ crate::config::SpaceSidebarToken::Custom("jj_status".into()),
+ ]]
+ );
+
+ let previous_agents = app.state.sidebar_agents.clone();
+ std::fs::write(
+ &path,
+ "[ui.sidebar.agents]\nrows = [[\"agent\"]]\n\n[ui.sidebar.agents.rows_by_agent]\nclaude-code = [[\"terminal_title\"]]\n",
+ )
+ .unwrap();
+ let report = app.reload_config();
+ assert_eq!(report.status, crate::config::ConfigReloadStatus::Partial);
+ assert_eq!(app.state.sidebar_agents, previous_agents);
+
+ std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR);
+ let _ = std::fs::remove_dir_all(path.parent().unwrap());
+ }
+
+ #[test]
fn reload_config_updates_sidebar_collapsed_mode() {
let _guard = config_env_lock().lock().unwrap();
let path = temp_config_path("reload-config-sidebar-collapsed-mode");