aboutsummaryrefslogtreecommitdiff
path: root/src/workspace
diff options
context:
space:
mode:
Diffstat (limited to 'src/workspace')
-rw-r--r--src/workspace/tab.rs118
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;