diff options
Diffstat (limited to 'src/workspace')
| -rw-r--r-- | src/workspace/tab.rs | 118 |
1 files changed, 53 insertions, 65 deletions
diff --git a/src/workspace/tab.rs b/src/workspace/tab.rs index 5cc35b68..6f0fa75e 100644 --- a/src/workspace/tab.rs +++ b/src/workspace/tab.rs @@ -205,6 +205,7 @@ impl Tab { self.custom_name = Some(name); } + #[cfg(test)] pub fn split_focused( &mut self, direction: Direction, @@ -217,7 +218,9 @@ impl Tab { shell_config: crate::pane::PaneShellConfig<'_>, launch_env: &PaneLaunchEnv, ) -> std::io::Result<NewPane> { - self.split_focused_with_runtime( + self.split_pane_with_runtime( + self.layout.focused(), + true, direction, None, rows, @@ -232,34 +235,6 @@ impl Tab { ) } - pub fn split_focused_with_ratio( - &mut self, - direction: Direction, - ratio: f32, - rows: u16, - cols: u16, - cwd: Option<PathBuf>, - scrollback_limit_bytes: usize, - host_terminal_theme: crate::terminal_theme::TerminalTheme, - host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, - shell_config: crate::pane::PaneShellConfig<'_>, - launch_env: &PaneLaunchEnv, - ) -> std::io::Result<NewPane> { - self.split_focused_with_runtime( - direction, - Some(ratio), - rows, - cols, - cwd, - scrollback_limit_bytes, - host_terminal_theme, - host_terminal_appearance, - shell_config, - launch_env, - None, - ) - } - pub fn split_focused_command( &mut self, direction: Direction, @@ -272,7 +247,9 @@ impl Tab { host_terminal_theme: crate::terminal_theme::TerminalTheme, host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, ) -> std::io::Result<NewPane> { - self.split_focused_with_runtime( + self.split_pane_with_runtime( + self.layout.focused(), + true, direction, None, rows, @@ -290,37 +267,51 @@ impl Tab { ) } - pub fn split_focused_argv_command( + /// Split `target` with a shell pane. Focus moves to the new pane only when + /// `focus_new_pane` is set; a spawn failure rolls the layout back without + /// touching focus or its history. + #[allow(clippy::too_many_arguments)] + pub(crate) fn split_pane_shell( &mut self, + target: PaneId, + focus_new_pane: bool, direction: Direction, + ratio: Option<f32>, rows: u16, cols: u16, cwd: Option<PathBuf>, - argv: &[String], - launch_env: &PaneLaunchEnv, scrollback_limit_bytes: usize, host_terminal_theme: crate::terminal_theme::TerminalTheme, host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, + shell_config: crate::pane::PaneShellConfig<'_>, + launch_env: &PaneLaunchEnv, ) -> std::io::Result<NewPane> { - self.split_focused_with_runtime( + self.split_pane_with_runtime( + target, + focus_new_pane, direction, - None, + ratio, rows, cols, cwd, scrollback_limit_bytes, host_terminal_theme, host_terminal_appearance, - crate::pane::PaneShellConfig::new("", crate::config::ShellModeConfig::NonLogin), + shell_config, launch_env, - Some(SplitCommand::Argv { argv, launch_env }), + None, ) } - pub fn split_focused_argv_command_with_ratio( + /// Split `target` with an argv-command pane. Same focus contract as + /// `split_pane_shell`. + #[allow(clippy::too_many_arguments)] + pub(crate) fn split_pane_argv( &mut self, + target: PaneId, + focus_new_pane: bool, direction: Direction, - ratio: f32, + ratio: Option<f32>, rows: u16, cols: u16, cwd: Option<PathBuf>, @@ -330,9 +321,11 @@ impl Tab { host_terminal_theme: crate::terminal_theme::TerminalTheme, host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, ) -> std::io::Result<NewPane> { - self.split_focused_with_runtime( + self.split_pane_with_runtime( + target, + focus_new_pane, direction, - Some(ratio), + ratio, rows, cols, cwd, @@ -347,8 +340,10 @@ impl Tab { // Split construction threads geometry, host context, launch policy, and command state. #[allow(clippy::too_many_arguments)] - fn split_focused_with_runtime( + fn split_pane_with_runtime( &mut self, + target: PaneId, + focus_new_pane: bool, direction: Direction, ratio: Option<f32>, rows: u16, @@ -361,10 +356,14 @@ impl Tab { launch_env: &PaneLaunchEnv, command: Option<SplitCommand<'_>>, ) -> std::io::Result<NewPane> { - let previous_focus = self.layout.focused(); - let new_id = match ratio { - Some(ratio) => self.layout.split_focused_with_ratio(direction, ratio), - None => self.layout.split_focused(direction), + let Some(new_id) = self + .layout + .split_pane(target, direction, ratio.unwrap_or(0.5)) + else { + return Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + "split target pane is not in the layout", + )); }; let actual_cwd = cwd.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| "/".into())); @@ -425,8 +424,7 @@ impl Tab { let runtime = match runtime { Ok(runtime) => runtime, Err(err) => { - self.layout.close_focused(); - self.layout.focus_pane(previous_focus); + self.layout.close_pane(new_id); return Err(err); } }; @@ -437,6 +435,9 @@ impl Tab { } None => TerminalState::new(terminal_id.clone(), actual_cwd), }; + if focus_new_pane { + self.layout.focus_pane(new_id); + } self.panes.insert(new_id, PaneState::new(terminal_id)); self.zoomed = false; Ok(NewPane { @@ -493,14 +494,7 @@ impl Tab { if self.layout.pane_count() > 1 { let next_root = self.promoted_root_if_needed(pane_id); - if self.layout.focused() == pane_id { - self.layout.close_focused(); - } else { - let prev_focus = self.layout.focused(); - self.layout.focus_pane(pane_id); - self.layout.close_focused(); - self.layout.focus_pane(prev_focus); - } + self.layout.close_pane(pane_id); if let Some(next_root) = next_root { self.root_pane = next_root; } @@ -520,10 +514,11 @@ impl Tab { moved: MovedPane, direction: Direction, ratio: f32, + focus: bool, ) -> Result<PaneId, MovedPane> { if !self .layout - .insert_pane_near(target_pane_id, moved.pane_id, direction, ratio) + .insert_pane_near(target_pane_id, moved.pane_id, direction, ratio, focus) { return Err(moved); } @@ -540,14 +535,7 @@ impl Tab { let next_root = self.promoted_root_if_needed(pane_id); - if self.layout.focused() == pane_id { - self.layout.close_focused(); - } else { - let prev_focus = self.layout.focused(); - self.layout.focus_pane(pane_id); - self.layout.close_focused(); - self.layout.focus_pane(prev_focus); - } + self.layout.close_pane(pane_id); let pane = self.panes.remove(&pane_id)?; let terminal_id = pane.attached_terminal_id; |
