From 14783c2b2c3bcd3b4b01e72c46d6af3ecbdd203c Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Tue, 9 Feb 2021 17:36:37 +0100 Subject: [PATCH] feat(ui): new keybindings and status bar (#160) * work * feat(statusbar): new design and keybindings * fix(ipc): add missing const * style(fmt): rustfmt * style(input): remove accidental comment --- assets/layouts/default.yaml | 2 +- assets/plugins/status-bar.wasm | Bin 479232 -> 509798 bytes src/client/boundaries.rs | 517 +++++++++++++++--- src/client/panes/plugin_pane.rs | 8 + src/client/panes/terminal_pane.rs | 3 + src/client/tab.rs | 15 + src/common/errors.rs | 2 + src/common/input/actions.rs | 1 + src/common/input/handler.rs | 124 +++-- src/common/input/keybinds.rs | 132 +++-- src/common/mod.rs | 20 +- src/common/screen.rs | 1 + src/common/wasm_vm.rs | 16 +- src/tests/integration/basic.rs | 75 ++- src/tests/integration/close_pane.rs | 298 ++++++---- src/tests/integration/move_focus_down.rs | 21 +- src/tests/integration/move_focus_left.rs | 21 +- src/tests/integration/move_focus_right.rs | 21 +- src/tests/integration/move_focus_up.rs | 21 +- src/tests/integration/resize_down.rs | 321 +++++++---- src/tests/integration/resize_left.rs | 320 +++++++---- src/tests/integration/resize_right.rs | 321 +++++++---- src/tests/integration/resize_up.rs | 320 +++++++---- ...the_tab_that_has_a_pane_in_fullscreen.snap | 20 +- src/tests/integration/tabs.rs | 130 +++-- src/tests/integration/toggle_fullscreen.rs | 18 +- src/tests/utils.rs | 75 ++- 27 files changed, 1907 insertions(+), 916 deletions(-) diff --git a/assets/layouts/default.yaml b/assets/layouts/default.yaml index e63356917..a3987e50b 100644 --- a/assets/layouts/default.yaml +++ b/assets/layouts/default.yaml @@ -5,4 +5,4 @@ parts: - direction: Vertical split_size: Fixed: 1 - plugin: status-bar \ No newline at end of file + plugin: status-bar diff --git a/assets/plugins/status-bar.wasm b/assets/plugins/status-bar.wasm index 97b9be0cec015383f155c1ec6f6000e55b6c21ce..646ad3b5b30030d148cd8fb046900fed25aa3ac9 100644 GIT binary patch delta 144260 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஛z!Q*7jZy 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

Q!ojx0o|aVtKrXKU*oV(ck~;bnD}g{2HHxc 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 NrtEa}z%cu~{|D6JRUZHV delta 116892 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 z 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 diff --git a/src/client/boundaries.rs b/src/client/boundaries.rs index 498a37318..67733c12b 100644 --- a/src/client/boundaries.rs +++ b/src/client/boundaries.rs @@ -1,6 +1,8 @@ use crate::tab::Pane; use std::collections::HashMap; +use std::fmt::{Display, Error, Formatter}; + pub mod boundary_type { pub const TOP_RIGHT: &str = "┐"; pub const VERTICAL: &str = "│"; @@ -17,277 +19,579 @@ pub mod boundary_type { pub type BoundaryType = &'static str; // easy way to refer to boundary_type above -fn combine_symbols(current_symbol: &str, next_symbol: &str) -> Option<&'static str> { +#[derive(Clone, Copy, Debug)] +pub struct BoundarySymbol { + boundary_type: BoundaryType, + invisible: bool, +} + +impl BoundarySymbol { + pub fn new(boundary_type: BoundaryType) -> Self { + BoundarySymbol { + boundary_type, + invisible: false, + } + } + pub fn invisible(mut self) -> Self { + self.invisible = true; + self + } +} + +impl Display for BoundarySymbol { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + if self.invisible { + write!(f, " ") + } else { + write!(f, "{}", self.boundary_type) + } + } +} + +fn combine_symbols( + current_symbol: BoundarySymbol, + next_symbol: BoundarySymbol, +) -> Option { + let invisible = current_symbol.invisible || next_symbol.invisible; + let current_symbol = current_symbol.boundary_type; + let next_symbol = next_symbol.boundary_type; match (current_symbol, next_symbol) { (boundary_type::TOP_RIGHT, boundary_type::TOP_RIGHT) => { // (┐, ┐) => Some(┐) - Some(boundary_type::TOP_RIGHT) + let boundary_type = boundary_type::TOP_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::VERTICAL) => { // (┐, │) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL) => { // (┐, ─) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::TOP_LEFT) => { // (┐, ┌) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::BOTTOM_RIGHT) => { // (┐, ┘) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::BOTTOM_LEFT) => { // (┐, └) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::VERTICAL_LEFT) => { // (┐, ┤) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::VERTICAL_RIGHT) => { // (┐, ├) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_DOWN) => { // (┐, ┬) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_UP) => { // (┐, ┴) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_RIGHT, boundary_type::CROSS) => { // (┐, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL) => { // (─, ─) => Some(─) - Some(boundary_type::HORIZONTAL) + let boundary_type = boundary_type::HORIZONTAL; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::VERTICAL) => { // (─, │) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::TOP_LEFT) => { // (─, ┌) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::BOTTOM_RIGHT) => { // (─, ┘) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::BOTTOM_LEFT) => { // (─, └) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::VERTICAL_LEFT) => { // (─, ┤) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::VERTICAL_RIGHT) => { // (─, ├) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_DOWN) => { // (─, ┬) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_UP) => { // (─, ┴) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL, boundary_type::CROSS) => { // (─, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::VERTICAL) => { // (│, │) => Some(│) - Some(boundary_type::VERTICAL) + let boundary_type = boundary_type::VERTICAL; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::TOP_LEFT) => { // (│, ┌) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::BOTTOM_RIGHT) => { // (│, ┘) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::BOTTOM_LEFT) => { // (│, └) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::VERTICAL_LEFT) => { // (│, ┤) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::VERTICAL_RIGHT) => { // (│, ├) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::HORIZONTAL_DOWN) => { // (│, ┬) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::HORIZONTAL_UP) => { // (│, ┴) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL, boundary_type::CROSS) => { // (│, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::TOP_LEFT) => { // (┌, ┌) => Some(┌) - Some(boundary_type::TOP_LEFT) + let boundary_type = boundary_type::TOP_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::BOTTOM_RIGHT) => { // (┌, ┘) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::BOTTOM_LEFT) => { // (┌, └) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::VERTICAL_LEFT) => { // (┌, ┤) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::VERTICAL_RIGHT) => { // (┌, ├) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_DOWN) => { // (┌, ┬) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_UP) => { // (┌, ┴) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::TOP_LEFT, boundary_type::CROSS) => { // (┌, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_RIGHT) => { // (┘, ┘) => Some(┘) - Some(boundary_type::BOTTOM_RIGHT) + let boundary_type = boundary_type::BOTTOM_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_LEFT) => { // (┘, └) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_LEFT) => { // (┘, ┤) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_RIGHT) => { // (┘, ├) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_DOWN) => { // (┘, ┬) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_UP) => { // (┘, ┴) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_RIGHT, boundary_type::CROSS) => { // (┘, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::BOTTOM_LEFT) => { // (└, └) => Some(└) - Some(boundary_type::BOTTOM_LEFT) + let boundary_type = boundary_type::BOTTOM_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_LEFT) => { // (└, ┤) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_RIGHT) => { // (└, ├) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_DOWN) => { // (└, ┬) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_UP) => { // (└, ┴) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::BOTTOM_LEFT, boundary_type::CROSS) => { // (└, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_LEFT) => { // (┤, ┤) => Some(┤) - Some(boundary_type::VERTICAL_LEFT) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_RIGHT) => { // (┤, ├) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_DOWN) => { // (┤, ┬) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_UP) => { // (┤, ┴) => Some(┼) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_LEFT, boundary_type::CROSS) => { // (┤, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_RIGHT, boundary_type::VERTICAL_RIGHT) => { // (├, ├) => Some(├) - Some(boundary_type::VERTICAL_RIGHT) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_DOWN) => { // (├, ┬) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_UP) => { // (├, ┴) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::VERTICAL_RIGHT, boundary_type::CROSS) => { // (├, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_DOWN) => { // (┬, ┬) => Some(┬) - Some(boundary_type::HORIZONTAL_DOWN) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_UP) => { // (┬, ┴) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL_DOWN, boundary_type::CROSS) => { // (┬, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL_UP, boundary_type::HORIZONTAL_UP) => { // (┴, ┴) => Some(┴) - Some(boundary_type::HORIZONTAL_UP) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::HORIZONTAL_UP, boundary_type::CROSS) => { // (┴, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (boundary_type::CROSS, boundary_type::CROSS) => { // (┼, ┼) => Some(┼) - Some(boundary_type::CROSS) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) } (_, _) => None, } } -fn find_next_symbol(first_symbol: &str, second_symbol: &str) -> Option<&'static str> { +fn find_next_symbol( + first_symbol: BoundarySymbol, + second_symbol: BoundarySymbol, +) -> Option { if let Some(symbol) = combine_symbols(first_symbol, second_symbol) { Some(symbol) } else { @@ -359,7 +663,8 @@ pub trait Rect { pub struct Boundaries { columns: usize, rows: usize, - boundary_characters: HashMap, + // boundary_characters: HashMap, + boundary_characters: HashMap, } impl Boundaries { @@ -373,6 +678,54 @@ impl Boundaries { } } pub fn add_rect(&mut self, rect: &dyn Pane) { + if rect.x() > 0 { + let boundary_x_coords = rect.x() - 1; + let first_row_coordinates = self.rect_right_boundary_row_start(rect); + let last_row_coordinates = self.rect_right_boundary_row_end(rect); + for row in first_row_coordinates..last_row_coordinates { + let coordinates = Coordinates::new(boundary_x_coords, row); + let mut symbol_to_add = if row == first_row_coordinates && row != 0 { + BoundarySymbol::new(boundary_type::TOP_LEFT) + } else if row == last_row_coordinates - 1 && row != self.rows - 1 { + BoundarySymbol::new(boundary_type::BOTTOM_LEFT) + } else { + BoundarySymbol::new(boundary_type::VERTICAL) + }; + if rect.invisible_borders() { + symbol_to_add = symbol_to_add.invisible(); + } + let next_symbol = self + .boundary_characters + .remove(&coordinates) + .and_then(|current_symbol| find_next_symbol(current_symbol, symbol_to_add)) + .unwrap_or(symbol_to_add); + self.boundary_characters.insert(coordinates, next_symbol); + } + } + if rect.y() > 0 { + let boundary_y_coords = rect.y() - 1; + let first_col_coordinates = self.rect_bottom_boundary_col_start(rect); + let last_col_coordinates = self.rect_bottom_boundary_col_end(rect); + for col in first_col_coordinates..last_col_coordinates { + let coordinates = Coordinates::new(col, boundary_y_coords); + let mut symbol_to_add = if col == first_col_coordinates && col != 0 { + BoundarySymbol::new(boundary_type::TOP_LEFT) + } else if col == last_col_coordinates - 1 && col != self.columns - 1 { + BoundarySymbol::new(boundary_type::TOP_RIGHT) + } else { + BoundarySymbol::new(boundary_type::HORIZONTAL) + }; + if rect.invisible_borders() { + symbol_to_add = symbol_to_add.invisible(); + } + let next_symbol = self + .boundary_characters + .remove(&coordinates) + .and_then(|current_symbol| find_next_symbol(current_symbol, symbol_to_add)) + .unwrap_or(symbol_to_add); + self.boundary_characters.insert(coordinates, next_symbol); + } + } if self.rect_right_boundary_is_before_screen_edge(rect) { // let boundary_x_coords = self.rect_right_boundary_x_coords(rect); let boundary_x_coords = rect.right_boundary_x_coords(); @@ -380,16 +733,19 @@ impl Boundaries { let last_row_coordinates = self.rect_right_boundary_row_end(rect); for row in first_row_coordinates..last_row_coordinates { let coordinates = Coordinates::new(boundary_x_coords, row); - let symbol_to_add = if row == first_row_coordinates && row != 0 { - boundary_type::TOP_RIGHT + let mut symbol_to_add = if row == first_row_coordinates && row != 0 { + BoundarySymbol::new(boundary_type::TOP_RIGHT) } else if row == last_row_coordinates - 1 && row != self.rows - 1 { - boundary_type::BOTTOM_RIGHT + BoundarySymbol::new(boundary_type::BOTTOM_RIGHT) } else { - boundary_type::VERTICAL + BoundarySymbol::new(boundary_type::VERTICAL) }; + if rect.invisible_borders() { + symbol_to_add = symbol_to_add.invisible(); + } let next_symbol = self .boundary_characters - .get(&coordinates) + .remove(&coordinates) .and_then(|current_symbol| find_next_symbol(current_symbol, symbol_to_add)) .unwrap_or(symbol_to_add); self.boundary_characters.insert(coordinates, next_symbol); @@ -401,16 +757,19 @@ impl Boundaries { let last_col_coordinates = self.rect_bottom_boundary_col_end(rect); for col in first_col_coordinates..last_col_coordinates { let coordinates = Coordinates::new(col, boundary_y_coords); - let symbol_to_add = if col == first_col_coordinates && col != 0 { - boundary_type::BOTTOM_LEFT + let mut symbol_to_add = if col == first_col_coordinates && col != 0 { + BoundarySymbol::new(boundary_type::BOTTOM_LEFT) } else if col == last_col_coordinates - 1 && col != self.columns - 1 { - boundary_type::BOTTOM_RIGHT + BoundarySymbol::new(boundary_type::BOTTOM_RIGHT) } else { - boundary_type::HORIZONTAL + BoundarySymbol::new(boundary_type::HORIZONTAL) }; + if rect.invisible_borders() { + symbol_to_add = symbol_to_add.invisible(); + } let next_symbol = self .boundary_characters - .get(&coordinates) + .remove(&coordinates) .and_then(|current_symbol| find_next_symbol(current_symbol, symbol_to_add)) .unwrap_or(symbol_to_add); self.boundary_characters.insert(coordinates, next_symbol); diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs index ff173d187..588cffd63 100644 --- a/src/client/panes/plugin_pane.rs +++ b/src/client/panes/plugin_pane.rs @@ -10,6 +10,7 @@ pub struct PluginPane { pub pid: u32, pub should_render: bool, pub selectable: bool, + pub invisible_borders: bool, pub position_and_size: PositionAndSize, pub position_and_size_override: Option, pub send_plugin_instructions: SenderWithContext, @@ -26,6 +27,7 @@ impl PluginPane { pid, should_render: true, selectable: true, + invisible_borders: false, position_and_size, position_and_size_override: None, send_plugin_instructions, @@ -102,6 +104,9 @@ impl Pane for PluginPane { fn set_selectable(&mut self, selectable: bool) { self.selectable = selectable; } + fn set_invisible_borders(&mut self, invisible_borders: bool) { + self.invisible_borders = invisible_borders; + } fn set_max_height(&mut self, max_height: usize) { self.max_height = Some(max_height); } @@ -180,4 +185,7 @@ impl Pane for PluginPane { fn max_height(&self) -> Option { self.max_height } + fn invisible_borders(&self) -> bool { + self.invisible_borders + } } diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index fe7fb5850..21244fab1 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -181,6 +181,9 @@ impl Pane for TerminalPane { fn set_max_height(&mut self, max_height: usize) { self.max_height = Some(max_height); } + fn set_invisible_borders(&mut self, _invisible_borders: bool) { + unimplemented!(); + } fn max_height(&self) -> Option { self.max_height } diff --git a/src/client/tab.rs b/src/client/tab.rs index 3b49a1c4a..b7f0e5c2f 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -11,6 +11,8 @@ use std::{ }; use std::{io::Write, sync::mpsc::channel}; +use crate::utils::logging::debug_log_to_file; + /* * Tab * @@ -86,6 +88,7 @@ pub trait Pane { fn set_should_render(&mut self, should_render: bool); fn selectable(&self) -> bool; fn set_selectable(&mut self, selectable: bool); + fn set_invisible_borders(&mut self, invisible_borders: bool); fn set_max_height(&mut self, max_height: usize); fn render(&mut self) -> Option; fn pid(&self) -> PaneId; @@ -155,6 +158,9 @@ pub trait Pane { fn max_height(&self) -> Option { None } + fn invisible_borders(&self) -> bool { + false + } } impl Tab { @@ -1895,6 +1901,15 @@ impl Tab { } } } + pub fn set_pane_invisible_borders(&mut self, id: PaneId, invisible_borders: bool) { + debug_log_to_file(format!( + "set_pane_invisible_borders: {:?}", + invisible_borders + )); + if let Some(pane) = self.panes.get_mut(&id) { + pane.set_invisible_borders(invisible_borders); + } + } pub fn set_pane_max_height(&mut self, id: PaneId, max_height: usize) { if let Some(pane) = self.panes.get_mut(&id) { pane.set_max_height(max_height); diff --git a/src/common/errors.rs b/src/common/errors.rs index 90ca6f9ec..27fe31039 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -167,6 +167,7 @@ pub enum ScreenContext { CloseFocusedPane, ToggleActiveTerminalFullscreen, SetSelectable, + SetInvisibleBorders, SetMaxHeight, ClosePane, ApplyLayout, @@ -203,6 +204,7 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenContext::ToggleActiveTerminalFullscreen } ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable, + ScreenInstruction::SetInvisibleBorders(..) => ScreenContext::SetInvisibleBorders, ScreenInstruction::SetMaxHeight(..) => ScreenContext::SetMaxHeight, ScreenInstruction::ClosePane(_) => ScreenContext::ClosePane, ScreenInstruction::ApplyLayout(_) => ScreenContext::ApplyLayout, diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs index be7bcdb9d..6f4a4521c 100644 --- a/src/common/input/actions.rs +++ b/src/common/input/actions.rs @@ -18,6 +18,7 @@ pub enum Action { Write(Vec), /// Switch to the specified input mode SwitchToMode(handler::InputMode), + TogglePersistentMode, /// Resize focus pane in specified direction Resize(Direction), /// Switch focus to next pane in specified direction diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index b10e9df36..2a1c2c729 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -9,6 +9,7 @@ use crate::screen::ScreenInstruction; use crate::wasm_vm::PluginInstruction; use crate::CommandIsExecuting; +use serde::{Deserialize, Serialize}; use strum_macros::EnumIter; use termion::input::TermReadEventsAndRaw; @@ -16,6 +17,7 @@ use super::keybinds::key_to_action; struct InputHandler { mode: InputMode, + mode_is_persistent: bool, os_input: Box, command_is_executing: CommandIsExecuting, send_screen_instructions: SenderWithContext, @@ -35,6 +37,7 @@ impl InputHandler { ) -> Self { InputHandler { mode: InputMode::Normal, + mode_is_persistent: false, os_input, command_is_executing, send_screen_instructions, @@ -68,12 +71,13 @@ impl InputHandler { &key, raw_bytes, &self.mode, &keybinds, )); //@@@ This is a hack until we dispatch more than one action per key stroke - if entry_mode == InputMode::Command - && self.mode == InputMode::Command - { + if entry_mode == self.mode && !self.mode_is_persistent { self.mode = InputMode::Normal; update_state(&self.send_app_instructions, |_| AppState { - input_mode: self.mode, + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, }); } if should_break { @@ -113,13 +117,28 @@ impl InputHandler { } Action::SwitchToMode(mode) => { self.mode = mode; + if mode == InputMode::Normal { + self.mode_is_persistent = false; + } update_state(&self.send_app_instructions, |_| AppState { - input_mode: self.mode, + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, }); self.send_screen_instructions .send(ScreenInstruction::Render) .unwrap(); } + Action::TogglePersistentMode => { + self.mode_is_persistent = !self.mode_is_persistent; + update_state(&self.send_app_instructions, |_| AppState { + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, + }); + } Action::Resize(direction) => { let screen_instr = match direction { super::actions::Direction::Left => ScreenInstruction::ResizeLeft, @@ -224,6 +243,21 @@ impl InputHandler { } } +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)] +pub struct InputState { + mode: InputMode, + persistent: bool, +} + +impl Default for InputState { + fn default() -> InputState { + InputState { + mode: InputMode::Normal, + persistent: false, + } + } +} + /// Dictates whether we're in command mode, persistent command mode, normal mode or exiting: /// - Normal mode either writes characters to the terminal, or switches to command mode /// using a particular key control @@ -231,41 +265,65 @@ impl InputHandler { /// back to normal mode /// - Persistent command mode is the same as command mode, but doesn't return automatically to /// normal mode -#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter)] +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter, Serialize, Deserialize)] pub enum InputMode { Normal, Command, - CommandPersistent, + Resize, + Pane, + Tab, + Scroll, Exiting, } -// FIXME: This should be auto-generated from the soon-to-be-added `get_default_keybinds` -pub fn get_help(mode: &InputMode) -> Vec { - let command_help = vec![ - " Split".into(), - " Resize".into(), - "

Focus Next".into(), - " Close Pane".into(), - " Quit".into(), - " Scroll".into(), - "<1> New Tab".into(), - "<2/3> Move Tab".into(), - "<4> Close Tab".into(), - ]; - match mode { - InputMode::Normal => vec![" Command Mode".into()], - InputMode::Command => [ - vec![ - " Persistent Mode".into(), - " Normal Mode".into(), - ], - command_help, - ] - .concat(), - InputMode::CommandPersistent => { - [vec![" Normal Mode".into()], command_help].concat() +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct Help { + pub mode: InputMode, + pub mode_is_persistent: bool, + pub keybinds: Vec<(String, String)>, // => +} + +impl Default for InputMode { + fn default() -> InputMode { + InputMode::Normal + } +} + +pub fn get_help(input_state: &InputState) -> Help { + let mut keybinds: Vec<(String, String)> = vec![]; + match input_state.mode { + InputMode::Normal | InputMode::Command | InputMode::Exiting => { + keybinds.push((format!("p"), format!("Pane mode"))); + keybinds.push((format!("t"), format!("Tab mode"))); + keybinds.push((format!("r"), format!("Resize mode"))); } - InputMode::Exiting => vec!["Bye from Mosaic!".into()], + InputMode::Resize => { + keybinds.push((format!("←↓↑→"), format!("resize pane"))); + } + InputMode::Pane => { + keybinds.push((format!("←↓↑→"), format!("move focus"))); + keybinds.push((format!("p"), format!("next pane"))); + keybinds.push((format!("n"), format!("new pane"))); + keybinds.push((format!("d"), format!("down split"))); + keybinds.push((format!("r"), format!("right split"))); + keybinds.push((format!("x"), format!("exit pane"))); + keybinds.push((format!("f"), format!("fullscreen pane"))); + } + InputMode::Tab => { + keybinds.push((format!("←↓↑→"), format!("move tab focus"))); + keybinds.push((format!("n"), format!("new tab"))); + keybinds.push((format!("x"), format!("exit tab"))); + } + InputMode::Scroll => { + keybinds.push((format!("↓↑"), format!("scroll up/down"))); + } + } + keybinds.push((format!("ESC"), format!("Back"))); + keybinds.push((format!("q"), format!("Quit"))); + Help { + mode: input_state.mode, + mode_is_persistent: input_state.persistent, + keybinds, } } diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs index c8a87d51c..d6ace68d0 100644 --- a/src/common/input/keybinds.rs +++ b/src/common/input/keybinds.rs @@ -28,57 +28,101 @@ fn get_defaults_for_mode(mode: &InputMode) -> Result { match *mode { InputMode::Normal => { - // Ctrl+G -> Command Mode defaults.insert(Key::Ctrl('g'), Action::SwitchToMode(InputMode::Command)); } - command_mode @ InputMode::Command | command_mode @ InputMode::CommandPersistent => { - match command_mode { - InputMode::Command => { - // Ctrl+G -> Command Mode (Persistent) - defaults.insert( - Key::Ctrl('g'), - Action::SwitchToMode(InputMode::CommandPersistent), - ); - } - InputMode::CommandPersistent => { - // Ctrl+G -> Command Mode (Persistent) - defaults.insert(Key::Ctrl('g'), Action::SwitchToMode(InputMode::Normal)); - } - _ => unreachable!(), - } - // Esc -> Normal Mode + InputMode::Command => { + defaults.insert(Key::Char('r'), Action::SwitchToMode(InputMode::Resize)); + defaults.insert(Key::Char('p'), Action::SwitchToMode(InputMode::Pane)); + defaults.insert(Key::Char('t'), Action::SwitchToMode(InputMode::Tab)); + defaults.insert(Key::Char('s'), Action::SwitchToMode(InputMode::Scroll)); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); - // Resize commands + defaults.insert(Key::Char('q'), Action::Quit); + } + InputMode::Resize => { + defaults.insert(Key::Char('h'), Action::Resize(Direction::Left)); defaults.insert(Key::Char('j'), Action::Resize(Direction::Down)); defaults.insert(Key::Char('k'), Action::Resize(Direction::Up)); - defaults.insert(Key::Char('h'), Action::Resize(Direction::Left)); defaults.insert(Key::Char('l'), Action::Resize(Direction::Right)); - // Move pane commands - defaults.insert(Key::Char('u'), Action::MoveFocus(Direction::Down)); - defaults.insert(Key::Char('i'), Action::MoveFocus(Direction::Up)); - defaults.insert(Key::Char('y'), Action::MoveFocus(Direction::Left)); - defaults.insert(Key::Char('o'), Action::MoveFocus(Direction::Right)); - // Switch focus - // @@@ Currently just tab through panes - use right for this - defaults.insert(Key::Char('p'), Action::SwitchFocus(Direction::Right)); - // Scroll - defaults.insert(Key::PageUp, Action::ScrollUp); - defaults.insert(Key::PageDown, Action::ScrollDown); - // Tab controls - defaults.insert(Key::Char('1'), Action::NewTab); - defaults.insert(Key::Char('2'), Action::GoToNextTab); - defaults.insert(Key::Char('3'), Action::GoToPreviousTab); - defaults.insert(Key::Char('4'), Action::CloseTab); - // New pane - defaults.insert(Key::Char('z'), Action::NewPane(None)); - defaults.insert(Key::Char('b'), Action::NewPane(Some(Direction::Down))); - defaults.insert(Key::Char('n'), Action::NewPane(Some(Direction::Right))); - // Toggle focus fullscreen - defaults.insert(Key::Char('e'), Action::ToggleFocusFullscreen); - // Close pane - defaults.insert(Key::Char('x'), Action::CloseFocus); - // Close Mosaic + + defaults.insert(Key::Left, Action::Resize(Direction::Left)); + defaults.insert(Key::Down, Action::Resize(Direction::Down)); + defaults.insert(Key::Up, Action::Resize(Direction::Up)); + defaults.insert(Key::Right, Action::Resize(Direction::Right)); + + defaults.insert(Key::Ctrl('b'), Action::Resize(Direction::Left)); + defaults.insert(Key::Ctrl('n'), Action::Resize(Direction::Down)); + defaults.insert(Key::Ctrl('p'), Action::Resize(Direction::Up)); + defaults.insert(Key::Ctrl('f'), Action::Resize(Direction::Right)); + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Pane => { + defaults.insert(Key::Char('h'), Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Char('j'), Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Char('k'), Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Char('l'), Action::MoveFocus(Direction::Right)); + + defaults.insert(Key::Left, Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Down, Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Up, Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Right, Action::MoveFocus(Direction::Right)); + + defaults.insert(Key::Ctrl('b'), Action::MoveFocus(Direction::Left)); + defaults.insert(Key::Ctrl('n'), Action::MoveFocus(Direction::Down)); + defaults.insert(Key::Ctrl('p'), Action::MoveFocus(Direction::Up)); + defaults.insert(Key::Ctrl('f'), Action::MoveFocus(Direction::Right)); + + defaults.insert(Key::Char('p'), Action::SwitchFocus(Direction::Right)); + defaults.insert(Key::Char('n'), Action::NewPane(None)); + defaults.insert(Key::Char('d'), Action::NewPane(Some(Direction::Down))); + defaults.insert(Key::Char('r'), Action::NewPane(Some(Direction::Right))); + defaults.insert(Key::Char('x'), Action::CloseFocus); + + defaults.insert(Key::Char('f'), Action::ToggleFocusFullscreen); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Tab => { + defaults.insert(Key::Char('h'), Action::GoToPreviousTab); + defaults.insert(Key::Char('j'), Action::GoToNextTab); + defaults.insert(Key::Char('k'), Action::GoToPreviousTab); + defaults.insert(Key::Char('l'), Action::GoToNextTab); + + defaults.insert(Key::Left, Action::GoToPreviousTab); + defaults.insert(Key::Down, Action::GoToNextTab); + defaults.insert(Key::Up, Action::GoToPreviousTab); + defaults.insert(Key::Right, Action::GoToNextTab); + + defaults.insert(Key::Ctrl('b'), Action::GoToPreviousTab); + defaults.insert(Key::Ctrl('n'), Action::GoToNextTab); + defaults.insert(Key::Ctrl('p'), Action::GoToPreviousTab); + defaults.insert(Key::Ctrl('f'), Action::GoToNextTab); + + defaults.insert(Key::Char('n'), Action::NewTab); + defaults.insert(Key::Char('x'), Action::CloseTab); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); + } + InputMode::Scroll => { + defaults.insert(Key::Char('j'), Action::ScrollDown); + defaults.insert(Key::Char('k'), Action::ScrollUp); + + defaults.insert(Key::Down, Action::ScrollDown); + defaults.insert(Key::Up, Action::ScrollUp); + + defaults.insert(Key::Ctrl('n'), Action::ScrollDown); + defaults.insert(Key::Ctrl('p'), Action::ScrollUp); + + defaults.insert(Key::Char('q'), Action::Quit); + defaults.insert(Key::Ctrl('g'), Action::TogglePersistentMode); + defaults.insert(Key::Esc, Action::SwitchToMode(InputMode::Normal)); } InputMode::Exiting => {} } diff --git a/src/common/mod.rs b/src/common/mod.rs index ab4b84e24..de0b9f763 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -17,7 +17,7 @@ use std::{collections::HashMap, fs}; use crate::panes::PaneId; use directories_next::ProjectDirs; -use input::handler::InputMode; +use input::handler::InputState; use serde::{Deserialize, Serialize}; use termion::input::TermRead; use wasm_vm::PluginEnv; @@ -43,18 +43,11 @@ pub enum ApiCommand { MoveFocus, } // FIXME: It would be good to add some more things to this over time -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct AppState { - pub input_mode: InputMode, + pub input_state: InputState, } -impl Default for AppState { - fn default() -> Self { - Self { - input_mode: InputMode::Normal, - } - } -} // FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted // from self instead of being explicitly passed here pub fn update_state( @@ -362,6 +355,13 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .unwrap() .set_pane_max_height(id, max_height); } + ScreenInstruction::SetInvisibleBorders(id, invisible_borders) => { + screen + .get_active_tab_mut() + .unwrap() + .set_pane_invisible_borders(id, invisible_borders); + screen.render(); + } ScreenInstruction::ClosePane(id) => { screen.get_active_tab_mut().unwrap().close_pane(id); screen.render(); diff --git a/src/common/screen.rs b/src/common/screen.rs index 69595c075..6ae89ddc4 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -44,6 +44,7 @@ pub enum ScreenInstruction { ToggleActiveTerminalFullscreen, SetSelectable(PaneId, bool), SetMaxHeight(PaneId, usize), + SetInvisibleBorders(PaneId, bool), ClosePane(PaneId), ApplyLayout((Layout, Vec)), NewTab(RawFd), diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index 9f04488f8..758d5e8a3 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -5,6 +5,8 @@ use std::{ use wasmer::{imports, Function, ImportObject, Store, WasmerEnv}; use wasmer_wasi::WasiEnv; +use crate::utils::logging::debug_log_to_file; + use super::{ input::handler::get_help, pty_bus::PtyInstruction, screen::ScreenInstruction, AppInstruction, PaneId, SenderWithContext, @@ -35,6 +37,7 @@ pub fn mosaic_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject { imports! { "mosaic" => { "host_open_file" => Function::new_native_with_env(store, plugin_env.clone(), host_open_file), + "host_set_invisible_borders" => Function::new_native_with_env(store, plugin_env.clone(), host_set_invisible_borders), "host_set_max_height" => Function::new_native_with_env(store, plugin_env.clone(), host_set_max_height), "host_set_selectable" => Function::new_native_with_env(store, plugin_env.clone(), host_set_selectable), "host_get_help" => Function::new_native_with_env(store, plugin_env.clone(), host_get_help), @@ -74,6 +77,17 @@ fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { .unwrap() } +fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) { + let invisible_borders = invisible_borders != 0; + plugin_env + .send_screen_instructions + .send(ScreenInstruction::SetInvisibleBorders( + PaneId::Plugin(plugin_env.plugin_id), + invisible_borders, + )) + .unwrap() +} + fn host_get_help(plugin_env: &PluginEnv) { let (state_tx, state_rx) = channel(); // FIXME: If I changed the application so that threads were sent the termination @@ -84,7 +98,7 @@ fn host_get_help(plugin_env: &PluginEnv) { .try_send(AppInstruction::GetState(state_tx)) .is_ok() { - let help = get_help(&state_rx.recv().unwrap().input_mode); + let help = get_help(&state_rx.recv().unwrap().input_state); wasi_write_string(&plugin_env.wasi_env, &serde_json::to_string(&help).unwrap()); } } diff --git a/src/tests/integration/basic.rs b/src/tests/integration/basic.rs index a48871a1c..226b08f39 100644 --- a/src/tests/integration/basic.rs +++ b/src/tests/integration/basic.rs @@ -3,8 +3,9 @@ use ::insta::assert_snapshot; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, QUIT, SCROLL_DOWN, SCROLL_UP, SPAWN_TERMINAL, SPLIT_HORIZONTALLY, - SPLIT_VERTICALLY, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, + COMMAND_TOGGLE, ESC, PANE_MODE, QUIT, SCROLL_DOWN_IN_SCROLL_MODE, SCROLL_MODE, + SCROLL_UP_IN_SCROLL_MODE, SPAWN_TERMINAL_IN_PANE_MODE, SPLIT_DOWN_IN_PANE_MODE, + SPLIT_RIGHT_IN_PANE_MODE, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, }; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; use crate::{start, CliArgs}; @@ -47,7 +48,8 @@ pub fn split_terminals_vertically() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -74,7 +76,8 @@ pub fn split_terminals_horizontally() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -102,9 +105,10 @@ pub fn split_largest_terminal() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, + &PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -131,7 +135,8 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -158,7 +163,8 @@ pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -185,7 +191,8 @@ pub fn cannot_split_largest_terminal_when_there_is_no_room() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPAWN_TERMINAL, + &PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -212,10 +219,15 @@ pub fn scrolling_up_inside_a_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SCROLL_UP, - &SCROLL_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &SCROLL_MODE, + &SCROLL_UP_IN_SCROLL_MODE, + &SCROLL_UP_IN_SCROLL_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -242,12 +254,17 @@ pub fn scrolling_down_inside_a_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SCROLL_UP, - &SCROLL_UP, - &SCROLL_DOWN, - &SCROLL_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &SCROLL_MODE, + &SCROLL_UP_IN_SCROLL_MODE, + &SCROLL_UP_IN_SCROLL_MODE, + &SCROLL_DOWN_IN_SCROLL_MODE, + &SCROLL_DOWN_IN_SCROLL_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -276,10 +293,11 @@ pub fn max_panes() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, + &PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, &QUIT, ]); let mut opts = CliArgs::default(); @@ -308,10 +326,11 @@ pub fn toggle_focused_pane_fullscreen() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, - &SPAWN_TERMINAL, - &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, + &PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, &QUIT, ]); let mut opts = CliArgs::default(); diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs index e5659fdbe..be60fd7c4 100644 --- a/src/tests/integration/close_pane.rs +++ b/src/tests/integration/close_pane.rs @@ -6,8 +6,9 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - CLOSE_FOCUSED_PANE, COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, RESIZE_UP, - SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + CLOSE_PANE_IN_PANE_MODE, COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, + RESIZE_DOWN_IN_RESIZE_MODE, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, + SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -34,8 +35,9 @@ pub fn close_pane_with_another_pane_above_it() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -71,9 +73,10 @@ pub fn close_pane_with_another_pane_below_it() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -107,8 +110,9 @@ pub fn close_pane_with_another_pane_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -142,9 +146,10 @@ pub fn close_pane_with_another_pane_to_the_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -180,12 +185,13 @@ pub fn close_pane_with_multiple_panes_above_it() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -221,10 +227,11 @@ pub fn close_pane_with_multiple_panes_below_it() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -260,12 +267,13 @@ pub fn close_pane_with_multiple_panes_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -301,10 +309,11 @@ pub fn close_pane_with_multiple_panes_to_the_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -340,24 +349,41 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &RESIZE_UP, - &MOVE_FOCUS, - &RESIZE_UP, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -393,24 +419,41 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &RESIZE_DOWN, - &MOVE_FOCUS, - &RESIZE_DOWN, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -448,24 +491,41 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &RESIZE_LEFT, - &MOVE_FOCUS, - &RESIZE_LEFT, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -503,24 +563,41 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &RESIZE_LEFT, - &MOVE_FOCUS, - &RESIZE_LEFT, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -548,12 +625,13 @@ pub fn closing_last_pane_exits_app() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &CLOSE_FOCUSED_PANE, - &CLOSE_FOCUSED_PANE, - &CLOSE_FOCUSED_PANE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/move_focus_down.rs b/src/tests/integration/move_focus_down.rs index a5b423aaf..639078d8f 100644 --- a/src/tests/integration/move_focus_down.rs +++ b/src/tests/integration/move_focus_down.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS_DOWN, MOVE_FOCUS_UP, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS_DOWN_IN_PANE_MODE, MOVE_FOCUS_UP_IN_PANE_MODE, PANE_MODE, QUIT, + SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -25,9 +26,10 @@ pub fn move_focus_down() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS_UP, - &MOVE_FOCUS_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, + &MOVE_FOCUS_DOWN_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -55,11 +57,12 @@ pub fn move_focus_down_to_the_largest_overlap() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS_UP, - &MOVE_FOCUS_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, + &MOVE_FOCUS_DOWN_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/move_focus_left.rs b/src/tests/integration/move_focus_left.rs index 3f133557f..a8e073b90 100644 --- a/src/tests/integration/move_focus_left.rs +++ b/src/tests/integration/move_focus_left.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS_LEFT, MOVE_FOCUS_RIGHT, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS_LEFT_IN_PANE_MODE, MOVE_FOCUS_RIGHT_IN_PANE_MODE, PANE_MODE, QUIT, + SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -25,8 +26,9 @@ pub fn move_focus_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -54,12 +56,13 @@ pub fn move_focus_left_to_the_largest_overlap() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS_LEFT, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS_RIGHT, - &MOVE_FOCUS_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/move_focus_right.rs b/src/tests/integration/move_focus_right.rs index 05065b69c..72c24a9b8 100644 --- a/src/tests/integration/move_focus_right.rs +++ b/src/tests/integration/move_focus_right.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS_LEFT, MOVE_FOCUS_RIGHT, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS_LEFT_IN_PANE_MODE, MOVE_FOCUS_RIGHT_IN_PANE_MODE, PANE_MODE, QUIT, + SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -25,9 +26,10 @@ pub fn move_focus_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS_LEFT, - &MOVE_FOCUS_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, + &MOVE_FOCUS_RIGHT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -55,11 +57,12 @@ pub fn move_focus_right_to_the_largest_overlap() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS_LEFT, - &MOVE_FOCUS_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, + &MOVE_FOCUS_RIGHT_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/move_focus_up.rs b/src/tests/integration/move_focus_up.rs index 4944c1cad..fcfedb18f 100644 --- a/src/tests/integration/move_focus_up.rs +++ b/src/tests/integration/move_focus_up.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS_DOWN, MOVE_FOCUS_UP, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, MOVE_FOCUS_DOWN_IN_PANE_MODE, MOVE_FOCUS_UP_IN_PANE_MODE, PANE_MODE, QUIT, + SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -25,8 +26,9 @@ pub fn move_focus_up() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -54,12 +56,13 @@ pub fn move_focus_up_to_the_largest_overlap() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS_UP, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS_DOWN, - &MOVE_FOCUS_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/resize_down.rs b/src/tests/integration/resize_down.rs index 3b20fda83..ec0221cbd 100644 --- a/src/tests/integration/resize_down.rs +++ b/src/tests/integration/resize_down.rs @@ -6,8 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_DOWN, RESIZE_LEFT, SPLIT_HORIZONTALLY, - SPLIT_VERTICALLY, + COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_DOWN_IN_RESIZE_MODE, + RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -35,8 +35,13 @@ pub fn resize_down_with_pane_above() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -72,9 +77,14 @@ pub fn resize_down_with_pane_below() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -113,11 +123,16 @@ pub fn resize_down_with_panes_above_and_below() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -154,12 +169,17 @@ pub fn resize_down_with_multiple_panes_above() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -197,14 +217,19 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -242,13 +267,18 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -286,11 +316,16 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -328,12 +363,17 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -371,15 +411,20 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -417,17 +462,22 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -465,32 +515,45 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_LEFT, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -528,34 +591,47 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_ fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_LEFT, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); @@ -590,8 +666,13 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &RESIZE_DOWN, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_DOWN_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/resize_left.rs b/src/tests/integration/resize_left.rs index 3546ebe3e..9645a4ec4 100644 --- a/src/tests/integration/resize_left.rs +++ b/src/tests/integration/resize_left.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_LEFT_IN_RESIZE_MODE, + RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -31,8 +32,13 @@ pub fn resize_left_with_pane_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -66,9 +72,14 @@ pub fn resize_left_with_pane_to_the_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -102,11 +113,16 @@ pub fn resize_left_with_panes_to_the_left_and_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -141,12 +157,17 @@ pub fn resize_left_with_multiple_panes_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -182,14 +203,19 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -225,11 +251,16 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -265,13 +296,18 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -307,12 +343,17 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -350,15 +391,20 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -396,17 +442,22 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -444,32 +495,45 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_UP, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -508,34 +572,47 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_UP, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); @@ -570,8 +647,13 @@ pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &RESIZE_LEFT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/resize_right.rs b/src/tests/integration/resize_right.rs index 9f2c590ce..cea8ecdab 100644 --- a/src/tests/integration/resize_right.rs +++ b/src/tests/integration/resize_right.rs @@ -6,7 +6,9 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_RIGHT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_MODE, + RESIZE_RIGHT_IN_RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SPLIT_DOWN_IN_PANE_MODE, + SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -31,8 +33,13 @@ pub fn resize_right_with_pane_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -66,9 +73,14 @@ pub fn resize_right_with_pane_to_the_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -102,11 +114,16 @@ pub fn resize_right_with_panes_to_the_left_and_right() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -141,12 +158,17 @@ pub fn resize_right_with_multiple_panes_to_the_left() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -182,14 +204,19 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -225,11 +252,16 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -265,13 +297,18 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -307,12 +344,17 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -350,15 +392,20 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -396,17 +443,22 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_ fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -444,32 +496,45 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_UP, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -507,34 +572,47 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_UP, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, - &RESIZE_UP, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); @@ -569,8 +647,13 @@ pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &RESIZE_RIGHT, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_RIGHT_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/resize_up.rs b/src/tests/integration/resize_up.rs index 80dfac8a4..6e9f78133 100644 --- a/src/tests/integration/resize_up.rs +++ b/src/tests/integration/resize_up.rs @@ -6,7 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - COMMAND_TOGGLE, MOVE_FOCUS, QUIT, RESIZE_LEFT, RESIZE_UP, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, + COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, RESIZE_LEFT_IN_RESIZE_MODE, + RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE, SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -33,8 +34,13 @@ pub fn resize_up_with_pane_above() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -70,9 +76,14 @@ pub fn resize_up_with_pane_below() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -111,11 +122,16 @@ pub fn resize_up_with_panes_above_and_below() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -151,12 +167,17 @@ pub fn resize_up_with_multiple_panes_above() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -192,14 +213,19 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -237,13 +263,18 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -281,11 +312,16 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -323,12 +359,17 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -366,15 +407,20 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -412,17 +458,22 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -460,32 +511,45 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_ fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_LEFT, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -523,34 +587,47 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_LEFT, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_HORIZONTALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &SPLIT_VERTICALLY, - &SPLIT_VERTICALLY, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &MOVE_FOCUS, - &RESIZE_LEFT, - &RESIZE_LEFT, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_LEFT_IN_RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); @@ -585,8 +662,13 @@ pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &RESIZE_UP, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &RESIZE_MODE, + &RESIZE_UP_IN_RESIZE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap b/src/tests/integration/snapshots/mosaic__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap index 8c5ca0a82..8515bf37c 100644 --- a/src/tests/integration/snapshots/mosaic__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap +++ b/src/tests/integration/snapshots/mosaic__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap @@ -2,16 +2,6 @@ source: src/tests/integration/tabs.rs expression: snapshot_before_quit --- -line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -21,4 +11,14 @@ line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa prompt $ █ diff --git a/src/tests/integration/tabs.rs b/src/tests/integration/tabs.rs index 235042801..a4a0f52a2 100644 --- a/src/tests/integration/tabs.rs +++ b/src/tests/integration/tabs.rs @@ -2,12 +2,13 @@ use insta::assert_snapshot; use crate::tests::fakes::FakeInputOutput; use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; -use crate::{panes::PositionAndSize, tests::utils::commands::CLOSE_FOCUSED_PANE}; +use crate::{panes::PositionAndSize, tests::utils::commands::CLOSE_PANE_IN_PANE_MODE}; use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - CLOSE_TAB, COMMAND_TOGGLE, NEW_TAB, QUIT, SPLIT_HORIZONTALLY, SWITCH_NEXT_TAB, SWITCH_PREV_TAB, - TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, + CLOSE_TAB_IN_TAB_MODE, COMMAND_TOGGLE, ESC, NEW_TAB_IN_TAB_MODE, PANE_MODE, QUIT, + SPLIT_DOWN_IN_PANE_MODE, SWITCH_NEXT_TAB_IN_TAB_MODE, SWITCH_PREV_TAB_IN_TAB_MODE, TAB_MODE, + TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -26,8 +27,13 @@ pub fn open_new_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -55,9 +61,14 @@ pub fn switch_to_prev_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SWITCH_PREV_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &SWITCH_PREV_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -85,9 +96,14 @@ pub fn switch_to_next_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SWITCH_NEXT_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &SWITCH_NEXT_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -115,9 +131,14 @@ pub fn close_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &CLOSE_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -145,10 +166,15 @@ pub fn close_last_pane_in_a_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &NEW_TAB, - &SPLIT_HORIZONTALLY, - &CLOSE_FOCUSED_PANE, - &CLOSE_FOCUSED_PANE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -176,12 +202,20 @@ pub fn close_the_middle_tab() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SWITCH_PREV_TAB, - &CLOSE_TAB, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &SWITCH_PREV_TAB_IN_TAB_MODE, + &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -209,13 +243,34 @@ pub fn close_the_tab_that_has_a_pane_in_fullscreen() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &SWITCH_PREV_TAB, - &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, - &CLOSE_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &SWITCH_PREV_TAB_IN_TAB_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &CLOSE_TAB_IN_TAB_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -243,10 +298,15 @@ pub fn closing_last_tab_exits_the_app() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_HORIZONTALLY, - &NEW_TAB, - &CLOSE_TAB, - &CLOSE_TAB, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &ESC, + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &TAB_MODE, + &NEW_TAB_IN_TAB_MODE, + &CLOSE_TAB_IN_TAB_MODE, + &CLOSE_TAB_IN_TAB_MODE, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/integration/toggle_fullscreen.rs b/src/tests/integration/toggle_fullscreen.rs index 391497044..943e91a56 100644 --- a/src/tests/integration/toggle_fullscreen.rs +++ b/src/tests/integration/toggle_fullscreen.rs @@ -6,8 +6,8 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots} use crate::{start, CliArgs}; use crate::tests::utils::commands::{ - CLOSE_FOCUSED_PANE, COMMAND_TOGGLE, MOVE_FOCUS, QUIT, SPLIT_HORIZONTALLY, SPLIT_VERTICALLY, - TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, + COMMAND_TOGGLE, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT, SPLIT_DOWN_IN_PANE_MODE, + SPLIT_RIGHT_IN_PANE_MODE, TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, }; fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { @@ -26,9 +26,10 @@ pub fn adding_new_terminal_in_fullscreen() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, - &SPLIT_HORIZONTALLY, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); @@ -56,9 +57,10 @@ pub fn move_focus_is_disabled_in_fullscreen() { fake_input_output.add_terminal_input(&[ &COMMAND_TOGGLE, &COMMAND_TOGGLE, - &SPLIT_VERTICALLY, - &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN, - &MOVE_FOCUS, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE, + &MOVE_FOCUS_IN_PANE_MODE, &QUIT, ]); start(Box::new(fake_input_output.clone()), CliArgs::default()); diff --git a/src/tests/utils.rs b/src/tests/utils.rs index b8ecaeae9..587d36fdd 100644 --- a/src/tests/utils.rs +++ b/src/tests/utils.rs @@ -45,48 +45,35 @@ pub fn get_next_to_last_snapshot(mut snapshots: Vec) -> Option { } pub mod commands { - /// ctrl-g - pub const COMMAND_TOGGLE: [u8; 1] = [7]; - /// b - pub const SPLIT_HORIZONTALLY: [u8; 1] = [98]; - /// n - pub const SPLIT_VERTICALLY: [u8; 1] = [110]; - /// j - pub const RESIZE_DOWN: [u8; 1] = [106]; - /// k - pub const RESIZE_UP: [u8; 1] = [107]; - /// p - pub const MOVE_FOCUS: [u8; 1] = [112]; - /// h - pub const RESIZE_LEFT: [u8; 1] = [104]; - /// l - pub const RESIZE_RIGHT: [u8; 1] = [108]; - /// z - pub const SPAWN_TERMINAL: [u8; 1] = [122]; - /// q - pub const QUIT: [u8; 1] = [113]; - /// PgUp - pub const SCROLL_UP: [u8; 4] = [27, 91, 53, 126]; - /// PgDn - pub const SCROLL_DOWN: [u8; 4] = [27, 91, 54, 126]; - /// x - pub const CLOSE_FOCUSED_PANE: [u8; 1] = [120]; - /// e - pub const TOGGLE_ACTIVE_TERMINAL_FULLSCREEN: [u8; 1] = [101]; - /// y - pub const MOVE_FOCUS_LEFT: [u8; 1] = [121]; - /// u - pub const MOVE_FOCUS_DOWN: [u8; 1] = [117]; - /// i - pub const MOVE_FOCUS_UP: [u8; 1] = [105]; - /// o - pub const MOVE_FOCUS_RIGHT: [u8; 1] = [111]; - /// 1 - pub const NEW_TAB: [u8; 1] = [49]; - /// 2 - pub const SWITCH_PREV_TAB: [u8; 1] = [50]; - /// 3 - pub const SWITCH_NEXT_TAB: [u8; 1] = [51]; - /// 4 - pub const CLOSE_TAB: [u8; 1] = [52]; + pub const COMMAND_TOGGLE: [u8; 1] = [7]; // ctrl-g + pub const QUIT: [u8; 1] = [113]; // q + pub const ESC: [u8; 1] = [27]; + + pub const PANE_MODE: [u8; 1] = [112]; // p + pub const SPAWN_TERMINAL_IN_PANE_MODE: [u8; 1] = [110]; // n + pub const MOVE_FOCUS_IN_PANE_MODE: [u8; 1] = [112]; // p + pub const SPLIT_DOWN_IN_PANE_MODE: [u8; 1] = [100]; // d + pub const SPLIT_RIGHT_IN_PANE_MODE: [u8; 1] = [114]; // r + pub const TOGGLE_ACTIVE_TERMINAL_FULLSCREEN_IN_PANE_MODE: [u8; 1] = [102]; // f + pub const CLOSE_PANE_IN_PANE_MODE: [u8; 1] = [120]; // x + pub const MOVE_FOCUS_DOWN_IN_PANE_MODE: [u8; 1] = [106]; // j + pub const MOVE_FOCUS_UP_IN_PANE_MODE: [u8; 1] = [107]; // k + pub const MOVE_FOCUS_LEFT_IN_PANE_MODE: [u8; 1] = [104]; // h + pub const MOVE_FOCUS_RIGHT_IN_PANE_MODE: [u8; 1] = [108]; // l + + pub const SCROLL_MODE: [u8; 1] = [115]; // s + pub const SCROLL_UP_IN_SCROLL_MODE: [u8; 1] = [107]; // k + pub const SCROLL_DOWN_IN_SCROLL_MODE: [u8; 1] = [106]; // j + + pub const RESIZE_MODE: [u8; 1] = [114]; // r + pub const RESIZE_DOWN_IN_RESIZE_MODE: [u8; 1] = [106]; // j + pub const RESIZE_UP_IN_RESIZE_MODE: [u8; 1] = [107]; // k + pub const RESIZE_LEFT_IN_RESIZE_MODE: [u8; 1] = [104]; // h + pub const RESIZE_RIGHT_IN_RESIZE_MODE: [u8; 1] = [108]; // l + + pub const TAB_MODE: [u8; 1] = [116]; // t + pub const NEW_TAB_IN_TAB_MODE: [u8; 1] = [110]; // n + pub const SWITCH_NEXT_TAB_IN_TAB_MODE: [u8; 1] = [108]; // l + pub const SWITCH_PREV_TAB_IN_TAB_MODE: [u8; 1] = [104]; // h + pub const CLOSE_TAB_IN_TAB_MODE: [u8; 1] = [120]; // x }