Errors: less unwrap in server (#2069)

* server/pty: Remove last `unwrap`

* server/route: Remove calls to `unwrap`

* server/screen: Remove calls to `unwrap`

* WIP: server/plugins: Remove calls to unwrap

* server/route: Apply rustfmt

* server/plugins: Remove last `unwrap`s

* server/screen: update tabs before rendering

which was previously accidentally changed.

* server/tab: Remove calls to `unwrap`

* server/plugins: Add context to plugin panic reporter

* changelog: Add PR #2069
This commit is contained in:
har7an 2023-01-14 05:14:17 +00:00 committed by GitHub
parent 1e02754e19
commit 04b294aabb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 563 additions and 350 deletions

View file

@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* fix: copy_on_select = false sticky selection (https://github.com/zellij-org/zellij/pull/2086)
* fix: do not drop wide chars when resizing to width of 1 column (https://github.com/zellij-org/zellij/pull/2082)
* fix: disallow path-like names for sessions (https://github.com/zellij-org/zellij/pull/2082)
* errors: Remove more `unwrwap`s from server code (https://github.com/zellij-org/zellij/pull/2069)
## [0.34.4] - 2022-12-13

View file

@ -122,6 +122,17 @@ pub struct PluginEnv {
plugin_own_data_dir: PathBuf,
}
impl PluginEnv {
// Get the name (path) of the containing plugin
pub fn name(&self) -> String {
format!(
"{} (ID {})",
self.plugin.path.display().to_string(),
self.plugin_id
)
}
}
type PluginMap = HashMap<(u32, ClientId), (Instance, PluginEnv, (usize, usize))>; // u32 =>
// plugin_id,
// (usize, usize)
@ -407,18 +418,21 @@ impl WasmBridge {
*current_columns = new_columns;
// TODO: consolidate with above render function
let render = instance
let rendered_bytes = instance
.exports
.get_function("render")
.with_context(err_context)?;
.map_err(anyError::new)
.and_then(|render| {
render
.call(&[
Value::I32(*current_rows as i32),
Value::I32(*current_columns as i32),
])
.map_err(anyError::new)
})
.and_then(|_| wasi_read_string(&plugin_env.wasi_env))
.with_context(err_context)?;
let rendered_bytes = wasi_read_string(&plugin_env.wasi_env);
plugin_bytes.push((*plugin_id, *client_id, rendered_bytes.as_bytes().to_vec()));
}
}
@ -462,7 +476,7 @@ impl WasmBridge {
.exports
.get_function("update")
.with_context(err_context)?;
wasi_write_object(&plugin_env.wasi_env, &event);
wasi_write_object(&plugin_env.wasi_env, &event).with_context(err_context)?;
let update_return = update.call(&[]).or_else::<anyError, _>(|e| {
match e.downcast::<serde_json::Error>() {
Ok(_) => panic!(
@ -483,14 +497,17 @@ impl WasmBridge {
};
if *rows > 0 && *columns > 0 && should_render {
let render = instance
let rendered_bytes = instance
.exports
.get_function("render")
.with_context(err_context)?;
.map_err(anyError::new)
.and_then(|render| {
render
.call(&[Value::I32(*rows as i32), Value::I32(*columns as i32)])
.map_err(anyError::new)
})
.and_then(|_| wasi_read_string(&plugin_env.wasi_env))
.with_context(err_context)?;
let rendered_bytes = wasi_read_string(&plugin_env.wasi_env);
plugin_bytes.push((
plugin_id,
client_id,
@ -531,10 +548,12 @@ fn assert_plugin_version(instance: &Instance, plugin_env: &PluginEnv) -> Result<
)))
},
};
plugin_version_func.call(&[]).with_context(err_context)?;
let plugin_version_str = wasi_read_string(&plugin_env.wasi_env);
let plugin_version = Version::parse(&plugin_version_str)
.context("failed to parse plugin version")
let plugin_version = plugin_version_func
.call(&[])
.map_err(anyError::new)
.and_then(|_| wasi_read_string(&plugin_env.wasi_env))
.and_then(|string| Version::parse(&string).context("failed to parse plugin version"))
.with_context(err_context)?;
let zellij_version = Version::parse(VERSION)
.context("failed to parse zellij version")
@ -542,7 +561,7 @@ fn assert_plugin_version(instance: &Instance, plugin_env: &PluginEnv) -> Result<
if plugin_version != zellij_version {
return Err(anyError::new(VersionMismatchError::new(
VERSION,
&plugin_version_str,
&plugin_version.to_string(),
&plugin_env.plugin.path,
plugin_env.plugin.is_builtin(),
)));
@ -590,15 +609,27 @@ pub(crate) fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObj
}
fn host_subscribe(plugin_env: &PluginEnv) {
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
let new: HashSet<EventType> = wasi_read_object(&plugin_env.wasi_env);
subscriptions.extend(new);
wasi_read_object::<HashSet<EventType>>(&plugin_env.wasi_env)
.and_then(|new| {
plugin_env.subscriptions.lock().to_anyhow()?.extend(new);
Ok(())
})
.with_context(|| format!("failed to subscribe for plugin {}", plugin_env.name()))
.fatal();
}
fn host_unsubscribe(plugin_env: &PluginEnv) {
let mut subscriptions = plugin_env.subscriptions.lock().unwrap();
let old: HashSet<EventType> = wasi_read_object(&plugin_env.wasi_env);
subscriptions.retain(|k| !old.contains(k));
wasi_read_object::<HashSet<EventType>>(&plugin_env.wasi_env)
.and_then(|old| {
plugin_env
.subscriptions
.lock()
.to_anyhow()?
.retain(|k| !old.contains(k));
Ok(())
})
.with_context(|| format!("failed to unsubscribe for plugin {}", plugin_env.name()))
.fatal();
}
fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
@ -612,7 +643,14 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
selectable,
tab_index,
))
.unwrap()
.with_context(|| {
format!(
"failed to set plugin {} selectable from plugin {}",
selectable,
plugin_env.name()
)
})
.non_fatal();
},
_ => {
debug!(
@ -628,15 +666,30 @@ fn host_get_plugin_ids(plugin_env: &PluginEnv) {
plugin_id: plugin_env.plugin_id,
zellij_pid: process::id(),
};
wasi_write_object(&plugin_env.wasi_env, &ids);
wasi_write_object(&plugin_env.wasi_env, &ids)
.with_context(|| {
format!(
"failed to query plugin IDs from host for plugin {}",
plugin_env.name()
)
})
.non_fatal();
}
fn host_get_zellij_version(plugin_env: &PluginEnv) {
wasi_write_object(&plugin_env.wasi_env, VERSION);
wasi_write_object(&plugin_env.wasi_env, VERSION)
.with_context(|| {
format!(
"failed to request zellij version from host for plugin {}",
plugin_env.name()
)
})
.non_fatal();
}
fn host_open_file(plugin_env: &PluginEnv) {
let path: PathBuf = wasi_read_object(&plugin_env.wasi_env);
wasi_read_object::<PathBuf>(&plugin_env.wasi_env)
.and_then(|path| {
plugin_env
.senders
.send_to_pty(PtyInstruction::SpawnTerminal(
@ -645,7 +698,14 @@ fn host_open_file(plugin_env: &PluginEnv) {
None,
ClientOrTabIndex::TabIndex(plugin_env.tab_index),
))
.unwrap();
})
.with_context(|| {
format!(
"failed to open file on host from plugin {}",
plugin_env.name()
)
})
.non_fatal();
}
fn host_switch_tab_to(plugin_env: &PluginEnv, tab_idx: u32) {
@ -655,7 +715,13 @@ fn host_switch_tab_to(plugin_env: &PluginEnv, tab_idx: u32) {
tab_idx,
Some(plugin_env.client_id),
))
.unwrap();
.with_context(|| {
format!(
"failed to switch host to tab {tab_idx} from plugin {}",
plugin_env.name()
)
})
.non_fatal();
}
fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) {
@ -671,6 +737,7 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) {
let send_plugin_instructions = plugin_env.senders.to_plugin.clone();
let update_target = Some(plugin_env.plugin_id);
let client_id = plugin_env.client_id;
let plugin_name = plugin_env.name();
thread::spawn(move || {
let start_time = Instant::now();
thread::sleep(Duration::from_secs_f64(secs));
@ -679,18 +746,37 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) {
let elapsed_time = Instant::now().duration_since(start_time).as_secs_f64();
send_plugin_instructions
.unwrap()
.ok_or(anyhow!("found no sender to send plugin instruction to"))
.and_then(|sender| {
sender
.send(PluginInstruction::Update(vec![(
update_target,
Some(client_id),
Event::Timer(elapsed_time),
)]))
.unwrap();
.to_anyhow()
})
.with_context(|| {
format!(
"failed to set host timeout of {secs} s for plugin {}",
plugin_name
)
})
.non_fatal();
});
}
fn host_exec_cmd(plugin_env: &PluginEnv) {
let mut cmdline: Vec<String> = wasi_read_object(&plugin_env.wasi_env);
let err_context = || {
format!(
"failed to execute command on host for plugin '{}'",
plugin_env.name()
)
};
let mut cmdline: Vec<String> = wasi_read_object(&plugin_env.wasi_env)
.with_context(err_context)
.fatal();
let command = cmdline.remove(0);
// Bail out if we're forbidden to run command
@ -704,7 +790,8 @@ fn host_exec_cmd(plugin_env: &PluginEnv) {
process::Command::new(command)
.args(cmdline)
.spawn()
.unwrap();
.with_context(err_context)
.non_fatal();
}
// Custom panic handler for plugins.
@ -713,32 +800,58 @@ fn host_exec_cmd(plugin_env: &PluginEnv) {
// code trying to deserialize an `Event` upon a plugin state update, we read some panic message,
// formatted as string from the plugin.
fn host_report_panic(plugin_env: &PluginEnv) {
let msg = wasi_read_string(&plugin_env.wasi_env);
let msg = wasi_read_string(&plugin_env.wasi_env)
.with_context(|| format!("failed to report panic for plugin '{}'", plugin_env.name()))
.fatal();
panic!("{}", msg);
}
// Helper Functions ---------------------------------------------------------------------------------------------------
pub fn wasi_read_string(wasi_env: &WasiEnv) -> String {
let mut state = wasi_env.state();
let wasi_file = state.fs.stdout_mut().unwrap().as_mut().unwrap();
pub fn wasi_read_string(wasi_env: &WasiEnv) -> Result<String> {
let err_context = || format!("failed to read string from WASI env '{wasi_env:?}'");
let mut buf = String::new();
wasi_file.read_to_string(&mut buf).unwrap();
wasi_env
.state()
.fs
.stdout_mut()
.map_err(anyError::new)
.and_then(|stdout| {
stdout
.as_mut()
.ok_or(anyhow!("failed to get mutable reference to stdout"))
})
.and_then(|wasi_file| wasi_file.read_to_string(&mut buf).map_err(anyError::new))
.with_context(err_context)?;
// https://stackoverflow.com/questions/66450942/in-rust-is-there-a-way-to-make-literal-newlines-in-r-using-windows-c
buf.replace("\n", "\n\r")
Ok(buf.replace("\n", "\n\r"))
}
pub fn wasi_write_string(wasi_env: &WasiEnv, buf: &str) {
let mut state = wasi_env.state();
let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap();
writeln!(wasi_file, "{}\r", buf).unwrap();
pub fn wasi_write_string(wasi_env: &WasiEnv, buf: &str) -> Result<()> {
wasi_env
.state()
.fs
.stdin_mut()
.map_err(anyError::new)
.and_then(|stdin| {
stdin
.as_mut()
.ok_or(anyhow!("failed to get mutable reference to stdin"))
})
.and_then(|stdin| writeln!(stdin, "{}\r", buf).map_err(anyError::new))
.with_context(|| format!("failed to write string to WASI env '{wasi_env:?}'"))
}
pub fn wasi_write_object(wasi_env: &WasiEnv, object: &(impl Serialize + ?Sized)) {
wasi_write_string(wasi_env, &serde_json::to_string(&object).unwrap());
pub fn wasi_write_object(wasi_env: &WasiEnv, object: &(impl Serialize + ?Sized)) -> Result<()> {
serde_json::to_string(&object)
.map_err(anyError::new)
.and_then(|string| wasi_write_string(wasi_env, &string))
.with_context(|| format!("failed to serialize object for WASI env '{wasi_env:?}'"))
}
pub fn wasi_read_object<T: DeserializeOwned>(wasi_env: &WasiEnv) -> T {
let json = wasi_read_string(wasi_env);
serde_json::from_str(&json).unwrap()
pub fn wasi_read_object<T: DeserializeOwned>(wasi_env: &WasiEnv) -> Result<T> {
wasi_read_string(wasi_env)
.and_then(|string| serde_json::from_str(&string).map_err(anyError::new))
.with_context(|| format!("failed to deserialize object from WASI env '{wasi_env:?}'"))
}

View file

@ -513,7 +513,13 @@ impl Pty {
if hold_on_start {
// we don't actually open a terminal in this case, just wait for the user to run it
let starts_held = hold_on_start;
let terminal_id = self.bus.os_input.as_mut().unwrap().reserve_terminal_id()?;
let terminal_id = self
.bus
.os_input
.as_mut()
.context("couldn't get mutable reference to OS interface")
.and_then(|os_input| os_input.reserve_terminal_id())
.with_context(err_context)?;
return Ok((terminal_id, starts_held));
}

View file

@ -618,14 +618,13 @@ pub(crate) fn route_action(
macro_rules! send_to_screen_or_retry_queue {
($rlocked_sessions:expr, $message:expr, $instruction: expr, $retry_queue:expr) => {{
match $rlocked_sessions.as_ref() {
Some(session_metadata) => {
session_metadata.senders.send_to_screen($message).unwrap();
},
Some(session_metadata) => session_metadata.senders.send_to_screen($message),
None => {
log::warn!("Server not ready, trying to place instruction in retry queue...");
if let Some(retry_queue) = $retry_queue.as_mut() {
retry_queue.push($instruction);
}
Ok(())
},
}
}};
@ -645,7 +644,7 @@ pub(crate) fn route_thread_main(
match receiver.recv() {
Some((instruction, err_ctx)) => {
err_ctx.update_thread_ctx();
let rlocked_sessions = session_data.read().unwrap();
let rlocked_sessions = session_data.read().to_anyhow().with_context(err_context)?;
let handle_instruction = |instruction: ClientToServerMsg,
mut retry_queue: Option<&mut Vec<ClientToServerMsg>>|
-> Result<bool> {
@ -679,18 +678,24 @@ pub(crate) fn route_thread_main(
ClientToServerMsg::TerminalResize(new_size) => {
session_state
.write()
.unwrap()
.to_anyhow()
.with_context(err_context)?
.set_client_size(client_id, new_size);
let min_size = session_state
session_state
.read()
.unwrap()
.min_client_terminal_size()
.with_context(err_context)?;
.to_anyhow()
.and_then(|state| {
state.min_client_terminal_size().ok_or(anyhow!(
"failed to determine minimal client terminal size"
))
})
.and_then(|min_size| {
rlocked_sessions
.as_ref()
.unwrap()
.context("couldn't get reference to read-locked session")?
.senders
.send_to_screen(ScreenInstruction::TerminalResize(min_size))
})
.with_context(err_context)?;
},
ClientToServerMsg::TerminalPixelDimensions(pixel_dimensions) => {
@ -699,7 +704,8 @@ pub(crate) fn route_thread_main(
ScreenInstruction::TerminalPixelDimensions(pixel_dimensions),
instruction,
retry_queue
);
)
.with_context(err_context)?;
},
ClientToServerMsg::BackgroundColor(ref background_color_instruction) => {
send_to_screen_or_retry_queue!(
@ -709,7 +715,8 @@ pub(crate) fn route_thread_main(
),
instruction,
retry_queue
);
)
.with_context(err_context)?;
},
ClientToServerMsg::ForegroundColor(ref foreground_color_instruction) => {
send_to_screen_or_retry_queue!(
@ -719,7 +726,8 @@ pub(crate) fn route_thread_main(
),
instruction,
retry_queue
);
)
.with_context(err_context)?;
},
ClientToServerMsg::ColorRegisters(ref color_registers) => {
send_to_screen_or_retry_queue!(
@ -727,7 +735,8 @@ pub(crate) fn route_thread_main(
ScreenInstruction::TerminalColorRegisters(color_registers.clone()),
instruction,
retry_queue
);
)
.with_context(err_context)?;
},
ClientToServerMsg::NewClient(
client_attributes,

View file

@ -738,13 +738,15 @@ impl Screen {
}
pub fn resize_to_screen(&mut self, new_screen_size: Size) -> Result<()> {
let err_context = || format!("failed to resize to screen size: {new_screen_size:#?}");
self.size = new_screen_size;
for tab in self.tabs.values_mut() {
tab.resize_whole_tab(new_screen_size);
tab.resize_whole_tab(new_screen_size)
.with_context(err_context)?;
tab.set_force_render();
}
self.render()
.with_context(|| format!("failed to resize to screen size: {new_screen_size:#?}"))
self.render().with_context(err_context)
}
pub fn update_pixel_dimensions(&mut self, pixel_dimensions: PixelDimensions) {
@ -970,7 +972,10 @@ impl Screen {
};
// apply the layout to the new tab
let tab = self.tabs.get_mut(&tab_index).unwrap(); // TODO: no unwrap
self.tabs
.get_mut(&tab_index)
.context("couldn't find tab with index {tab_index}")
.and_then(|tab| {
tab.apply_layout(
layout,
floating_panes_layout,
@ -978,21 +983,24 @@ impl Screen {
new_floating_terminal_ids,
new_plugin_ids,
client_id,
)
.with_context(err_context)?;
tab.update_input_modes().with_context(err_context)?;
tab.visible(true).with_context(err_context)?;
)?;
tab.update_input_modes()?;
tab.visible(true)?;
if let Some(drained_clients) = drained_clients {
tab.add_multiple_clients(drained_clients)
.with_context(err_context)?;
tab.add_multiple_clients(drained_clients)?;
}
Ok(())
})
.with_context(err_context)?;
if !self.active_tab_indices.contains_key(&client_id) {
// this means this is a new client and we need to add it to our state properly
self.add_client(client_id).with_context(err_context)?;
}
self.update_tabs().with_context(err_context)?;
self.render().with_context(err_context)
self.update_tabs()
.and_then(|_| self.render())
.with_context(err_context)
}
pub fn add_client(&mut self, client_id: ClientId) -> Result<()> {
@ -1243,10 +1251,17 @@ impl Screen {
if let Some(client_id) = client_id {
match self.get_active_tab_mut(client_id) {
Ok(active_tab) => {
if !active_tab.move_focus_left(client_id) {
active_tab
.move_focus_left(client_id)
.and_then(|success| {
if !success {
self.switch_tab_prev(client_id)
.context("failed to move focus left")?;
.context("failed to move focus to previous tab")
} else {
Ok(())
}
})
.with_context(err_context)?;
},
Err(err) => Err::<(), _>(err).with_context(err_context).non_fatal(),
};
@ -1270,10 +1285,17 @@ impl Screen {
if let Some(client_id) = client_id {
match self.get_active_tab_mut(client_id) {
Ok(active_tab) => {
if !active_tab.move_focus_right(client_id) {
active_tab
.move_focus_right(client_id)
.and_then(|success| {
if !success {
self.switch_tab_next(client_id)
.context("failed to move focus right")?;
.context("failed to move focus to next tab")
} else {
Ok(())
}
})
.with_context(err_context)?;
},
Err(err) => Err::<(), _>(err).with_context(err_context).non_fatal(),
};
@ -1560,7 +1582,8 @@ pub(crate) fn screen_thread_main(
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| tab.move_focus_left(client_id)
|tab: &mut Tab, client_id: ClientId| tab.move_focus_left(client_id),
?
);
screen.render()?;
screen.unblock_input()?;
@ -1574,7 +1597,8 @@ pub(crate) fn screen_thread_main(
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| tab.move_focus_down(client_id)
|tab: &mut Tab, client_id: ClientId| tab.move_focus_down(client_id),
?
);
screen.render()?;
screen.unblock_input()?;
@ -1583,7 +1607,8 @@ pub(crate) fn screen_thread_main(
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| tab.move_focus_right(client_id)
|tab: &mut Tab, client_id: ClientId| tab.move_focus_right(client_id),
?
);
screen.render()?;
screen.unblock_input()?;
@ -1597,7 +1622,8 @@ pub(crate) fn screen_thread_main(
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| tab.move_focus_up(client_id)
|tab: &mut Tab, client_id: ClientId| tab.move_focus_up(client_id),
?
);
screen.render()?;
screen.unblock_input()?;

View file

@ -198,7 +198,7 @@ impl<'a> LayoutApplier<'a> {
.send_to_pty(PtyInstruction::ClosePane(PaneId::Terminal(*unused_pid)))
.with_context(err_context)?;
}
self.adjust_viewport();
self.adjust_viewport().with_context(err_context)?;
self.set_focused_tiled_pane(focus_pane_id, client_id);
},
Err(e) => {
@ -309,12 +309,21 @@ impl<'a> LayoutApplier<'a> {
Ok(false)
}
}
fn resize_whole_tab(&mut self, new_screen_size: Size) {
fn resize_whole_tab(&mut self, new_screen_size: Size) -> Result<()> {
let err_context = || {
format!(
"failed to resize whole tab to new screen size {:?}",
new_screen_size
)
};
self.floating_panes.resize(new_screen_size);
// we need to do this explicitly because floating_panes.resize does not do this
self.floating_panes
.resize_pty_all_panes(&mut self.os_api)
.unwrap(); // we need to do this explicitly because floating_panes.resize does not do this
.with_context(err_context)?;
self.tiled_panes.resize(new_screen_size);
Ok(())
}
fn offset_viewport(&mut self, position_and_size: &Viewport) {
let mut viewport = self.viewport.borrow_mut();
@ -339,23 +348,26 @@ impl<'a> LayoutApplier<'a> {
}
}
}
fn adjust_viewport(&mut self) {
fn adjust_viewport(&mut self) -> Result<()> {
// here we offset the viewport after applying a tiled panes layout
// from borderless panes that are on the edges of the
// screen, this is so that when we don't have pane boundaries (eg. when they were
// disabled by the user) boundaries won't be drawn around these panes
// geometrically, we can only do this with panes that are on the edges of the
// screen - so it's mostly a best-effort thing
let err_context = "failed to adjust viewport";
let display_area = {
let display_area = self.display_area.borrow();
*display_area
};
self.resize_whole_tab(display_area);
self.resize_whole_tab(display_area).context(err_context)?;
let boundary_geoms = self.tiled_panes.borderless_pane_geoms();
for geom in boundary_geoms {
self.offset_viewport(&geom)
}
self.tiled_panes.set_pane_frames(self.draw_pane_frames);
Ok(())
}
fn set_focused_tiled_pane(&mut self, focus_pane_id: Option<PaneId>, client_id: ClientId) {
if let Some(pane_id) = focus_pane_id {

View file

@ -1230,7 +1230,10 @@ impl Tab {
let err_context = || format!("failed to write to terminal at position {position:?}");
if self.floating_panes.panes_are_visible() {
let pane_id = self.floating_panes.get_pane_id_at(position, false).unwrap();
let pane_id = self
.floating_panes
.get_pane_id_at(position, false)
.with_context(err_context)?;
if let Some(pane_id) = pane_id {
self.write_to_pane_id(input_bytes, pane_id)
.with_context(err_context)?;
@ -1518,13 +1521,17 @@ impl Tab {
let selectable_tiled_panes = self.tiled_panes.get_panes().filter(|(_, p)| p.selectable());
selectable_tiled_panes.count() > 0
}
pub fn resize_whole_tab(&mut self, new_screen_size: Size) {
pub fn resize_whole_tab(&mut self, new_screen_size: Size) -> Result<()> {
let err_context = || format!("failed to resize whole tab (index {})", self.index);
self.floating_panes.resize(new_screen_size);
// we need to do this explicitly because floating_panes.resize does not do this
self.floating_panes
.resize_pty_all_panes(&mut self.os_api)
.unwrap(); // we need to do this explicitly because floating_panes.resize does not do this
.with_context(err_context)?;
self.tiled_panes.resize(new_screen_size);
self.should_clear_display_before_rendering = true;
Ok(())
}
pub fn resize(&mut self, client_id: ClientId, strategy: ResizeStrategy) -> Result<()> {
let err_context = || format!("unable to resize pane");
@ -1532,7 +1539,7 @@ impl Tab {
let successfully_resized = self
.floating_panes
.resize_active_pane(client_id, &mut self.os_api, &strategy)
.unwrap();
.with_context(err_context)?;
if successfully_resized {
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" in case of a decrease
}
@ -1590,7 +1597,9 @@ impl Tab {
self.tiled_panes.focus_previous_pane(client_id);
}
// returns a boolean that indicates whether the focus moved
pub fn move_focus_left(&mut self, client_id: ClientId) -> bool {
pub fn move_focus_left(&mut self, client_id: ClientId) -> Result<bool> {
let err_context = || format!("failed to move focus left for client {}", client_id);
if self.floating_panes.panes_are_visible() {
self.floating_panes
.move_focus(
@ -1598,19 +1607,21 @@ impl Tab {
&self.connected_clients.borrow().iter().copied().collect(),
&Direction::Left,
)
.unwrap()
.with_context(err_context)
} else {
if !self.has_selectable_panes() {
return false;
return Ok(false);
}
if self.tiled_panes.fullscreen_is_active() {
self.switch_next_pane_fullscreen(client_id);
return true;
return Ok(true);
}
self.tiled_panes.move_focus_left(client_id)
Ok(self.tiled_panes.move_focus_left(client_id))
}
}
pub fn move_focus_down(&mut self, client_id: ClientId) -> bool {
pub fn move_focus_down(&mut self, client_id: ClientId) -> Result<bool> {
let err_context = || format!("failed to move focus down for client {}", client_id);
if self.floating_panes.panes_are_visible() {
self.floating_panes
.move_focus(
@ -1618,18 +1629,20 @@ impl Tab {
&self.connected_clients.borrow().iter().copied().collect(),
&Direction::Down,
)
.unwrap()
.with_context(err_context)
} else {
if !self.has_selectable_panes() {
return false;
return Ok(false);
}
if self.tiled_panes.fullscreen_is_active() {
return false;
return Ok(false);
}
self.tiled_panes.move_focus_down(client_id)
Ok(self.tiled_panes.move_focus_down(client_id))
}
}
pub fn move_focus_up(&mut self, client_id: ClientId) -> bool {
pub fn move_focus_up(&mut self, client_id: ClientId) -> Result<bool> {
let err_context = || format!("failed to move focus up for client {}", client_id);
if self.floating_panes.panes_are_visible() {
self.floating_panes
.move_focus(
@ -1637,19 +1650,21 @@ impl Tab {
&self.connected_clients.borrow().iter().copied().collect(),
&Direction::Up,
)
.unwrap()
.with_context(err_context)
} else {
if !self.has_selectable_panes() {
return false;
return Ok(false);
}
if self.tiled_panes.fullscreen_is_active() {
return false;
return Ok(false);
}
self.tiled_panes.move_focus_up(client_id)
Ok(self.tiled_panes.move_focus_up(client_id))
}
}
// returns a boolean that indicates whether the focus moved
pub fn move_focus_right(&mut self, client_id: ClientId) -> bool {
pub fn move_focus_right(&mut self, client_id: ClientId) -> Result<bool> {
let err_context = || format!("failed to move focus right for client {}", client_id);
if self.floating_panes.panes_are_visible() {
self.floating_panes
.move_focus(
@ -1657,16 +1672,16 @@ impl Tab {
&self.connected_clients.borrow().iter().copied().collect(),
&Direction::Right,
)
.unwrap()
.with_context(err_context)
} else {
if !self.has_selectable_panes() {
return false;
return Ok(false);
}
if self.tiled_panes.fullscreen_is_active() {
self.switch_next_pane_fullscreen(client_id);
return true;
return Ok(true);
}
self.tiled_panes.move_focus_right(client_id)
Ok(self.tiled_panes.move_focus_right(client_id))
}
}
pub fn move_active_pane(&mut self, client_id: ClientId) {
@ -1796,7 +1811,15 @@ impl Tab {
// TODO: separate the "close_pane" logic and the "move_pane_somewhere_else" logic, they're
// overloaded here and that's not great
if !ignore_suppressed_panes && self.suppressed_panes.contains_key(&id) {
return self.replace_pane_with_suppressed_pane(id);
return match self.replace_pane_with_suppressed_pane(id) {
Ok(pane) => pane,
Err(e) => {
Err::<(), _>(e)
.with_context(|| format!("failed to close pane {:?}", id))
.non_fatal();
None
},
};
}
if self.floating_panes.panes_contain(&id) {
let closed_pane = self.floating_panes.remove_pane(id);
@ -1832,15 +1855,22 @@ impl Tab {
.hold_pane(id, exit_status, is_first_run, run_command);
}
}
pub fn replace_pane_with_suppressed_pane(&mut self, pane_id: PaneId) -> Option<Box<dyn Pane>> {
pub fn replace_pane_with_suppressed_pane(
&mut self,
pane_id: PaneId,
) -> Result<Option<Box<dyn Pane>>> {
self.suppressed_panes
.remove(&pane_id)
.with_context(|| {
format!(
"couldn't find pane with id {:?} in suppressed panes",
pane_id
)
})
.and_then(|suppressed_pane| {
let suppressed_pane_id = suppressed_pane.pid();
let replaced_pane = if self.are_floating_panes_visible() {
Some(self.floating_panes.replace_pane(pane_id, suppressed_pane))
.transpose()
.unwrap()
Some(self.floating_panes.replace_pane(pane_id, suppressed_pane)).transpose()?
} else {
self.tiled_panes.replace_pane(pane_id, suppressed_pane)
};
@ -1857,9 +1887,15 @@ impl Tab {
// the pane there we replaced. Now, we need to update its pty about its new size.
// We couldn't do that before, and we can't use the original moved item now - so we
// need to refetch it
resize_pty!(suppressed_pane, self.os_api, self.senders).unwrap();
resize_pty!(suppressed_pane, self.os_api, self.senders)?;
}
replaced_pane
Ok(replaced_pane)
})
.with_context(|| {
format!(
"failed to replace active pane with suppressed pane {:?}",
pane_id
)
})
}
pub fn close_focused_pane(&mut self, client_id: ClientId) -> Result<()> {
@ -2098,18 +2134,20 @@ impl Tab {
point: &Position,
search_selectable: bool,
) -> Result<Option<&mut Box<dyn Pane>>> {
let err_context = || format!("failed to get pane at position {point:?}");
if self.floating_panes.panes_are_visible() {
if let Some(pane_id) = self
.floating_panes
.get_pane_id_at(point, search_selectable)
.unwrap()
.with_context(err_context)?
{
return Ok(self.floating_panes.get_pane_mut(pane_id));
}
}
if let Some(pane_id) = self
.get_pane_id_at(point, search_selectable)
.with_context(|| format!("failed to get pane at position {point:?}"))?
.with_context(err_context)?
{
Ok(self.tiled_panes.get_pane_mut(pane_id))
} else {
@ -2245,7 +2283,11 @@ impl Tab {
|| format!("failed to focus pane at position {point:?} for client {client_id}");
if self.floating_panes.panes_are_visible() {
if let Some(clicked_pane) = self.floating_panes.get_pane_id_at(point, true).unwrap() {
if let Some(clicked_pane) = self
.floating_panes
.get_pane_id_at(point, true)
.with_context(err_context)?
{
self.floating_panes.focus_pane(clicked_pane, client_id);
self.set_pane_active_at(clicked_pane);
return Ok(());

View file

@ -996,7 +996,7 @@ fn move_floating_pane_focus_left() {
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.move_focus_left(client_id);
tab.move_focus_left(client_id).unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1051,8 +1051,8 @@ fn move_floating_pane_focus_right() {
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.move_focus_left(client_id);
tab.move_focus_right(client_id);
tab.move_focus_left(client_id).unwrap();
tab.move_focus_right(client_id).unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1107,7 +1107,7 @@ fn move_floating_pane_focus_up() {
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.move_focus_up(client_id);
tab.move_focus_up(client_id).unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1162,8 +1162,8 @@ fn move_floating_pane_focus_down() {
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.move_focus_up(client_id);
tab.move_focus_down(client_id);
tab.move_focus_up(client_id).unwrap();
tab.move_focus_down(client_id).unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1461,7 +1461,8 @@ fn resize_tab_with_floating_panes() {
tab.resize_whole_tab(Size {
cols: 100,
rows: 10,
});
})
.unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, _cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1511,7 +1512,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() {
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.resize_whole_tab(Size { cols: 50, rows: 10 });
tab.resize_whole_tab(Size { cols: 50, rows: 10 }).unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, _cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1561,11 +1562,12 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b
.unwrap();
tab.handle_pty_bytes(6, Vec::from("\u{1b}#8".as_bytes()))
.unwrap();
tab.resize_whole_tab(Size { cols: 50, rows: 10 });
tab.resize_whole_tab(Size { cols: 50, rows: 10 }).unwrap();
tab.resize_whole_tab(Size {
cols: 121,
rows: 20,
});
})
.unwrap();
tab.render(&mut output, None).unwrap();
let (snapshot, _cursor_coordinates) = take_snapshot_and_cursor_position(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -1833,7 +1835,7 @@ fn save_cursor_position_across_resizes() {
1,
Vec::from("\n\nI am some text\nI am another line of text\nLet's save the cursor position here \u{1b}[sI should be ovewritten".as_bytes()),
).unwrap();
tab.resize_whole_tab(Size { cols: 100, rows: 3 });
tab.resize_whole_tab(Size { cols: 100, rows: 3 }).unwrap();
tab.handle_pty_bytes(1, Vec::from("\u{1b}[uthis overwrote me!".as_bytes()))
.unwrap();
@ -2106,7 +2108,8 @@ fn resize_whole_tab_while_tiled_pane_is_suppressed() {
tab.resize_whole_tab(Size {
cols: 100,
rows: 10,
});
})
.unwrap();
tab.render(&mut output, None).unwrap();
let snapshot = take_snapshot(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -2138,7 +2141,8 @@ fn resize_whole_tab_while_floting_pane_is_suppressed() {
tab.resize_whole_tab(Size {
cols: 100,
rows: 10,
});
})
.unwrap();
tab.render(&mut output, None).unwrap();
let snapshot = take_snapshot(
output.serialize().unwrap().get(&client_id).unwrap(),
@ -2749,7 +2753,7 @@ fn move_pane_focus_sends_tty_csi_event() {
Vec::from("\u{1b}[?1004h".as_bytes()),
)
.unwrap();
tab.move_focus_left(client_id);
tab.move_focus_left(client_id).unwrap();
assert_snapshot!(format!("{:?}", *tty_stdin_bytes.lock().unwrap()));
}
@ -2792,7 +2796,7 @@ fn move_floating_pane_focus_sends_tty_csi_event() {
Vec::from("\u{1b}[?1004h".as_bytes()),
)
.unwrap();
tab.move_focus_left(client_id);
tab.move_focus_left(client_id).unwrap();
assert_snapshot!(format!("{:?}", *tty_stdin_bytes.lock().unwrap()));
}

View file

@ -995,7 +995,7 @@ pub fn close_pane_with_another_pane_below_it() {
let mut tab = create_new_tab(size);
let new_pane_id = PaneId::Terminal(2);
tab.horizontal_split(new_pane_id, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab");
@ -1120,7 +1120,7 @@ pub fn close_pane_with_another_pane_to_the_right() {
let mut tab = create_new_tab(size);
let new_pane_id = PaneId::Terminal(2);
tab.vertical_split(new_pane_id, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab");
@ -1186,9 +1186,9 @@ pub fn close_pane_with_multiple_panes_above_it() {
let new_pane_id_1 = PaneId::Terminal(2);
let new_pane_id_2 = PaneId::Terminal(3);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab");
@ -1298,7 +1298,7 @@ pub fn close_pane_with_multiple_panes_below_it() {
let new_pane_id_2 = PaneId::Terminal(3);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab");
@ -1407,9 +1407,9 @@ pub fn close_pane_with_multiple_panes_to_the_left() {
let new_pane_id_1 = PaneId::Terminal(2);
let new_pane_id_2 = PaneId::Terminal(3);
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab");
@ -1519,7 +1519,7 @@ pub fn close_pane_with_multiple_panes_to_the_right() {
let new_pane_id_2 = PaneId::Terminal(3);
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab");
@ -1634,18 +1634,18 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() {
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_left(1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(new_pane_id_4, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(new_pane_id_5, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_up(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_up(1).unwrap();
tab_resize_down(&mut tab, 1);
tab.vertical_split(new_pane_id_6, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab");
@ -1934,17 +1934,17 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() {
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_left(1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(new_pane_id_4, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(new_pane_id_5, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_up(&mut tab, 1);
tab.vertical_split(new_pane_id_6, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab");
@ -2235,20 +2235,20 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() {
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(new_pane_id_4, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(new_pane_id_5, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_left(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
tab_resize_up(&mut tab, 1);
tab_resize_up(&mut tab, 1);
tab.horizontal_split(new_pane_id_6, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab");
@ -2539,19 +2539,19 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(new_pane_id_4, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(new_pane_id_5, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_left(&mut tab, 1);
tab_resize_up(&mut tab, 1);
tab_resize_up(&mut tab, 1);
tab.horizontal_split(new_pane_id_6, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.close_focused_pane(1).unwrap();
assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab");
@ -2825,8 +2825,8 @@ pub fn move_focus_down() {
let new_pane_id = PaneId::Terminal(2);
tab.horizontal_split(new_pane_id, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_down(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_down(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -2849,8 +2849,8 @@ pub fn move_focus_down_to_the_most_recently_used_pane() {
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_down(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_down(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -2874,7 +2874,7 @@ pub fn move_focus_up() {
let new_pane_id = PaneId::Terminal(2);
tab.horizontal_split(new_pane_id, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -2895,11 +2895,11 @@ pub fn move_focus_up_to_the_most_recently_used_pane() {
let new_pane_id_3 = PaneId::Terminal(4);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_up(1);
tab.move_focus_down(1).unwrap();
tab.move_focus_up(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -2923,7 +2923,7 @@ pub fn move_focus_left() {
let new_pane_id = PaneId::Terminal(2);
tab.vertical_split(new_pane_id, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().x(),
@ -2944,11 +2944,11 @@ pub fn move_focus_left_to_the_most_recently_used_pane() {
let new_pane_id_3 = PaneId::Terminal(4);
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_left(1);
tab.move_focus_right(1).unwrap();
tab.move_focus_left(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -2972,8 +2972,8 @@ pub fn move_focus_right() {
let new_pane_id = PaneId::Terminal(2);
tab.vertical_split(new_pane_id, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_right(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_right(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().x(),
@ -2996,8 +2996,8 @@ pub fn move_focus_right_to_the_most_recently_used_pane() {
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_right(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_right(1).unwrap();
assert_eq!(
tab.get_active_pane(1).unwrap().y(),
@ -3021,7 +3021,7 @@ pub fn move_active_pane_down() {
let new_pane_id = PaneId::Terminal(2);
tab.horizontal_split(new_pane_id, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_active_pane_down(1);
assert_eq!(
@ -3050,7 +3050,7 @@ pub fn move_active_pane_down_to_the_most_recently_used_position() {
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_active_pane_down(1);
assert_eq!(
@ -3106,10 +3106,10 @@ pub fn move_active_pane_up_to_the_most_recently_used_position() {
let new_pane_id_3 = PaneId::Terminal(4);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.vertical_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.move_active_pane_up(1);
assert_eq!(
@ -3166,10 +3166,10 @@ pub fn move_active_pane_left_to_the_most_recently_used_position() {
let new_pane_id_3 = PaneId::Terminal(4);
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.move_active_pane_left(1);
assert_eq!(
@ -3200,7 +3200,7 @@ pub fn move_active_pane_right() {
let new_pane_id = PaneId::Terminal(2);
tab.vertical_split(new_pane_id, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.move_active_pane_right(1);
assert_eq!(
@ -3229,7 +3229,7 @@ pub fn move_active_pane_right_to_the_most_recently_used_position() {
tab.vertical_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.horizontal_split(new_pane_id_3, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.move_active_pane_right(1);
assert_eq!(
@ -3373,7 +3373,7 @@ pub fn resize_down_with_pane_below() {
let mut tab = create_new_tab(size);
let new_pane_id = PaneId::Terminal(2);
tab.horizontal_split(new_pane_id, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -3487,7 +3487,7 @@ pub fn resize_down_with_panes_above_and_below() {
let new_pane_id_2 = PaneId::Terminal(3);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.horizontal_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -3639,9 +3639,9 @@ pub fn resize_down_with_multiple_panes_above() {
let new_pane_id_1 = PaneId::Terminal(2);
let new_pane_id_2 = PaneId::Terminal(3);
tab.horizontal_split(new_pane_id_1, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(new_pane_id_2, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -3795,9 +3795,9 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() {
let pane_above = PaneId::Terminal(4);
tab.horizontal_split(pane_to_the_left, None, 1).unwrap();
tab.vertical_split(focused_pane, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(pane_above, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -3995,7 +3995,7 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() {
let focused_pane = PaneId::Terminal(4);
tab.horizontal_split(pane_below_and_left, None, 1).unwrap();
tab.vertical_split(pane_below, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(focused_pane, None, 1).unwrap();
tab_resize_down(&mut tab, 1);
@ -4194,10 +4194,10 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() {
let pane_above_and_right = PaneId::Terminal(4);
tab.horizontal_split(focused_pane, None, 1).unwrap();
tab.vertical_split(pane_to_the_right, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(pane_above_and_right, None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_left(1);
tab.move_focus_down(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -4395,9 +4395,9 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() {
let pane_to_the_right = PaneId::Terminal(4);
tab.horizontal_split(pane_below, None, 1).unwrap();
tab.vertical_split(pane_below_and_right, None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(pane_to_the_right, None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -4592,11 +4592,11 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() {
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_down(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_down(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -4877,10 +4877,10 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() {
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -5159,16 +5159,16 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -5533,18 +5533,18 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_up(1);
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -5907,7 +5907,7 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_down(&mut tab, 1);
assert_eq!(
@ -6190,7 +6190,7 @@ pub fn resize_left_with_pane_to_the_right() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -6296,7 +6296,7 @@ pub fn resize_left_with_panes_to_the_left_and_right() {
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -6443,9 +6443,9 @@ pub fn resize_left_with_multiple_panes_to_the_left() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -6594,9 +6594,9 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() {
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -6788,10 +6788,10 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() {
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_left(1);
tab.move_focus_down(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -6983,7 +6983,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() {
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab_resize_left(&mut tab, 1);
@ -7176,9 +7176,9 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() {
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -7373,11 +7373,11 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -7658,12 +7658,12 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_left(1);
tab.move_focus_down(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -7944,15 +7944,15 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_down(&mut tab, 1);
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -8319,16 +8319,16 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_down(&mut tab, 1);
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_left(&mut tab, 1);
assert_eq!(
@ -8833,7 +8833,7 @@ pub fn resize_right_with_pane_to_the_right() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -8939,7 +8939,7 @@ pub fn resize_right_with_panes_to_the_left_and_right() {
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -9087,9 +9087,9 @@ pub fn resize_right_with_multiple_panes_to_the_left() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -9237,9 +9237,9 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap();
tab_resize_right(&mut tab, 1);
@ -9430,11 +9430,11 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -9625,11 +9625,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -9820,12 +9820,12 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_left(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -10020,11 +10020,11 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -10304,12 +10304,12 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_left(1);
tab.move_focus_down(1).unwrap();
tab.move_focus_left(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -10589,15 +10589,15 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_up(&mut tab, 1);
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -10963,16 +10963,16 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_up(&mut tab, 1);
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_right(&mut tab, 1);
assert_eq!(
@ -11524,7 +11524,7 @@ pub fn resize_up_with_pane_below() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -11634,7 +11634,7 @@ pub fn resize_up_with_panes_above_and_below() {
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -11782,9 +11782,9 @@ pub fn resize_up_with_multiple_panes_above() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -11931,9 +11931,9 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab_resize_up(&mut tab, 1);
@ -12126,11 +12126,11 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -12322,11 +12322,11 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -12518,12 +12518,12 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() {
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_up(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_up(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -12717,10 +12717,10 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() {
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -13000,11 +13000,11 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() {
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_up(1);
tab.move_focus_left(1).unwrap();
tab.move_focus_up(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -13282,16 +13282,16 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -13655,17 +13655,17 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri
};
let mut tab = create_new_tab(size);
tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_up(1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap();
tab.move_focus_down(1);
tab.move_focus_down(1).unwrap();
tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap();
tab.move_focus_up(1);
tab.move_focus_left(1);
tab.move_focus_up(1).unwrap();
tab.move_focus_left(1).unwrap();
tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_up(&mut tab, 1);
assert_eq!(
@ -14118,9 +14118,9 @@ pub fn nondirectional_resize_increase_with_2_panes_to_left() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_right(1);
tab.move_focus_right(1).unwrap();
tab_resize_increase(&mut tab, 1);
// should behave like `resize_left_with_multiple_panes_to_the_left`
@ -14176,7 +14176,7 @@ pub fn nondirectional_resize_increase_with_1_pane_to_right_1_pane_above() {
};
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap();
tab_resize_increase(&mut tab, 1);
@ -14233,7 +14233,7 @@ pub fn nondirectional_resize_increase_with_1_pane_to_right_1_pane_to_left() {
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_increase(&mut tab, 1);
assert_eq!(
@ -14289,7 +14289,7 @@ pub fn nondirectional_resize_increase_with_pane_above_aligned_right_with_current
let mut tab = create_new_tab(size);
tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap();
tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap();
tab.move_focus_left(1);
tab.move_focus_left(1).unwrap();
tab_resize_increase(&mut tab, 1);
assert_eq!(