aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/api.rs4
-rw-r--r--src/app/api/panes.rs2
-rw-r--r--src/app/api/tabs.rs2
-rw-r--r--src/app/creation.rs4
-rw-r--r--src/app/input/mod.rs2
-rw-r--r--src/app/input/mouse.rs2
-rw-r--r--src/app/input/navigate.rs2
-rw-r--r--src/app/input/terminal.rs2
-rw-r--r--src/app/mod.rs46
-rw-r--r--src/app/state.rs2
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,