diff options
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/api.rs | 4 | ||||
| -rw-r--r-- | src/app/api/panes.rs | 2 | ||||
| -rw-r--r-- | src/app/api/tabs.rs | 2 | ||||
| -rw-r--r-- | src/app/creation.rs | 4 | ||||
| -rw-r--r-- | src/app/input/mod.rs | 2 | ||||
| -rw-r--r-- | src/app/input/mouse.rs | 2 | ||||
| -rw-r--r-- | src/app/input/navigate.rs | 2 | ||||
| -rw-r--r-- | src/app/input/terminal.rs | 2 | ||||
| -rw-r--r-- | src/app/mod.rs | 46 | ||||
| -rw-r--r-- | src/app/state.rs | 2 |
10 files changed, 57 insertions, 11 deletions
diff --git a/src/app/api.rs b/src/app/api.rs index df20cd34..a26b2856 100644 --- a/src/app/api.rs +++ b/src/app/api.rs @@ -311,7 +311,7 @@ impl App { cwd, self.state.pane_scrollback_limit_bytes, self.state.host_terminal_theme, - &self.state.default_shell, + crate::pane::PaneShellConfig::new(&self.state.default_shell, self.state.shell_mode), self.event_tx.clone(), self.render_notify.clone(), self.render_dirty.clone(), @@ -644,7 +644,7 @@ mod tests { live_cwd.clone(), 0, crate::terminal_theme::TerminalTheme::default(), - "/bin/sh", + crate::pane::PaneShellConfig::new("/bin/sh", crate::config::ShellModeConfig::NonLogin), events, std::sync::Arc::new(tokio::sync::Notify::new()), std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), diff --git a/src/app/api/panes.rs b/src/app/api/panes.rs index 4620329f..67bac8d3 100644 --- a/src/app/api/panes.rs +++ b/src/app/api/panes.rs @@ -50,7 +50,7 @@ impl App { split_cwd, scrollback_limit_bytes, host_terminal_theme, - &default_shell, + crate::pane::PaneShellConfig::new(&default_shell, self.state.shell_mode), params.focus, ) { Some(Ok(result)) => result, diff --git a/src/app/api/tabs.rs b/src/app/api/tabs.rs index f605d143..4057eced 100644 --- a/src/app/api/tabs.rs +++ b/src/app/api/tabs.rs @@ -86,7 +86,7 @@ impl App { cwd, scrollback_limit_bytes, host_terminal_theme, - &default_shell, + crate::pane::PaneShellConfig::new(&default_shell, self.state.shell_mode), ) }); match result { diff --git a/src/app/creation.rs b/src/app/creation.rs index 0f63d60d..f8edd676 100644 --- a/src/app/creation.rs +++ b/src/app/creation.rs @@ -110,7 +110,7 @@ impl App { initial_cwd, self.state.pane_scrollback_limit_bytes, self.state.host_terminal_theme, - &self.state.default_shell, + crate::pane::PaneShellConfig::new(&self.state.default_shell, self.state.shell_mode), )?; let root_pane = ws.tabs[idx].root_pane; self.terminal_runtimes.insert(terminal.id.clone(), runtime); @@ -142,7 +142,7 @@ impl App { cols, self.state.pane_scrollback_limit_bytes, self.state.host_terminal_theme, - &self.state.default_shell, + crate::pane::PaneShellConfig::new(&self.state.default_shell, self.state.shell_mode), self.event_tx.clone(), self.render_notify.clone(), self.render_dirty.clone(), diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs index 76a32fc1..cfcc3039 100644 --- a/src/app/input/mod.rs +++ b/src/app/input/mod.rs @@ -417,7 +417,7 @@ impl AppState { cwd, self.pane_scrollback_limit_bytes, self.host_terminal_theme, - &self.default_shell, + crate::pane::PaneShellConfig::new(&self.default_shell, self.shell_mode), ) { let new_id = new_pane.pane_id; terminal_runtimes.insert(new_pane.terminal.id.clone(), new_pane.runtime); diff --git a/src/app/input/mouse.rs b/src/app/input/mouse.rs index a9badfa9..e3ad0bc5 100644 --- a/src/app/input/mouse.rs +++ b/src/app/input/mouse.rs @@ -1975,7 +1975,7 @@ mod tests { 80, app.state.pane_scrollback_limit_bytes, app.state.host_terminal_theme, - &app.state.default_shell, + crate::pane::PaneShellConfig::new(&app.state.default_shell, app.state.shell_mode), app.event_tx.clone(), app.render_notify.clone(), app.render_dirty.clone(), diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs index e7581c5b..6a7e8d7c 100644 --- a/src/app/input/navigate.rs +++ b/src/app/input/navigate.rs @@ -1820,7 +1820,7 @@ last_pane = "prefix+tab" 80, app.state.pane_scrollback_limit_bytes, app.state.host_terminal_theme, - &app.state.default_shell, + crate::pane::PaneShellConfig::new(&app.state.default_shell, app.state.shell_mode), app.event_tx.clone(), app.render_notify.clone(), app.render_dirty.clone(), diff --git a/src/app/input/terminal.rs b/src/app/input/terminal.rs index 0a35c3be..5447e2b0 100644 --- a/src/app/input/terminal.rs +++ b/src/app/input/terminal.rs @@ -845,7 +845,7 @@ mod tests { 80, app.state.pane_scrollback_limit_bytes, app.state.host_terminal_theme, - &app.state.default_shell, + crate::pane::PaneShellConfig::new(&app.state.default_shell, app.state.shell_mode), app.event_tx.clone(), app.render_notify.clone(), app.render_dirty.clone(), diff --git a/src/app/mod.rs b/src/app/mod.rs index 1291d2a0..d8071c4d 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -289,6 +289,7 @@ impl App { 80, config.advanced.scrollback_limit_bytes, &config.terminal.default_shell, + config.terminal.shell_mode, config.session.resume_agents_on_restore, event_tx.clone(), render_notify.clone(), @@ -499,6 +500,7 @@ impl App { cjk_ime_cursor_shape: config.experimental.cjk_ime_cursor_shape.to_decscusr(), kitty_graphics_enabled: config.experimental.kitty_graphics, default_shell: config.terminal.default_shell.clone(), + shell_mode: config.terminal.shell_mode, new_terminal_cwd: config.terminal.new_cwd.clone(), pane_scrollback_limit_bytes: config.advanced.scrollback_limit_bytes, accent: crate::config::parse_color(&config.ui.accent), @@ -606,6 +608,7 @@ impl App { snapshot, config.advanced.scrollback_limit_bytes, &config.terminal.default_shell, + config.terminal.shell_mode, imports, app.event_tx.clone(), app.render_notify.clone(), @@ -1143,6 +1146,7 @@ impl App { if !invalid_section("terminal") { self.state.default_shell = config.terminal.default_shell.clone(); + self.state.shell_mode = config.terminal.shell_mode; self.state.new_terminal_cwd = config.terminal.new_cwd.clone(); } @@ -1707,7 +1711,7 @@ mod tests { std::fs::create_dir_all(path.parent().unwrap()).unwrap(); std::fs::write( &path, - "[terminal]\ndefault_shell = \"nu\"\nnew_cwd = \"home\"\n[keys]\nnew_workspace = \"prefix+m\"\nprefix = \"ctrl+a\"\n[ui]\nagent_panel_scope = \"current\"\nredraw_on_focus_gained = false\n[ui.toast]\ndelivery = \"herdr\"\n", + "[terminal]\ndefault_shell = \"nu\"\nshell_mode = \"non_login\"\nnew_cwd = \"home\"\n[keys]\nnew_workspace = \"prefix+m\"\nprefix = \"ctrl+a\"\n[ui]\nagent_panel_scope = \"current\"\nredraw_on_focus_gained = false\n[ui.toast]\ndelivery = \"herdr\"\n", ) .unwrap(); std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path); @@ -1735,6 +1739,10 @@ mod tests { assert!(app.state.request_client_config_reload); assert_eq!(app.state.default_shell, "nu"); assert_eq!( + app.state.shell_mode, + crate::config::ShellModeConfig::NonLogin + ); + assert_eq!( app.state.new_terminal_cwd, crate::config::NewTerminalCwdConfig::Home ); @@ -1996,6 +2004,42 @@ mod tests { } #[test] + fn reload_config_preserves_invalid_terminal_section_but_applies_valid_ui() { + let _guard = config_env_lock().lock().unwrap(); + let path = temp_config_path("reload-config-invalid-terminal-section"); + std::fs::create_dir_all(path.parent().unwrap()).unwrap(); + std::fs::write( + &path, + "[terminal]\ndefault_shell = \"nu\"\nshell_mode = \"sideways\"\nnew_cwd = \"home\"\n[ui.toast]\ndelivery = \"terminal\"\n", + ) + .unwrap(); + std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path); + + let mut app = test_app(); + let original_default_shell = app.state.default_shell.clone(); + let original_shell_mode = app.state.shell_mode; + let original_new_cwd = app.state.new_terminal_cwd.clone(); + let report = app.reload_config(); + + assert_eq!(report.status, crate::config::ConfigReloadStatus::Partial); + assert_eq!(app.state.default_shell, original_default_shell); + assert_eq!(app.state.shell_mode, original_shell_mode); + assert_eq!(app.state.new_terminal_cwd, original_new_cwd); + assert_eq!( + app.state.toast_config.delivery, + crate::config::ToastDelivery::Terminal + ); + assert!(app + .state + .config_diagnostic + .as_deref() + .is_some_and(|message| message.contains("invalid terminal config"))); + + std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR); + let _ = std::fs::remove_dir_all(path.parent().unwrap()); + } + + #[test] fn settings_save_toast_delivery_persists_then_applies_live_config() { let _guard = config_env_lock().lock().unwrap(); let path = temp_config_path("settings-save-toast-delivery"); diff --git a/src/app/state.rs b/src/app/state.rs index 012d79e4..a9c1b8a3 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -1157,6 +1157,7 @@ pub struct AppState { pub cjk_ime_cursor_shape: u8, pub kitty_graphics_enabled: bool, pub default_shell: String, + pub shell_mode: crate::config::ShellModeConfig, pub new_terminal_cwd: NewTerminalCwdConfig, pub pane_scrollback_limit_bytes: usize, #[allow(dead_code)] // kept for backward compat; palette.accent is the source of truth @@ -1461,6 +1462,7 @@ impl AppState { cjk_ime_cursor_shape: 2, // steady_block kitty_graphics_enabled: false, default_shell: String::new(), + shell_mode: crate::config::ShellModeConfig::Auto, new_terminal_cwd: NewTerminalCwdConfig::Follow, pane_scrollback_limit_bytes: crate::config::DEFAULT_SCROLLBACK_LIMIT_BYTES, accent: Color::Cyan, |
