aboutsummaryrefslogtreecommitdiff
path: root/src/app/mod.rs
diff options
context:
space:
mode:
authorzhugehyuk <icedac@users.noreply.github.com>2026-05-25 03:28:33 +0900
committerGitHub <noreply@github.com>2026-05-24 21:28:33 +0300
commit43c6ca3a5dbdcefc6c6dc29be9ce81d990baf39e (patch)
tree73be12f81129dab324ea08901c733a6a56ec0e61 /src/app/mod.rs
parent5ce738cf5397d0d8a50ed1aa6335297073cc0f0f (diff)
feat: persist pane history across restarts (#248)
refs #217 Co-authored-by: Can Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/app/mod.rs')
-rw-r--r--src/app/mod.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/app/mod.rs b/src/app/mod.rs
index bacbf0ce..1679364b 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -82,6 +82,7 @@ pub struct App {
pub(crate) next_auto_update_check: Option<Instant>,
pub(crate) selection_autoscroll_deadline: Option<Instant>,
pub(crate) session_save_deadline: Option<Instant>,
+ pub(crate) persist_pane_history: bool,
pub(crate) last_render_at: Option<Instant>,
pub(crate) suppressed_repeat_keys:
HashSet<(crossterm::event::KeyCode, crossterm::event::KeyModifiers)>,
@@ -252,8 +253,14 @@ impl App {
std::collections::HashSet::new(),
)
} else if let Some(snap) = crate::persist::load() {
+ let history = config
+ .experimental
+ .pane_history
+ .then(crate::persist::load_history)
+ .flatten();
let (ws, terminals, terminal_runtimes) = crate::persist::restore(
&snap,
+ history.as_ref(),
24,
80,
config.advanced.scrollback_limit_bytes,
@@ -455,6 +462,7 @@ impl App {
confirm_close: config.ui.confirm_close,
prompt_new_tab_name: config.ui.prompt_new_tab_name,
show_agent_labels_on_pane_borders: config.ui.show_agent_labels_on_pane_borders,
+ 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(),
cjk_ime_agents: parse_cjk_ime_agents(&config.experimental.cjk_ime_agents),
@@ -529,6 +537,7 @@ impl App {
.then_some(Instant::now() + AUTO_UPDATE_CHECK_INTERVAL),
session_save_deadline: None,
selection_autoscroll_deadline: None,
+ persist_pane_history: config.experimental.pane_history,
last_render_at: None,
suppressed_repeat_keys: HashSet::new(),
api_rx,
@@ -1013,6 +1022,11 @@ impl App {
self.state.cjk_ime_agents = parse_cjk_ime_agents(&config.experimental.cjk_ime_agents);
self.state.cjk_ime_cursor_shape =
config.experimental.cjk_ime_cursor_shape.to_decscusr();
+ self.persist_pane_history = config.experimental.pane_history;
+ self.state.pane_history_persistence = config.experimental.pane_history;
+ if !self.persist_pane_history {
+ crate::persist::clear_history();
+ }
}
if !invalid_section("advanced") {
@@ -1848,6 +1862,31 @@ mod tests {
}
#[test]
+ fn settings_save_pane_history_persists_then_applies_live_config() {
+ let _guard = config_env_lock().lock().unwrap();
+ let path = temp_config_path("settings-save-pane-history");
+ std::fs::create_dir_all(path.parent().unwrap()).unwrap();
+ std::fs::write(&path, "onboarding = false\n").unwrap();
+ std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path);
+
+ let mut app = test_app();
+ assert!(!app.persist_pane_history);
+ assert!(!app.state.pane_history_persistence);
+
+ app.save_pane_history_persistence(true);
+
+ assert!(app.persist_pane_history);
+ assert!(app.state.pane_history_persistence);
+ let content = std::fs::read_to_string(&path).unwrap();
+ assert!(content.contains("[experimental]"));
+ assert!(content.contains("pane_history = true"));
+ assert!(app.state.config_diagnostic.is_none());
+
+ std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR);
+ let _ = std::fs::remove_dir_all(path.parent().unwrap());
+ }
+
+ #[test]
fn reload_config_keeps_current_state_on_invalid_toml() {
let _guard = config_env_lock().lock().unwrap();
let path = temp_config_path("reload-config-invalid-toml");