diff options
| author | Brooks J Rady <b.j.rady@gmail.com> | 2021-02-09 22:19:34 +0000 |
|---|---|---|
| committer | Brooks J Rady <b.j.rady@gmail.com> | 2021-02-09 22:19:34 +0000 |
| commit | 979197085617a84992b38c7fd02098965e2479d5 (patch) | |
| tree | 4136a1d4f39254e72379d1204b62ce6b1e54d144 /src | |
| parent | Work towards a functional build (diff) | |
| download | sl0ppij-979197085617a84992b38c7fd02098965e2479d5.tar.gz sl0ppij-979197085617a84992b38c7fd02098965e2479d5.tar.xz sl0ppij-979197085617a84992b38c7fd02098965e2479d5.zip | |
Well, it turns out that I spent 4 hours on something impossible...
Diffstat (limited to 'src')
182 files changed, 16962 insertions, 0 deletions
diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 00000000..6fc5020b --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,29 @@ +use std::path::PathBuf; +use structopt::StructOpt; + +#[derive(StructOpt, Debug, Default)] +#[structopt(name = "mosaic")] +pub struct CliArgs { + /// Send "split (direction h == horizontal / v == vertical)" to active mosaic session + #[structopt(short, long)] + pub split: Option<char>, + + /// Send "move focused pane" to active mosaic session + #[structopt(short, long)] + pub move_focus: bool, + + /// Send "open file in new pane" to active mosaic session + #[structopt(short, long)] + pub open_file: Option<PathBuf>, + + /// Maximum panes on screen, caution: opening more panes will close old ones + #[structopt(long)] + pub max_panes: Option<usize>, + + /// Path to a layout yaml file + #[structopt(short, long)] + pub layout: Option<PathBuf>, + + #[structopt(short, long)] + pub debug: bool, +} diff --git a/src/client/boundaries.rs b/src/client/boundaries.rs new file mode 100644 index 00000000..67733c12 --- /dev/null +++ b/src/client/boundaries.rs @@ -0,0 +1,831 @@ +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 = "│"; + pub const HORIZONTAL: &str = "─"; + pub const TOP_LEFT: &str = "┌"; + pub const BOTTOM_RIGHT: &str = "┘"; + pub const BOTTOM_LEFT: &str = "└"; + pub const VERTICAL_LEFT: &str = "┤"; + pub const VERTICAL_RIGHT: &str = "├"; + pub const HORIZONTAL_DOWN: &str = "┬"; + pub const HORIZONTAL_UP: &str = "┴"; + pub const CROSS: &str = "┼"; +} + +pub type BoundaryType = &'static str; // easy way to refer to boundary_type above + +#[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<BoundarySymbol> { + 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(┐) + let boundary_type = boundary_type::TOP_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::VERTICAL) => { + // (┐, │) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL) => { + // (┐, ─) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::TOP_LEFT) => { + // (┐, ┌) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::BOTTOM_RIGHT) => { + // (┐, ┘) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::BOTTOM_LEFT) => { + // (┐, └) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::VERTICAL_LEFT) => { + // (┐, ┤) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::VERTICAL_RIGHT) => { + // (┐, ├) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_DOWN) => { + // (┐, ┬) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::HORIZONTAL_UP) => { + // (┐, ┴) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_RIGHT, boundary_type::CROSS) => { + // (┐, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL) => { + // (─, ─) => Some(─) + let boundary_type = boundary_type::HORIZONTAL; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::VERTICAL) => { + // (─, │) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::TOP_LEFT) => { + // (─, ┌) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::BOTTOM_RIGHT) => { + // (─, ┘) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::BOTTOM_LEFT) => { + // (─, └) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::VERTICAL_LEFT) => { + // (─, ┤) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::VERTICAL_RIGHT) => { + // (─, ├) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_DOWN) => { + // (─, ┬) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::HORIZONTAL_UP) => { + // (─, ┴) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL, boundary_type::CROSS) => { + // (─, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::VERTICAL) => { + // (│, │) => Some(│) + let boundary_type = boundary_type::VERTICAL; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::TOP_LEFT) => { + // (│, ┌) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::BOTTOM_RIGHT) => { + // (│, ┘) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::BOTTOM_LEFT) => { + // (│, └) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::VERTICAL_LEFT) => { + // (│, ┤) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::VERTICAL_RIGHT) => { + // (│, ├) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::HORIZONTAL_DOWN) => { + // (│, ┬) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::HORIZONTAL_UP) => { + // (│, ┴) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL, boundary_type::CROSS) => { + // (│, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::TOP_LEFT) => { + // (┌, ┌) => Some(┌) + let boundary_type = boundary_type::TOP_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::BOTTOM_RIGHT) => { + // (┌, ┘) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::BOTTOM_LEFT) => { + // (┌, └) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::VERTICAL_LEFT) => { + // (┌, ┤) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::VERTICAL_RIGHT) => { + // (┌, ├) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_DOWN) => { + // (┌, ┬) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::HORIZONTAL_UP) => { + // (┌, ┴) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::TOP_LEFT, boundary_type::CROSS) => { + // (┌, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_RIGHT) => { + // (┘, ┘) => Some(┘) + let boundary_type = boundary_type::BOTTOM_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::BOTTOM_LEFT) => { + // (┘, └) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_LEFT) => { + // (┘, ┤) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::VERTICAL_RIGHT) => { + // (┘, ├) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_DOWN) => { + // (┘, ┬) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::HORIZONTAL_UP) => { + // (┘, ┴) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_RIGHT, boundary_type::CROSS) => { + // (┘, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::BOTTOM_LEFT) => { + // (└, └) => Some(└) + let boundary_type = boundary_type::BOTTOM_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_LEFT) => { + // (└, ┤) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::VERTICAL_RIGHT) => { + // (└, ├) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_DOWN) => { + // (└, ┬) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::HORIZONTAL_UP) => { + // (└, ┴) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::BOTTOM_LEFT, boundary_type::CROSS) => { + // (└, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_LEFT) => { + // (┤, ┤) => Some(┤) + let boundary_type = boundary_type::VERTICAL_LEFT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_LEFT, boundary_type::VERTICAL_RIGHT) => { + // (┤, ├) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_DOWN) => { + // (┤, ┬) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_LEFT, boundary_type::HORIZONTAL_UP) => { + // (┤, ┴) => Some(┼) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_LEFT, boundary_type::CROSS) => { + // (┤, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_RIGHT, boundary_type::VERTICAL_RIGHT) => { + // (├, ├) => Some(├) + let boundary_type = boundary_type::VERTICAL_RIGHT; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_DOWN) => { + // (├, ┬) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_RIGHT, boundary_type::HORIZONTAL_UP) => { + // (├, ┴) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::VERTICAL_RIGHT, boundary_type::CROSS) => { + // (├, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_DOWN) => { + // (┬, ┬) => Some(┬) + let boundary_type = boundary_type::HORIZONTAL_DOWN; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL_DOWN, boundary_type::HORIZONTAL_UP) => { + // (┬, ┴) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL_DOWN, boundary_type::CROSS) => { + // (┬, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL_UP, boundary_type::HORIZONTAL_UP) => { + // (┴, ┴) => Some(┴) + let boundary_type = boundary_type::HORIZONTAL_UP; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::HORIZONTAL_UP, boundary_type::CROSS) => { + // (┴, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (boundary_type::CROSS, boundary_type::CROSS) => { + // (┼, ┼) => Some(┼) + let boundary_type = boundary_type::CROSS; + Some(BoundarySymbol { + boundary_type, + invisible, + }) + } + (_, _) => None, + } +} + +fn find_next_symbol( + first_symbol: BoundarySymbol, + second_symbol: BoundarySymbol, +) -> Option<BoundarySymbol> { + if let Some(symbol) = combine_symbols(first_symbol, second_symbol) { + Some(symbol) + } else { + combine_symbols(second_symbol, first_symbol) + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub struct Coordinates { + x: usize, + y: usize, +} + +impl Coordinates { + pub fn new(x: usize, y: usize) -> Self { + Coordinates { x, y } + } +} + +pub trait Rect { + fn x(&self) -> usize; + fn y(&self) -> usize; + fn rows(&self) -> usize; + fn columns(&self) -> usize; + fn right_boundary_x_coords(&self) -> usize { + self.x() + self.columns() + } + fn bottom_boundary_y_coords(&self) -> usize { + self.y() + self.rows() + } + fn is_directly_right_of(&self, other: &Self) -> bool { + self.x() == other.x() + other.columns() + 1 + } + fn is_directly_left_of(&self, other: &Self) -> bool { + self.x() + self.columns() + 1 == other.x() + } + fn is_directly_below(&self, other: &Self) -> bool { + self.y() == other.y() + other.rows() + 1 + } + fn is_directly_above(&self, other: &Self) -> bool { + self.y() + self.rows() + 1 == other.y() + } + fn horizontally_overlaps_with(&self, other: &Self) -> bool { + (self.y() >= other.y() && self.y() <= (other.y() + other.rows())) + || ((self.y() + self.rows()) <= (other.y() + other.rows()) + && (self.y() + self.rows()) > other.y()) + || (self.y() <= other.y() && (self.y() + self.rows() >= (other.y() + other.rows()))) + || (other.y() <= self.y() && (other.y() + other.rows() >= (self.y() + self.rows()))) + } + fn get_horizontal_overlap_with(&self, other: &Self) -> usize { + std::cmp::min(self.y() + self.rows(), other.y() + other.rows()) + - std::cmp::max(self.y(), other.y()) + } + fn vertically_overlaps_with(&self, other: &Self) -> bool { + (self.x() >= other.x() && self.x() <= (other.x() + other.columns())) + || ((self.x() + self.columns()) <= (other.x() + other.columns()) + && (self.x() + self.columns()) > other.x()) + || (self.x() <= other.x() + && (self.x() + self.columns() >= (other.x() + other.columns()))) + || (other.x() <= self.x() + && (other.x() + other.columns() >= (self.x() + self.columns()))) + } + fn get_vertical_overlap_with(&self, other: &Self) -> usize { + std::cmp::min(self.x() + self.columns(), other.x() + other.columns()) + - std::cmp::max(self.x(), other.x()) + } +} + +pub struct Boundaries { + columns: usize, + rows: usize, + // boundary_characters: HashMap<Coordinates, BoundaryType>, + boundary_characters: HashMap<Coordinates, BoundarySymbol>, +} + +impl Boundaries { + pub fn new(columns: u16, rows: u16) -> Self { + let columns = columns as usize; + let rows = rows as usize; + Boundaries { + columns, + rows, + boundary_characters: HashMap::new(), + } + } + 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(); + 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_RIGHT) + } else if row == last_row_coordinates - 1 && row != self.rows - 1 { + BoundarySymbol::new(boundary_type::BOTTOM_RIGHT) + } 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 self.rect_bottom_boundary_is_before_screen_edge(rect) { + let boundary_y_coords = rect.bottom_boundary_y_coords(); + 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::BOTTOM_LEFT) + } else if col == last_col_coordinates - 1 && col != self.columns - 1 { + BoundarySymbol::new(boundary_type::BOTTOM_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); + } + } + } + pub fn vte_output(&self) -> String { + let mut vte_output = String::new(); + for (coordinates, boundary_character) in &self.boundary_characters { + vte_output.push_str(&format!( + "\u{1b}[{};{}H\u{1b}[m{}", + coordinates.y + 1, + coordinates.x + 1, + boundary_character + )); // goto row/col + boundary character + } + vte_output + } + fn rect_right_boundary_is_before_screen_edge(&self, rect: &dyn Pane) -> bool { + rect.x() + rect.columns() < self.columns + } + fn rect_bottom_boundary_is_before_screen_edge(&self, rect: &dyn Pane) -> bool { + rect.y() + rect.rows() < self.rows + } + fn rect_right_boundary_row_start(&self, rect: &dyn Pane) -> usize { + if rect.y() == 0 { + 0 + } else { + rect.y() - 1 + } + } + fn rect_right_boundary_row_end(&self, rect: &dyn Pane) -> usize { + let rect_bottom_row = rect.y() + rect.rows(); + // we do this because unless we're on the screen edge, we'd like to go one extra row to + // connect to whatever boundary is beneath us + if rect_bottom_row == self.rows { + rect_bottom_row + } else { + rect_bottom_row + 1 + } + } + fn rect_bottom_boundary_col_start(&self, rect: &dyn Pane) -> usize { + if rect.x() == 0 { + 0 + } else { + rect.x() - 1 + } + } + fn rect_bottom_boundary_col_end(&self, rect: &dyn Pane) -> usize { + let rect_right_col = rect.x() + rect.columns(); + // we do this because unless we're on the screen edge, we'd like to go one extra column to + // connect to whatever boundary is right of us + if rect_right_col == self.columns { + rect_right_col + } else { + rect_right_col + 1 + } + } +} diff --git a/src/client/layout.rs b/src/client/layout.rs new file mode 100644 index 00000000..d09e7618 --- /dev/null +++ b/src/client/layout.rs @@ -0,0 +1,220 @@ +use crate::utils::consts::MOSAIC_ROOT_LAYOUT_DIR; +use directories_next::ProjectDirs; +use serde::{Deserialize, Serialize}; +use std::path::{Path, PathBuf}; +use std::{fs::File, io::prelude::*}; + +use crate::panes::PositionAndSize; + +fn split_space_to_parts_vertically( + space_to_split: &PositionAndSize, + sizes: Vec<Option<SplitSize>>, +) -> Vec<PositionAndSize> { + let mut split_parts = Vec::new(); + let mut current_x_position = space_to_split.x; + let mut current_width = 0; + let max_width = space_to_split.columns - (sizes.len() - 1); // minus space for gaps + + let mut parts_to_grow = Vec::new(); + + // First fit in the parameterized sizes + for size in sizes { + let columns = match size { + Some(SplitSize::Percent(percent)) => { + (max_width as f32 * (percent as f32 / 100.0)) as usize + } // TODO: round properly + Some(SplitSize::Fixed(size)) => size as usize, + None => { + parts_to_grow.push(current_x_position); + 1 // This is grown later on + } + }; + split_parts.push(PositionAndSize { + x: current_x_position, + y: space_to_split.y, + columns, + rows: space_to_split.rows, + }); + current_width += columns; + current_x_position += columns + 1; // 1 for gap + } + + if current_width > max_width { + panic!("Layout contained too many columns to fit onto the screen!"); + } + + let mut last_flexible_index = split_parts.len() - 1; + if let Some(new_columns) = (max_width - current_width).checked_div(parts_to_grow.len()) { + current_width = 0; + current_x_position = 0; + for (idx, part) in split_parts.iter_mut().enumerate() { + part.x = current_x_position; + if parts_to_grow.contains(&part.x) { + part.columns = new_columns; + last_flexible_index = idx; + } + current_width += part.columns; + current_x_position += part.columns + 1; // 1 for gap + } + } + + if current_width < max_width { + // we have some extra space left, let's add it to the last flexible part + let extra = max_width - current_width; + let mut last_part = split_parts.get_mut(last_flexible_index).unwrap(); + last_part.columns += extra; + for part in (&mut split_parts[last_flexible_index + 1..]).iter_mut() { + part.x += extra; + } + } + split_parts +} + +fn split_space_to_parts_horizontally( + space_to_split: &PositionAndSize, + sizes: Vec<Option<SplitSize>>, +) -> Vec<PositionAndSize> { + let mut split_parts = Vec::new(); + let mut current_y_position = space_to_split.y; + let mut current_height = 0; + let max_height = space_to_split.rows - (sizes.len() - 1); // minus space for gaps + + let mut parts_to_grow = Vec::new(); + + for size in sizes { + let rows = match size { + Some(SplitSize::Percent(percent)) => { + (max_height as f32 * (percent as f32 / 100.0)) as usize + } // TODO: round properly + Some(SplitSize::Fixed(size)) => size as usize, + None => { + parts_to_grow.push(current_y_position); + 1 // This is grown later on + } + }; + split_parts.push(PositionAndSize { + x: space_to_split.x, + y: current_y_position, + columns: space_to_split.columns, + rows, + }); + current_height += rows; + current_y_position += rows + 1; // 1 for gap + } + + if current_height > max_height { + panic!("Layout contained too many rows to fit onto the screen!"); + } + + let mut last_flexible_index = split_parts.len() - 1; + if let Some(new_rows) = (max_height - current_height).checked_div(parts_to_grow.len()) { + current_height = 0; + current_y_position = 0; + + for (idx, part) in split_parts.iter_mut().enumerate() { + part.y = current_y_position; + if parts_to_grow.contains(&part.y) { + part.rows = new_rows; + last_flexible_index = idx; + } + current_height += part.rows; + current_y_position += part.rows + 1; // 1 for gap + } + } + + if current_height < max_height { + // we have some extra space left, let's add it to the last flexible part + let extra = max_height - current_height; + let mut last_part = split_parts.get_mut(last_flexible_index).unwrap(); + last_part.rows += extra; + for part in (&mut split_parts[last_flexible_index + 1..]).iter_mut() { + part.y += extra; + } + } + split_parts +} + +fn split_space( + space_to_split: &PositionAndSize, + layout: &Layout, +) -> Vec<(Layout, PositionAndSize)> { + let mut pane_positions = Vec::new(); + let sizes: Vec<Option<SplitSize>> = layout.parts.iter().map(|part| part.split_size).collect(); + + let split_parts = match layout.direction { + Direction::Vertical => split_space_to_parts_vertically(space_to_split, sizes), + Direction::Horizontal => split_space_to_parts_horizontally(space_to_split, sizes), + }; + for (i, part) in layout.parts.iter().enumerate() { + let part_position_and_size = split_parts.get(i).unwrap(); + if !part.parts.is_empty() { + let mut part_positions = split_space(&part_position_and_size, part); + pane_positions.append(&mut part_positions); + } else { + pane_positions.push((part.clone(), *part_position_and_size)); + } + } + pane_positions +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub enum Direction { + Horizontal, + Vertical, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum SplitSize { + Percent(u8), // 1 to 100 + Fixed(u16), // An absolute number of columns or rows +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct Layout { + pub direction: Direction, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub parts: Vec<Layout>, + #[serde(skip_serializing_if = "Option::is_none")] + pub split_size: Option<SplitSize>, + #[serde(skip_serializing_if = "Option::is_none")] + pub plugin: Option<PathBuf>, +} + +impl Layout { + pub fn new(layout_path: PathBuf) -> Self { + let project_dirs = ProjectDirs::from("org", "Mosaic Contributors", "Mosaic").unwrap(); + let layout_dir = project_dirs.data_dir().join("layouts/"); + let root_layout_dir = Path::new(MOSAIC_ROOT_LAYOUT_DIR); + let mut layout_file = File::open(&layout_path) + .or_else(|_| File::open(&layout_path.with_extension("yaml"))) + .or_else(|_| File::open(&layout_dir.join(&layout_path).with_extension("yaml"))) + .or_else(|_| File::open(root_layout_dir.join(&layout_path).with_extension("yaml"))) + .unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display())); + + let mut layout = String::new(); + layout_file + .read_to_string(&mut layout) + .unwrap_or_else(|_| panic!("could not read layout {}", &layout_path.display())); + let layout: Layout = serde_yaml::from_str(&layout) + .unwrap_or_else(|_| panic!("could not parse layout {}", &layout_path.display())); + layout + } + + pub fn total_terminal_panes(&self) -> usize { + let mut total_panes = 0; + total_panes += self.parts.len(); + for part in self.parts.iter() { + if part.plugin.is_none() { + total_panes += part.total_terminal_panes(); + } + } + total_panes + } + + pub fn position_panes_in_space( + &self, + space: &PositionAndSize, + ) -> Vec<(Layout, PositionAndSize)> { + split_space(space, &self) + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 00000000..c8276253 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,6 @@ +pub mod boundaries; +pub mod layout; +pub mod panes; +pub mod tab; + +pub fn start_client() {} diff --git a/src/client/panes/grid.rs b/src/client/panes/grid.rs new file mode 100644 index 00000000..062b5c3a --- /dev/null +++ b/src/client/panes/grid.rs @@ -0,0 +1,820 @@ +use std::{ + cmp::Ordering, + fmt::{self, Debug, Formatter}, +}; + +use crate::panes::terminal_character::{ + CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, +}; + +fn get_top_non_canonical_rows(rows: &mut Vec<Row>) -> Vec<Row> { + let mut index_of_last_non_canonical_row = None; + for (i, row) in rows.iter().enumerate() { + if row.is_canonical { + break; + } else { + index_of_last_non_canonical_row = Some(i); + } + } + match index_of_last_non_canonical_row { + Some(index_of_last_non_canonical_row) => { + rows.drain(..=index_of_last_non_canonical_row).collect() + } + None => vec![], + } +} + +fn get_bottom_canonical_row_and_wraps(rows: &mut Vec<Row>) -> Vec<Row> { + let mut index_of_last_non_canonical_row = None; + for (i, row) in rows.iter().enumerate().rev() { + if row.is_canonical { + index_of_last_non_canonical_row = Some(i); + break; + } else { + index_of_last_non_canonical_row = Some(i); + } + } + match index_of_last_non_canonical_row { + Some(index_of_last_non_canonical_row) => { + rows.drain(index_of_last_non_canonical_row..).collect() + } + None => vec![], + } +} + +fn transfer_rows_down( + source: &mut Vec<Row>, + destination: &mut Vec<Row>, + count: usize, + max_src_width: Option<usize>, + max_dst_width: Option<usize>, +) { + let mut next_lines: Vec<Row> = vec![]; + let mut lines_added_to_destination: isize = 0; + loop { + if lines_added_to_destination as usize == count { + break; + } + if next_lines.is_empty() { + match source.pop() { + Some(next_line) => { + let mut top_non_canonical_rows_in_dst = get_top_non_canonical_rows(destination); + lines_added_to_destination -= top_non_canonical_rows_in_dst.len() as isize; + next_lines.push(next_line); + next_lines.append(&mut top_non_canonical_rows_in_dst); + next_lines = match max_dst_width { + Some(max_row_width) => { + Row::from_rows(next_lines).split_to_rows_of_length(max_row_width) + } + None => vec![Row::from_rows(next_lines)], + }; + } + None => break, // no more rows + } + } + destination.insert(0, next_lines.pop().unwrap()); + lines_added_to_destination += 1; + } + if !next_lines.is_empty() { + match max_src_width { + Some(max_row_width) => { + let mut excess_rows = + Row::from_rows(next_lines).split_to_rows_of_length(max_row_width); + source.append(&mut excess_rows); + } + None => { + let excess_row = Row::from_rows(next_lines); + source.push(excess_row); + } + } + } +} + +fn transfer_rows_up( + source: &mut Vec<Row>, + destination: &mut Vec<Row>, + count: usize, + max_src_width: Option<usize>, + max_dst_width: Option<usize>, +) { + let mut next_lines: Vec<Row> = vec![]; + for _ in 0..count { + if next_lines.is_empty() { + if !source.is_empty() { + let next_line = source.remove(0); + if !next_line.is_canonical { + let mut bottom_canonical_row_and_wraps_in_dst = + get_bottom_canonical_row_and_wraps(destination); + next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst); + } + next_lines.push(next_line); + next_lines = match max_dst_width { + Some(max_row_width) => { + Row::from_rows(next_lines).split_to_rows_of_length(max_row_width) + } + None => vec![Row::from_rows(next_lines)], + }; + } else { + break; // no more rows + } + } + destination.push(next_lines.remove(0)); + } + if !next_lines.is_empty() { + match max_src_width { + Some(max_row_width) => { + let excess_rows = Row::from_rows(next_lines).split_to_rows_of_length(max_row_width); + for row in excess_rows { + source.insert(0, row); + } + } + None => { + let excess_row = Row::from_rows(next_lines); + source.insert(0, excess_row); + } + } + } +} + +#[derive(Clone)] +pub struct Grid { + lines_above: Vec<Row>, + viewport: Vec<Row>, + lines_below: Vec<Row>, + cursor: Cursor, + scroll_region: Option<(usize, usize)>, + pub width: usize, + pub height: usize, +} + +impl Debug for Grid { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + for (i, row) in self.viewport.iter().enumerate() { + if row.is_canonical { + writeln!(f, "{:?} (C): {:?}", i, row)?; + } else { + writeln!(f, "{:?} (W): {:?}", i, row)?; + } + } + Ok(()) + } +} + +impl Grid { + pub fn new(rows: usize, columns: usize) -> Self { + Grid { + lines_above: vec![], + viewport: vec![], + lines_below: vec![], + cursor: Cursor::new(0, 0), + scroll_region: None, + width: columns, + height: rows, + } + } + fn cursor_canonical_line_index(&self) -> usize { + let mut cursor_canonical_line_index = 0; + let mut canonical_lines_traversed = 0; + for (i, line) in self.viewport.iter().enumerate() { + if line.is_canonical { + cursor_canonical_line_index = canonical_lines_traversed; + canonical_lines_traversed += 1; + } + if i == self.cursor.y { + break; + } + } + cursor_canonical_line_index + } + // TODO: merge these two funtions + fn cursor_index_in_canonical_line(&self) -> usize { + let mut cursor_canonical_line_index = 0; + let mut cursor_index_in_canonical_line = 0; + for (i, line) in self.viewport.iter().enumerate() { + if line.is_canonical { + cursor_canonical_line_index = i; + } + if i == self.cursor.y { + let line_wrap_position_in_line = self.cursor.y - cursor_canonical_line_index; + cursor_index_in_canonical_line = line_wrap_position_in_line + self.cursor.x; + break; + } + } + cursor_index_in_canonical_line + } + fn canonical_line_y_coordinates(&self, canonical_line_index: usize) -> usize { + let mut canonical_lines_traversed = 0; + let mut y_coordinates = 0; + for (i, line) in self.viewport.iter().enumerate() { + if line.is_canonical { + canonical_lines_traversed += 1; + if canonical_lines_traversed == canonical_line_index + 1 { + y_coordinates = i; + break; + } + } + } + y_coordinates + } + pub fn scroll_up_one_line(&mut self) { + if !self.lines_above.is_empty() && self.viewport.len() == self.height { + let line_to_push_down = self.viewport.pop().unwrap(); + self.lines_below.insert(0, line_to_push_down); + let line_to_insert_at_viewport_top = self.lines_above.pop().unwrap(); + self.viewport.insert(0, line_to_insert_at_viewport_top); + } + } + pub fn scroll_down_one_line(&mut self) { + if !self.lines_below.is_empty() && self.viewport.len() == self.height { + let mut line_to_push_up = self.viewport.remove(0); + if line_to_push_up.is_canonical { + self.lines_above.push(line_to_push_up); + } else { + let mut last_line_above = self.lines_above.pop().unwrap(); + last_line_above.append(&mut line_to_push_up.columns); + self.lines_above.push(last_line_above); + } + let line_to_insert_at_viewport_bottom = self.lines_below.remove(0); + self.viewport.push(line_to_insert_at_viewport_bottom); + } + } + pub fn change_size(&mut self, new_rows: usize, new_columns: usize) { + if new_columns != self.width { + let mut cursor_canonical_line_index = self.cursor_canonical_line_index(); + let cursor_index_in_canonical_line = self.cursor_index_in_canonical_line(); + let mut viewport_canonical_lines = vec![]; + for mut row in self.viewport.drain(..) { + if !row.is_canonical + && viewport_canonical_lines.is_empty() + && !self.lines_above.is_empty() + { + let mut first_line_above = self.lines_above.pop().unwrap(); + first_line_above.append(&mut row.columns); + viewport_canonical_lines.push(first_line_above); + cursor_canonical_line_index += 1; + } else if row.is_canonical { + viewport_canonical_lines.push(row); + } else { + match viewport_canonical_lines.last_mut() { + Some(last_line) => { + last_line.append(&mut row.columns); + } + None => { + // the state is corrupted somehow + // this is a bug and I'm not yet sure why it happens + // usually it fixes itself and is a result of some race + // TODO: investigate why this happens and solve it + return; + } + } + } + } + let mut new_viewport_rows = vec![]; + for mut canonical_line in viewport_canonical_lines { + let mut canonical_line_parts: Vec<Row> = vec![]; + if canonical_line.columns.is_empty() { + canonical_line_parts.push(Row::new().canonical()); + } + while !canonical_line.columns.is_empty() { + let next_wrap = if canonical_line.len() > new_columns { + canonical_line.columns.drain(..new_columns) + } else { + canonical_line.columns.drain(..) + }; + let row = Row::from_columns(next_wrap.collect()); + // if there are no more parts, this row is canonical as long as it originally + // was canonical (it might not have been for example if it's the first row in + // the viewport, and the actual canonical row is above it in the scrollback) + let row = if canonical_line_parts.is_empty() && canonical_line.is_canonical { + row.canonical() + } else { + row + }; + canonical_line_parts.push(row); + } + new_viewport_rows.append(&mut canonical_line_parts); + } + self.viewport = new_viewport_rows; + + let mut new_cursor_y = self.canonical_line_y_coordinates(cursor_canonical_line_index); + let new_cursor_x = (cursor_index_in_canonical_line / new_columns) + + (cursor_index_in_canonical_line % new_columns); + let current_viewport_row_count = self.viewport.len(); + match current_viewport_row_count.cmp(&self.height) { + Ordering::Less => { + let row_count_to_transfer = self.height - current_viewport_row_count; + transfer_rows_down( + &mut self.lines_above, + &mut self.viewport, + row_count_to_transfer, + None, + Some(new_columns), + ); + let rows_pulled = self.viewport.len() - current_viewport_row_count; + new_cursor_y += rows_pulled; + } + Ordering::Greater => { + let row_count_to_transfer = current_viewport_row_count - self.height; + if row_count_to_transfer > new_cursor_y { + new_cursor_y = 0; + } else { + new_cursor_y -= row_count_to_transfer; + } + transfer_rows_up( + &mut self.viewport, + &mut self.lines_above, + row_count_to_transfer, + Some(new_columns), + None, + ); + } + Ordering::Equal => {} + } + self.cursor.y = new_cursor_y; + self.cursor.x = new_cursor_x; + } + if new_rows != self.height { + let current_viewport_row_count = self.viewport.len(); + match current_viewport_row_count.cmp(&new_rows) { + Ordering::Less => { + let row_count_to_transfer = new_rows - current_viewport_row_count; + transfer_rows_down( + &mut self.lines_above, + &mut self.viewport, + row_count_to_transfer, + None, + Some(new_columns), + ); + let rows_pulled = self.viewport.len() - current_viewport_row_count; + self.cursor.y += rows_pulled; + } + Ordering::Greater => { + let row_count_to_transfer = current_viewport_row_count - new_rows; + if row_count_to_transfer > self.cursor.y { + self.cursor.y = 0; + } else { + self.cursor.y -= row_count_to_transfer; + } + transfer_rows_up( + &mut self.viewport, + &mut self.lines_above, + row_count_to_transfer, + Some(new_columns), + None, + ); + } + Ordering::Equal => {} + } + } + self.height = new_rows; + self.width = new_columns; + if self.scroll_region.is_some() { + self.set_scroll_region_to_viewport_size(); + } + } + pub fn as_character_lines(&self) -> Vec<Vec<TerminalCharacter>> { + let mut lines: Vec<Vec<TerminalCharacter>> = self + .viewport + .iter() + .map(|r| { + let mut line: Vec<TerminalCharacter> = r.columns.iter().copied().collect(); + // pad line + line.resize(self.width, EMPTY_TERMINAL_CHARACTER); + line + }) + .collect(); + let empty_row = vec![EMPTY_TERMINAL_CHARACTER; self.width]; + for _ in lines.len()..self.height { + lines.push(empty_row.clone()); + } + lines + } + pub fn cursor_coordinates(&self) -> Option<(usize, usize)> { + if self.cursor.is_hidden { + None + } else { + Some((self.cursor.x, self.cursor.y)) + } + } + pub fn move_viewport_up(&mut self, count: usize) { + for _ in 0..count { + self.scroll_up_one_line(); + } + } + pub fn move_viewport_down(&mut self, count: usize) { + for _ in 0..count { + self.scroll_down_one_line(); + } + } + pub fn reset_viewport(&mut self) { + let row_count_below = self.lines_below.len(); + for _ in 0..row_count_below { + self.scroll_down_one_line(); + } + } + pub fn rotate_scroll_region_up(&mut self, _count: usize) { + // TBD + } + pub fn rotate_scroll_region_down(&mut self, _count: usize) { + // TBD + } + pub fn add_canonical_line(&mut self) { + if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { + if self.cursor.y == scroll_region_bottom { + // end of scroll region + // when we have a scroll region set and we're at its bottom + // we need to delete its first line, thus shifting all lines in it upwards + // then we add an empty line at its end which will be filled by the application + // controlling the scroll region (presumably filled by whatever comes next in the + // scroll buffer, but that's not something we control) + self.viewport.remove(scroll_region_top); + self.viewport + .insert(scroll_region_bottom, Row::new().canonical()); + return; + } + } + if self.viewport.len() <= self.cursor.y + 1 { + let new_row = Row::new().canonical(); + self.viewport.push(new_row); + } + if self.cursor.y == self.height - 1 { + let row_count_to_transfer = 1; + transfer_rows_up( + &mut self.viewport, + &mut self.lines_above, + row_count_to_transfer, + Some(self.width), + None, + ); + } else { + self.cursor.y += 1; + } + } + pub fn move_cursor_to_beginning_of_line(&mut self) { + self.cursor.x = 0; + } + pub fn move_cursor_backwards(&mut self, count: usize) { + if self.cursor.x > count { + self.cursor.x -= count; + } else { + self.cursor.x = 0; + } + } + pub fn insert_character_at_cursor_position(&mut self, terminal_character: TerminalCharacter) { + match self.viewport.get_mut(self.cursor.y) { + Some(row) => row.add_character_at(terminal_character, self.cursor.x), + None => { + // pad lines until cursor if they do not exist + for _ in self.viewport.len()..self.cursor.y { + self.viewport.push(Row::new().canonical()); + } + self.viewport + .push(Row::new().with_character(terminal_character).canonical()); + } + } + } + pub fn add_character(&mut self, terminal_character: TerminalCharacter) { + // TODO: try to separate adding characters from moving the cursors in this function + if self.cursor.x < self.width { + self.insert_character_at_cursor_position(terminal_character); + } else { + // line wrap + self.cursor.x = 0; + if self.cursor.y == self.height - 1 { + let row_count_to_transfer = 1; + transfer_rows_up( + &mut self.viewport, + &mut self.lines_above, + row_count_to_transfer, + Some(self.width), + None, + ); + let wrapped_row = Row::new(); + self.viewport.push(wrapped_row); + } else { + self.cursor.y += 1; + if self.viewport.len() <= self.cursor.y { + let line_wrapped_row = Row::new(); + self.viewport.push(line_wrapped_row); + } + } + self.insert_character_at_cursor_position(terminal_character); + } + self.move_cursor_forward_until_edge(1); + } + pub fn move_cursor_forward_until_edge(&mut self, count: usize) { + let count_to_move = std::cmp::min(count, self.width - (self.cursor.x)); + self.cursor.x += count_to_move; + } + pub fn replace_characters_in_line_after_cursor(&mut self, replace_with: TerminalCharacter) { + self.viewport + .get_mut(self.cursor.y) + .unwrap() + .truncate(self.cursor.x); + if self.cursor.x < self.width - 1 { + let mut characters_to_append = vec![replace_with; self.width - self.cursor.x]; + self.viewport + .get_mut(self.cursor.y) + .unwrap() + .append(&mut characters_to_append); + } + } + pub fn replace_characters_in_line_before_cursor(&mut self, replace_with: TerminalCharacter) { + let line_part = vec![replace_with; self.cursor.x]; + let row = self.viewport.get_mut(self.cursor.y).unwrap(); + row.replace_beginning_with(line_part); + } + pub fn clear_all_after_cursor(&mut self, replace_with: TerminalCharacter) { + let cursor_row = self.viewport.get_mut(self.cursor.y).unwrap(); + cursor_row.truncate(self.cursor.x); + let mut replace_with_columns_in_cursor_row = vec![replace_with; self.width - self.cursor.x]; + cursor_row.append(&mut replace_with_columns_in_cursor_row); + + let replace_with_columns = vec![replace_with; self.width]; + self.replace_characters_in_line_after_cursor(replace_with); + for row in self.viewport.iter_mut().skip(self.cursor.y + 1) { + row.replace_columns(replace_with_columns.clone()); + } + } + pub fn clear_cursor_line(&mut self) { + self.viewport.get_mut(self.cursor.y).unwrap().truncate(0); + } + pub fn clear_all(&mut self, replace_with: TerminalCharacter) { + let replace_with_columns = vec![replace_with; self.width]; + self.replace_characters_in_line_after_cursor(replace_with); + for row in self.viewport.iter_mut() { + row.replace_columns(replace_with_columns.clone()); + } + } + fn pad_current_line_until(&mut self, position: usize) { + let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); + for _ in current_row.len()..position { + current_row.push(EMPTY_TERMINAL_CHARACTER); + } + } + fn pad_lines_until(&mut self, position: usize) { + for _ in self.viewport.len()..position { + self.viewport.push(Row::new().canonical()); + } + } + pub fn move_cursor_to(&mut self, x: usize, y: usize) { + self.cursor.x = x; + self.cursor.y = y; + self.pad_lines_until(self.cursor.y + 1); + self.pad_current_line_until(self.cursor.x); + } + pub fn move_cursor_up(&mut self, count: usize) { + self.cursor.y = if self.cursor.y < count { + 0 + } else { + self.cursor.y - count + }; + } + pub fn move_cursor_up_with_scrolling(&mut self, count: usize) { + let (scroll_region_top, scroll_region_bottom) = + self.scroll_region.unwrap_or((0, self.height - 1)); + for _ in 0..count { + let current_line_index = self.cursor.y; + if current_line_index == scroll_region_top { + // if we're at the top line, we create a new line and remove the last line that + // would otherwise overflow + self.viewport.remove(scroll_region_bottom); + self.viewport.insert(current_line_index, Row::new()); // TODO: .canonical() ? + } else if current_line_index > scroll_region_top + && current_line_index <= scroll_region_bottom + { + self.move_cursor_up(count); + } + } + } + pub fn move_cursor_down(&mut self, count: usize) { + let lines_to_add = if self.cursor.y + count > self.height - 1 { + (self.cursor.y + count) - (self.height - 1) + } else { + 0 + }; + self.cursor.y = if self.cursor.y + count > self.height - 1 { + self.height - 1 + } else { + self.cursor.y + count + }; + for _ in 0..lines_to_add { + self.add_canonical_line(); + } + self.pad_lines_until(self.cursor.y); + } + pub fn move_cursor_back(&mut self, count: usize) { + if self.cursor.x < count { + self.cursor.x = 0; + } else { + self.cursor.x -= count; + } + } + pub fn hide_cursor(&mut self) { + self.cursor.is_hidden = true; + } + pub fn show_cursor(&mut self) { + self.cursor.is_hidden = false; + } + pub fn set_scroll_region(&mut self, top_line_index: usize, bottom_line_index: usize) { + self.scroll_region = Some((top_line_index, bottom_line_index)); + } + pub fn clear_scroll_region(&mut self) { + self.scroll_region = None; + } + pub fn set_scroll_region_to_viewport_size(&mut self) { + self.scroll_region = Some((0, self.height - 1)); + } + pub fn delete_lines_in_scroll_region(&mut self, count: usize) { + if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { + let current_line_index = self.cursor.y; + if current_line_index >= scroll_region_top && current_line_index <= scroll_region_bottom + { + // when deleting lines inside the scroll region, we must make sure it stays the + // same size (and that other lines below it aren't shifted inside it) + // so we delete the current line(s) and add an empty line at the end of the scroll + // region + for _ in 0..count { + self.viewport.remove(current_line_index); + self.viewport + .insert(scroll_region_bottom, Row::new().canonical()); + } + } + } + } + pub fn add_empty_lines_in_scroll_region(&mut self, count: usize) { + if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { + let current_line_index = self.cursor.y; + if current_line_index >= scroll_region_top && current_line_index <= scroll_region_bottom + { + // when adding empty lines inside the scroll region, we must make sure it stays the + // same size and that lines don't "leak" outside of it + // so we add an empty line where the cursor currently is, and delete the last line + // of the scroll region + for _ in 0..count { + self.viewport.remove(scroll_region_bottom); + self.viewport + .insert(current_line_index, Row::new().canonical()); + } + } + } + } + pub fn move_cursor_to_column(&mut self, column: usize) { + self.cursor.x = column; + self.pad_current_line_until(self.cursor.x); + } + pub fn move_cursor_to_line(&mut self, line: usize) { + self.cursor.y = line; + self.pad_lines_until(self.cursor.y + 1); + self.pad_current_line_until(self.cursor.x); + } + pub fn replace_with_empty_chars(&mut self, count: usize, empty_char_style: CharacterStyles) { + let mut empty_character = EMPTY_TERMINAL_CHARACTER; + empty_character.styles = empty_char_style; + let pad_until = std::cmp::min(self.width, self.cursor.x + count); + self.pad_current_line_until(pad_until); + let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); + for i in 0..count { + current_row.replace_character_at(empty_character, self.cursor.x + i); + } + } + pub fn erase_characters(&mut self, count: usize, empty_char_style: CharacterStyles) { + let mut empty_character = EMPTY_TERMINAL_CHARACTER; + empty_character.styles = empty_char_style; + let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); + for _ in 0..count { + current_row.delete_character(self.cursor.x); + } + let mut empty_space_to_append = vec![empty_character; count]; + self.viewport + .get_mut(self.cursor.y) + .unwrap() + .append(&mut empty_space_to_append); + } +} + +#[derive(Clone)] +pub struct Row { + pub columns: Vec<TerminalCharacter>, + pub is_canonical: bool, +} + +impl Debug for Row { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + for character in &self.columns { + write!(f, "{:?}", character)?; + } + Ok(()) + } +} + +impl Row { + pub fn new() -> Self { + Row { + columns: vec![], + is_canonical: false, + } + } + pub fn from_columns(columns: Vec<TerminalCharacter>) -> Self { + Row { + columns, + is_canonical: false, + } + } + pub fn from_rows(mut rows: Vec<Row>) -> Self { + if rows.is_empty() { + Row::new() + } else { + let mut first_row = rows.remove(0); + for row in rows.iter_mut() { + first_row.append(&mut row.columns); + } + first_row + } + } + pub fn with_character(mut self, terminal_character: TerminalCharacter) -> Self { + self.columns.push(terminal_character); + self + } + pub fn canonical(mut self) -> Self { + self.is_canonical = true; + self + } + pub fn add_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) { + match self.columns.len().cmp(&x) { + Ordering::Equal => self.columns.push(terminal_character), + Ordering::Less => { + self.columns.resize(x, EMPTY_TERMINAL_CHARACTER); + self.columns.push(terminal_character); + } + Ordering::Greater => { + // this is much more performant than remove/insert + self.columns.push(terminal_character); + self.columns.swap_remove(x); + } + } + } + pub fn replace_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) { + // this is much more performant than remove/insert + self.columns.push(terminal_character); + self.columns.swap_remove(x); + } + pub fn replace_columns(&mut self, columns: Vec<TerminalCharacter>) { + self.columns = columns; + } + pub fn push(&mut self, terminal_character: TerminalCharacter) { + self.columns.push(terminal_character); + } + pub fn truncate(&mut self, x: usize) { + self.columns.truncate(x); + } + pub fn append(&mut self, to_append: &mut Vec<TerminalCharacter>) { + self.columns.append(to_append); + } + pub fn replace_beginning_with(&mut self, mut line_part: Vec<TerminalCharacter>) { + drop(self.columns.drain(0..line_part.len())); + line_part.append(&mut self.columns); + self.columns = line_part; + } + pub fn len(&self) -> usize { + self.columns.len() + } + pub fn delete_character(&mut self, x: usize) { + self.columns.remove(x); + } + pub fn split_to_rows_of_length(&mut self, max_row_length: usize) -> Vec<Row> { + let mut parts: Vec<Row> = vec![]; + let mut current_part: Vec<TerminalCharacter> = vec![]; + for character in self.columns.drain(..) { + if current_part.len() == max_row_length { + parts.push(Row::from_columns(current_part)); + current_part = vec![]; + } + current_part.push(character); + } + if !current_part.is_empty() { + parts.push(Row::from_columns(current_part)) + }; + if !parts.is_empty() && self.is_canonical { + parts.get_mut(0).unwrap().is_canonical = true; + } + parts + } +} + +#[derive(Clone, Debug)] +pub struct Cursor { + x: usize, + y: usize, + is_hidden: bool, +} + +impl Cursor { + pub fn new(x: usize, y: usize) -> Self { + Cursor { + x, + y, + is_hidden: false, + } + } +} diff --git a/src/client/panes/mod.rs b/src/client/panes/mod.rs new file mode 100644 index 00000000..4e7d6e80 --- /dev/null +++ b/src/client/panes/mod.rs @@ -0,0 +1,9 @@ +mod grid; +mod plugin_pane; +mod terminal_character; +mod terminal_pane; + +pub use grid::*; +pub use plugin_pane::*; +pub use terminal_character::*; +pub use terminal_pane::*; diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs new file mode 100644 index 00000000..588cffd6 --- /dev/null +++ b/src/client/panes/plugin_pane.rs @@ -0,0 +1,191 @@ +#![allow(clippy::clippy::if_same_then_else)] + +use crate::{common::SenderWithContext, pty_bus::VteEvent, tab::Pane, wasm_vm::PluginInstruction}; + +use std::{sync::mpsc::channel, unimplemented}; + +use crate::panes::{PaneId, PositionAndSize}; + +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<PositionAndSize>, + pub send_plugin_instructions: SenderWithContext<PluginInstruction>, + pub max_height: Option<usize>, +} + +impl PluginPane { + pub fn new( + pid: u32, + position_and_size: PositionAndSize, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + ) -> Self { + Self { + pid, + should_render: true, + selectable: true, + invisible_borders: false, + position_and_size, + position_and_size_override: None, + send_plugin_instructions, + max_height: None, + } + } +} + +impl Pane for PluginPane { + // FIXME: These position and size things should all be moved to default trait implementations, + // with something like a get_pos_and_sz() method underpinning all of them. Alternatively and + // preferably, just use an enum and not a trait object + fn x(&self) -> usize { + self.position_and_size_override + .unwrap_or(self.position_and_size) + .x + } + fn y(&self) -> usize { + self.position_and_size_override + .unwrap_or(self.position_and_size) + .y + } + fn rows(&self) -> usize { + self.position_and_size_override + .unwrap_or(self.position_and_size) + .rows + } + fn columns(&self) -> usize { + self.position_and_size_override + .unwrap_or(self.position_and_size) + .columns + } + fn reset_size_and_position_override(&mut self) { + self.position_and_size_override = None; + self.should_render = true; + } + fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) { + self.position_and_size = *position_and_size; + self.should_render = true; + } + // FIXME: This is obviously a bit outdated and needs the x and y moved into `size` + fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) { + let position_and_size_override = PositionAndSize { + x, + y, + rows: size.rows, + columns: size.columns, + }; + self.position_and_size_override = Some(position_and_size_override); + self.should_render = true; + } + fn handle_event(&mut self, _event: VteEvent) { + unimplemented!() + } + fn cursor_coordinates(&self) -> Option<(usize, usize)> { + None + } + fn adjust_input_to_terminal(&self, _input_bytes: Vec<u8>) -> Vec<u8> { + unimplemented!() // FIXME: Shouldn't need this implmented? + } + + fn position_and_size_override(&self) -> Option<PositionAndSize> { + self.position_and_size_override + } + fn should_render(&self) -> bool { + self.should_render + } + fn set_should_render(&mut self, should_render: bool) { + self.should_render = should_render; + } + fn selectable(&self) -> bool { + self.selectable + } + 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); + } + fn render(&mut self) -> Option<String> { + // if self.should_render { + if true { + // while checking should_render rather than rendering each pane every time + // is more performant, it causes some problems when the pane to the left should be + // rendered and has wide characters (eg. Chinese characters or emoji) + // as a (hopefully) temporary hack, we render all panes until we find a better solution + let (buf_tx, buf_rx) = channel(); + + self.send_plugin_instructions + .send(PluginInstruction::Draw( + buf_tx, + self.pid, + self.rows(), + self.columns(), + )) + .unwrap(); + + self.should_render = false; + Some(buf_rx.recv().unwrap()) + } else { + None + } + } + fn pid(&self) -> PaneId { + PaneId::Plugin(self.pid) + } + fn reduce_height_down(&mut self, count: usize) { + self.position_and_size.y += count; + self.position_and_size.rows -= count; + self.should_render = true; + } + fn increase_height_down(&mut self, count: usize) { + self.position_and_size.rows += count; + self.should_render = true; + } + fn increase_height_up(&mut self, count: usize) { + self.position_and_size.y -= count; + self.position_and_size.rows += count; + self.should_render = true; + } + fn reduce_height_up(&mut self, count: usize) { + self.position_and_size.rows -= count; + self.should_render = true; + } + fn reduce_width_right(&mut self, count: usize) { + self.position_and_size.x += count; + self.position_and_size.columns -= count; + self.should_render = true; + } + fn reduce_width_left(&mut self, count: usize) { + self.position_and_size.columns -= count; + self.should_render = true; + } + fn increase_width_left(&mut self, count: usize) { + self.position_and_size.x -= count; + self.position_and_size.columns += count; + self.should_render = true; + } + fn increase_width_right(&mut self, count: usize) { + self.position_and_size.columns += count; + self.should_render = true; + } + fn scroll_up(&mut self, _count: usize) { + unimplemented!() + } + fn scroll_down(&mut self, _count: usize) { + unimplemented!() + } + fn clear_scroll(&mut self) { + unimplemented!() + } + fn max_height(&self) -> Option<usize> { + self.max_height + } + fn invisible_borders(&self) -> bool { + self.invisible_borders + } +} diff --git a/src/client/panes/terminal_character.rs b/src/client/panes/terminal_character.rs new file mode 100644 index 00000000..80c3162b --- /dev/null +++ b/src/client/panes/terminal_character.rs @@ -0,0 +1,572 @@ +use crate::utils::logging::debug_log_to_file; +use ::std::fmt::{self, Debug, Display, Formatter}; + +pub const EMPTY_TERMINAL_CHARACTER: TerminalCharacter = TerminalCharacter { + character: ' ', + styles: CharacterStyles { + foreground: Some(AnsiCode::Reset), + background: Some(AnsiCode::Reset), + strike: Some(AnsiCode::Reset), + hidden: Some(AnsiCode::Reset), + reverse: Some(AnsiCode::Reset), + slow_blink: Some(AnsiCode::Reset), + fast_blink: Some(AnsiCode::Reset), + underline: Some(AnsiCode::Reset), + bold: Some(AnsiCode::Reset), + dim: Some(AnsiCode::Reset), + italic: Some(AnsiCode::Reset), + }, +}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AnsiCode { + On, + Reset, + NamedColor(NamedColor), + RGBCode((u8, u8, u8)), + ColorIndex(u8), +} + +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum NamedColor { + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + White, +} + +impl NamedColor { + fn to_foreground_ansi_code(&self) -> String { + match self { + NamedColor::Black => format!("{}", 30), + NamedColor::Red => format!("{}", 31), + NamedColor::Green => format!("{}", 32), + NamedColor::Yellow => format!("{}", 33), + NamedColor::Blue => format!("{}", 34), + NamedColor::Magenta => format!("{}", 35), + NamedColor::Cyan => format!("{}", 36), + NamedColor::White => format!("{}", 37), + } + } + fn to_background_ansi_code(&self) -> String { + match self { + NamedColor::Black => format!("{}", 40), + NamedColor::Red => format!("{}", 41), + NamedColor::Green => format!("{}", 42), + NamedColor::Yellow => format!("{}", 43), + NamedColor::Blue => format!("{}", 44), + NamedColor::Magenta => format!("{}", 45), + NamedColor::Cyan => format!("{}", 46), + NamedColor::White => format!("{}", 47), + } + } +} + +#[derive(Clone, Copy, Debug)] +pub struct CharacterStyles { + pub foreground: Option<AnsiCode>, + pub background: Option<AnsiCode>, + pub strike: Option<AnsiCode>, + pub hidden: Option<AnsiCode>, + pub reverse: Option<AnsiCode>, + pub slow_blink: Option<AnsiCode>, + pub fast_blink: Option<AnsiCode>, + pub underline: Option<AnsiCode>, + pub bold: Option<AnsiCode>, + pub dim: Option<AnsiCode>, + pub italic: Option<AnsiCode>, +} + +impl CharacterStyles { + pub fn new() -> Self { + CharacterStyles { + foreground: None, + background: None, + strike: None, + hidden: None, + reverse: None, + slow_blink: None, + fast_blink: None, + underline: None, + bold: None, + dim: None, + italic: None, + } + } + pub fn foreground(mut self, foreground_code: Option<AnsiCode>) -> Self { + self.foreground = foreground_code; + self + } + pub fn background(mut self, background_code: Option<AnsiCode>) -> Self { + self.background = background_code; + self + } + pub fn bold(mut self, bold_code: Option<AnsiCode>) -> Self { + self.bold = bold_code; + self + } + pub fn dim(mut self, dim_code: Option<AnsiCode>) -> Self { + self.dim = dim_code; + self + } + pub fn italic(mut self, italic_code: Option<AnsiCode>) -> Self { + self.italic = italic_code; + self + } + pub fn underline(mut self, underline_code: Option<AnsiCode>) -> Self { + self.underline = underline_code; + self + } + pub fn blink_slow(mut self, slow_blink_code: Option<AnsiCode>) -> Self { + self.slow_blink = slow_blink_code; + self + } + pub fn blink_fast(mut self, fast_blink_code: Option<AnsiCode>) -> Self { + self.fast_blink = fast_blink_code; + self + } + pub fn reverse(mut self, reverse_code: Option<AnsiCode>) -> Self { + self.reverse = reverse_code; + self + } + pub fn hidden(mut self, hidden_code: Option<AnsiCode>) -> Self { + self.hidden = hidden_code; + self + } + pub fn strike(mut self, strike_code: Option<AnsiCode>) -> Self { + self.strike = strike_code; + self + } + pub fn clear(&mut self) { + self.foreground = None; + self.background = None; + self.strike = None; + self.hidden = None; + self.reverse = None; + self.slow_blink = None; + self.fast_blink = None; + self.underline = None; + self.bold = None; + self.dim = None; + self.italic = None; + } + pub fn update_and_return_diff( + &mut self, + new_styles: &CharacterStyles, + ) -> Option<CharacterStyles> { + let mut diff: Option<CharacterStyles> = None; + + if new_styles.foreground == Some(AnsiCode::Reset) + && new_styles.background == Some(AnsiCode::Reset) + && new_styles.strike == Some(AnsiCode::Reset) + && new_styles.hidden == Some(AnsiCode::Reset) + && new_styles.reverse == Some(AnsiCode::Reset) + && new_styles.fast_blink == Some(AnsiCode::Reset) + && new_styles.slow_blink == Some(AnsiCode::Reset) + && new_styles.underline == Some(AnsiCode::Reset) + && new_styles.bold == Some(AnsiCode::Reset) + && new_styles.dim == Some(AnsiCode::Reset) + && new_styles.italic == Some(AnsiCode::Reset) + { + self.foreground = Some(AnsiCode::Reset); + self.background = Some(AnsiCode::Reset); + self.strike = Some(AnsiCode::Reset); + self.hidden = Some(AnsiCode::Reset); + self.reverse = Some(AnsiCode::Reset); + self.fast_blink = Some(AnsiCode::Reset); + self.slow_blink = Some(AnsiCode::Reset); + self.underline = Some(AnsiCode::Reset); + self.bold = Some(AnsiCode::Reset); + self.dim = Some(AnsiCode::Reset); + self.italic = Some(AnsiCode::Reset); + return Some(*new_styles); + }; + + if self.foreground != new_styles.foreground { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.foreground(new_styles.foreground)); + self.foreground = new_styles.foreground; + } else { + diff = Some(CharacterStyles::new().foreground(new_styles.foreground)); + self.foreground = new_styles.foreground; + } + } + if self.background != new_styles.background { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.background(new_styles.background)); + self.background = new_styles.background; + } else { + diff = Some(CharacterStyles::new().background(new_styles.background)); + self.background = new_styles.background; + } + } + if self.strike != new_styles.strike { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.strike(new_styles.strike)); + self.strike = new_styles.strike; + } else { + diff = Some(CharacterStyles::new().strike(new_styles.strike)); + self.strike = new_styles.strike; + } + } + if self.hidden != new_styles.hidden { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.hidden(new_styles.hidden)); + self.hidden = new_styles.hidden; + } else { + diff = Some(CharacterStyles::new().hidden(new_styles.hidden)); + self.hidden = new_styles.hidden; + } + } + if self.reverse != new_styles.reverse { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.reverse(new_styles.reverse)); + self.reverse = new_styles.reverse; + } else { + diff = Some(CharacterStyles::new().reverse(new_styles.reverse)); + self.reverse = new_styles.reverse; + } + } + if self.slow_blink != new_styles.slow_blink { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.blink_slow(new_styles.slow_blink)); + self.slow_blink = new_styles.slow_blink; + } else { + diff = Some(CharacterStyles::new().blink_slow(new_styles.slow_blink)); + self.slow_blink = new_styles.slow_blink; + } + } + if self.fast_blink != new_styles.fast_blink { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.blink_fast(new_styles.fast_blink)); + self.fast_blink = new_styles.fast_blink; + } else { + diff = Some(CharacterStyles::new().blink_fast(new_styles.fast_blink)); + self.fast_blink = new_styles.fast_blink; + } + } + if self.underline != new_styles.underline { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.underline(new_styles.underline)); + self.underline = new_styles.underline; + } else { + diff = Some(CharacterStyles::new().underline(new_styles.underline)); + self.underline = new_styles.underline; + } + } + if self.bold != new_styles.bold { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.bold(new_styles.bold)); + self.bold = new_styles.bold; + } else { + diff = Some(CharacterStyles::new().bold(new_styles.bold)); + self.bold = new_styles.bold; + } + } + if self.dim != new_styles.dim { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.dim(new_styles.dim)); + self.dim = new_styles.dim; + } else { + diff = Some(CharacterStyles::new().dim(new_styles.dim)); + self.dim = new_styles.dim; + } + } + if self.italic != new_styles.italic { + if let Some(new_diff) = diff.as_mut() { + diff = Some(new_diff.italic(new_styles.italic)); + self.italic = new_styles.italic; + } else { + diff = Some(CharacterStyles::new().italic(new_styles.italic)); + self.italic = new_styles.italic; + } + } + diff + } + pub fn reset_all(&mut self) { + self.foreground = Some(AnsiCode::Reset); + self.background = Some(AnsiCode::Reset); + self.bold = Some(AnsiCode::Reset); + self.dim = Some(AnsiCode::Reset); + self.italic = Some(AnsiCode::Reset); + self.underline = Some(AnsiCode::Reset); + self.slow_blink = Some(AnsiCode::Reset); + self.fast_blink = Some(AnsiCode::Reset); + self.reverse = Some(AnsiCode::Reset); + self.hidden = Some(AnsiCode::Reset); + self.strike = Some(AnsiCode::Reset); + } + pub fn add_style_from_ansi_params(&mut self, ansi_params: &[i64]) { + let mut params_used = 1; // if there's a parameter, it is always used + match ansi_params { + [] | [0, ..] => self.reset_all(), + [1, ..] => *self = self.bold(Some(AnsiCode::On)), + [2, ..] => *self = self.dim(Some(AnsiCode::On)), + [3, ..] => *self = self.italic(Some(AnsiCode::On)), + [4, ..] => *self = self.underline(Some(AnsiCode::On)), + [5, ..] => *self = self.blink_slow(Some(AnsiCode::On)), + [6, ..] => *self = self.blink_fast(Some(AnsiCode::On)), + [7, ..] => *self = self.reverse(Some(AnsiCode::On)), + [8, ..] => *self = self.hidden(Some(AnsiCode::On)), + [9, ..] => *self = self.strike(Some(AnsiCode::On)), + [21, ..] => *self = self.bold(Some(AnsiCode::Reset)), + [22, ..] => { + *self = self.bold(Some(AnsiCode::Reset)); + *self = self.dim(Some(AnsiCode::Reset)); + } + [23, ..] => *self = self.italic(Some(AnsiCode::Reset)), + [24, ..] => *self = self.underline(Some(AnsiCode::Reset)), + [25, ..] => { + *self = self.blink_slow(Some(AnsiCode::Reset)); + *self = self.blink_fast(Some(AnsiCode::Reset)); + } + [27, ..] => *self = self.reverse(Some(AnsiCode::Reset)), + [28, ..] => *self = self.hidden(Some(AnsiCode::Reset)), + [29, ..] => *self = self.strike(Some(AnsiCode::Reset)), + [30, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Black))), + [31, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Red))), + [32, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Green))), + [33, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Yellow))), + [34, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Blue))), + [35, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Magenta))), + [36, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::Cyan))), + [37, ..] => *self = self.foreground(Some(AnsiCode::NamedColor(NamedColor::White))), + [38, 2, ..] => { + let ansi_code = AnsiCode::RGBCode(( + *ansi_params.get(2).unwrap() as u8, + *ansi_params.get(3).unwrap() as u8, + *ansi_params.get(4).unwrap() as u8, + )); + *self = self.foreground(Some(ansi_code)); + params_used += 4 // one for the indicator (2 in this case) and three for the rgb code + } + [38, 5, ..] => { + let ansi_code = AnsiCode::ColorIndex(*ansi_params.get(2).unwrap() as u8); + *self = self.foreground(Some(ansi_code)); + params_used += 2 // one for the indicator (5 in this case) and one for the color index + } + [38, ..] => { + // this is a bug + // it means we got a color encoding we don't know how to handle (or is invalid) + params_used += 1; // even if it's a bug, let's not create an endless loop, eh? + } + [39, ..] => *self = self.foreground(Some(AnsiCode::Reset)), + [40, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Black))), + [41, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Red))), + [42, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Green))), + [43, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Yellow))), + [44, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Blue))), + [45, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Magenta))), + [46, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::Cyan))), + [47, ..] => *self = self.background(Some(AnsiCode::NamedColor(NamedColor::White))), + [48, 2, ..] => { + let ansi_code = AnsiCode::RGBCode(( + *ansi_params.get(2).unwrap() as u8, + *ansi_params.get(3).unwrap() as u8, + *ansi_params.get(4).unwrap() as u8, + )); + *self = self.background(Some(ansi_code)); + params_used += 4 // one for the indicator (2 in this case) and three for the rgb code + } + [48, 5, ..] => { + let ansi_code = AnsiCode::ColorIndex(*ansi_params.get(2).unwrap() as u8); + *self = self.background(Some(ansi_code)); + params_used += 2 // one for the indicator (5 in this case) and one for the color index + } + [48, ..] => { + // this is a bug + // it means we got a color encoding we don't know how to handle (or is invalid) + params_used += 1; // even if it's a bug, let's not create an endless loop, eh? + } + [49, ..] => *self = self.background(Some(AnsiCode::Reset)), + _ => { + // if this happens, it's a bug + let _ = debug_log_to_file(format!("unhandled csi m code {:?}", ansi_params)); + return; + } + } + if let Some(next_params) = ansi_params.get(params_used..) { + if !next_params.is_empty() { + self.add_style_from_ansi_params(next_params); + } + } + } +} + +impl Display for CharacterStyles { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if self.foreground == Some(AnsiCode::Reset) + && self.background == Some(AnsiCode::Reset) + && self.strike == Some(AnsiCode::Reset) + && self.hidden == Some(AnsiCode::Reset) + && self.reverse == Some(AnsiCode::Reset) + && self.fast_blink == Some(AnsiCode::Reset) + && self.slow_blink == Some(AnsiCode::Reset) + && self.underline == Some(AnsiCode::Reset) + && self.bold == Some(AnsiCode::Reset) + && self.dim == Some(AnsiCode::Reset) + && self.italic == Some(AnsiCode::Reset) + { + write!(f, "\u{1b}[m")?; // reset all + return Ok(()); + } + if let Some(ansi_code) = self.foreground { + match ansi_code { + AnsiCode::RGBCode((r, g, b)) => { + write!(f, "\u{1b}[38;2;{};{};{}m", r, g, b)?; + } + AnsiCode::ColorIndex(color_index) => { + write!(f, "\u{1b}[38;5;{}m", color_index)?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[39m")?; + } + AnsiCode::NamedColor(named_color) => { + write!(f, "\u{1b}[{}m", named_color.to_foreground_ansi_code())?; + } + _ => {} + } + }; + if let Some(ansi_code) = self.background { + match ansi_code { + AnsiCode::RGBCode((r, g, b)) => { + write!(f, "\u{1b}[48;2;{};{};{}m", r, g, b)?; + } + AnsiCode::ColorIndex(color_index) => { + write!(f, "\u{1b}[48;5;{}m", color_index)?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[49m")?; + } + AnsiCode::NamedColor(named_color) => { + write!(f, "\u{1b}[{}m", named_color.to_background_ansi_code())?; + } + _ => {} + } + } + if let Some(ansi_code) = self.strike { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[9m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[29m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.hidden { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[8m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[28m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.reverse { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[7m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[27m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.fast_blink { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[6m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[25m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.slow_blink { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[5m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[25m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.bold { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[1m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[22m\u{1b}[24m")?; + // TODO: this cancels bold + underline, if this behaviour is indeed correct, we + // need to properly handle it in the struct methods etc like dim + } + _ => {} + } + } + // notice the order is important here, bold must be before underline + // because the bold reset also resets underline, and would override it + // otherwise + if let Some(ansi_code) = self.underline { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[4m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[24m")?; + } + _ => {} + } + } + if let Some(ansi_code) = self.dim { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[2m")?; + } + AnsiCode::Reset => { + if let Some(AnsiCode::Reset) = self.bold { + // we only reset dim if both dim and bold should be reset + write!(f, "\u{1b}[22m")?; + } + } + _ => {} + } + } + if let Some(ansi_code) = self.italic { + match ansi_code { + AnsiCode::On => { + write!(f, "\u{1b}[3m")?; + } + AnsiCode::Reset => { + write!(f, "\u{1b}[23m")?; + } + _ => {} + } + }; + Ok(()) + } +} + +#[derive(Clone, Copy)] +pub struct TerminalCharacter { + pub character: char, + pub styles: CharacterStyles, +} + +impl ::std::fmt::Debug for TerminalCharacter { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.character) + } +} diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs new file mode 100644 index 00000000..21244fab --- /dev/null +++ b/src/client/panes/terminal_pane.rs @@ -0,0 +1,675 @@ +#![allow(clippy::clippy::if_same_then_else)] + +use crate::tab::Pane; +use ::nix::pty::Winsize; +use ::std::os::unix::io::RawFd; +use ::vte::Perform; +use std::fmt::Debug; + +use crate::panes::grid::Grid; +use crate::panes::terminal_character::{ + CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, +}; +use crate::utils::logging::debug_log_to_file; +use crate::VteEvent; + +#[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy, Debug)] +pub enum PaneId { + Terminal(RawFd), + Plugin(u32), // FIXME: Drop the trait object, make this a wrapper for the struct? +} +#[derive(Clone, Copy, Debug, Default)] +pub struct PositionAndSize { + pub x: usize, + pub y: usize, + pub rows: usize, + pub columns: usize, +} + +impl From<Winsize> for PositionAndSize { + fn from(winsize: Winsize) -> PositionAndSize { + PositionAndSize { + columns: winsize.ws_col as usize, + rows: winsize.ws_row as usize, + ..Default::default() + } + } +} + +#[derive(Debug)] +pub struct TerminalPane { + pub grid: Grid, + pub alternative_grid: Option<Grid>, // for 1049h/l instructions which tell us to switch between these two + pub pid: RawFd, + pub should_render: bool, + pub selectable: bool, + pub position_and_size: PositionAndSize, + pub position_and_size_override: Option<PositionAndSize>, + pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "[D") + pub max_height: Option<usize>, + pending_styles: CharacterStyles, + clear_viewport_before_rendering: bool, +} + +impl Pane for TerminalPane { + fn x(&self) -> usize { + self.get_x() + } + fn y(&self) -> usize { + self.get_y() + } + fn rows(&self) -> usize { + self.get_rows() + } + fn columns(&self) -> usize { + self.get_columns() + } + fn reset_size_and_position_override(&mut self) { + self.position_and_size_override = None; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) { + self.position_and_size.columns = position_and_size.columns; + self.position_and_size.rows = position_and_size.rows; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) { + let position_and_size_override = PositionAndSize { + x, + y, + rows: size.rows, + columns: size.columns, + }; + self.position_and_size_override = Some(position_and_size_override); + self.reflow_lines(); + self.mark_for_rerender(); + } + fn handle_event(&mut self, event: VteEvent) { + match event { + VteEvent::Print(c) => { + self.print(c); + self.mark_for_rerender(); + } + VteEvent::Execute(byte) => { + self.execute(byte); + } + VteEvent::Hook(params, intermediates, ignore, c) => { + self.hook(¶ms, &intermediates, ignore, c); + } + VteEvent::Put(byte) => { + self.put(byte); + } + VteEvent::Unhook => { + self.unhook(); + } + VteEvent::OscDispatch(params, bell_terminated) => { + let params: Vec<&[u8]> = params.iter().map(|p| &p[..]).collect(); + self.osc_dispatch(¶ms[..], bell_terminated); + } + VteEvent::CsiDispatch(params, intermediates, ignore, c) => { + self.csi_dispatch(¶ms, &intermediates, ignore, c); + } + VteEvent::EscDispatch(intermediates, ignore, byte) => { + self.esc_dispatch(&intermediates, ignore, byte); + } + } + } + fn cursor_coordinates(&self) -> Option<(usize, usize)> { + // (x, y) + self.grid.cursor_coordinates() + } + fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8> { + // there are some cases in which the terminal state means that input sent to it + // needs to be adjusted. + // here we match against those cases - if need be, we adjust the input and if not + // we send back the original input + match input_bytes.as_slice() { + [27, 91, 68] => { + // left arrow + if self.cursor_key_mode { + // please note that in the line below, there is an ANSI escape code (27) at the beginning of the string, + // some editors will not show this + return "OD".as_bytes().to_vec(); + } + } + [27, 91, 67] => { + // right arrow + if self.cursor_key_mode { + // please note that in the line below, there is an ANSI escape code (27) at the beginning of the string, + // some editors will not show this + return "OC".as_bytes().to_vec(); + } + } + [27, 91, 65] => { + // up arrow + if self.cursor_key_mode { + // please note that in the line below, there is an ANSI escape code (27) at the beginning of the string, + // some editors will not show this + return "OA".as_bytes().to_vec(); + } + } + [27, 91, 66] => { + // down arrow + if self.cursor_key_mode { + // please note that in the line below, there is an ANSI escape code (27) at the beginning of the string, + // some editors will not show this + return "OB".as_bytes().to_vec(); + } + } + _ => {} + }; + input_bytes + } + + fn position_and_size_override(&self) -> Option<PositionAndSize> { + self.position_and_size_override + } + fn should_render(&self) -> bool { + self.should_render + } + fn set_should_render(&mut self, should_render: bool) { + self.should_render = should_render; + } + fn selectable(&self) -> bool { + self.selectable + } + fn set_selectable(&mut self, selectable: bool) { + self.selectable = selectable; + } + 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<usize> { + self.max_height + } + fn render(&mut self) -> Option<String> { + // if self.should_render { + if true { + // while checking should_render rather than rendering each pane every time + // is more performant, it causes some problems when the pane to the left should be + // rendered and has wide characters (eg. Chinese characters or emoji) + // as a (hopefully) temporary hack, we render all panes until we find a better solution + let mut vte_output = String::new(); + let buffer_lines = &self.read_buffer_as_lines(); + let display_cols = self.get_columns(); + let mut character_styles = CharacterStyles::new(); + if self.clear_viewport_before_rendering { + for line_index in 0..self.grid.height { + let x = self.get_x(); + let y = self.get_y(); + vte_output = format!( + "{}\u{1b}[{};{}H\u{1b}[m", + vte_output, + y + line_index + 1, + x + 1 + ); // goto row/col and reset styles + for _col_index in 0..self.grid.width { + vte_output.push(EMPTY_TERMINAL_CHARACTER.character); + } + } + self.clear_viewport_before_rendering = false; + } + for (row, line) in buffer_lines.iter().enumerate() { + let x = self.get_x(); + let y = self.get_y(); + vte_output = format!("{}\u{1b}[{};{}H\u{1b}[m", vte_output, y + row + 1, x + 1); // goto row/col and reset styles + for (col, t_character) in line.iter().enumerate() { + if col < display_cols { + // in some cases (eg. while resizing) some characters will spill over + // before they are corrected by the shell (for the prompt) or by reflowing + // lines + if let Some(new_styles) = + character_styles.update_and_return_diff(&t_character.styles) + { + // the terminal keeps the previous styles as long as we're in the same + // line, so we only want to update the new styles here (this also + // includes resetting previous styles as needed) + vte_output = format!("{}{}", vte_output, new_styles); + } + vte_output.push(t_character.character); + } + } + character_styles.clear(); + } + self.mark_for_rerender(); + Some(vte_output) + } else { + None + } + } + fn pid(&self) -> PaneId { + PaneId::Terminal(self.pid) + } + fn reduce_height_down(&mut self, count: usize) { + self.position_and_size.y += count; + self.position_and_size.rows -= count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn increase_height_down(&mut self, count: usize) { + self.position_and_size.rows += count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn increase_height_up(&mut self, count: usize) { + self.position_and_size.y -= count; + self.position_and_size.rows += count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn reduce_height_up(&mut self, count: usize) { + self.position_and_size.rows -= count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn reduce_width_right(&mut self, count: usize) { + self.position_and_size.x += count; + self.position_and_size.columns -= count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn reduce_width_left(&mut self, count: usize) { + self.position_and_size.columns -= count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn increase_width_left(&mut self, count: usize) { + self.position_and_size.x -= count; + self.position_and_size.columns += count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn increase_width_right(&mut self, count: usize) { + self.position_and_size.columns += count; + self.reflow_lines(); + self.mark_for_rerender(); + } + fn scroll_up(&mut self, count: usize) { + self.grid.move_viewport_up(count); + self.mark_for_rerender(); + } + fn scroll_down(&mut self, count: usize) { + self.grid.move_viewport_down(count); + self.mark_for_rerender(); + } + fn clear_scroll(&mut self) { + self.grid.reset_viewport(); + self.mark_for_rerender(); + } +} + +impl TerminalPane { + pub fn new(pid: RawFd, position_and_size: PositionAndSize) -> TerminalPane { + let grid = Grid::new(position_and_size.rows, position_and_size.columns); + let pending_styles = CharacterStyles::new(); + + TerminalPane { + pid, + grid, + alternative_grid: None, + should_render: true, + selectable: true, + pending_styles, + position_and_size, + position_and_size_override: None, + cursor_key_mode: false, + clear_viewport_before_rendering: false, + max_height: None, + } + } + pub fn mark_for_rerender(&mut self) { + self.should_render = true; + } + pub fn get_x(&self) -> usize { + match self.position_and_size_override { + Some(position_and_size_override) => position_and_size_override.x, + None => self.position_and_size.x as usize, + } + } + pub fn get_y(&self) -> usize { + match self.position_and_size_override { + Some(position_and_size_override) => position_and_size_override.y, + None => self.position_and_size.y as usize, + } + } + pub fn get_columns(&self) -> usize { + match &self.position_and_size_override.as_ref() { + Some(position_and_size_override) => position_and_size_override.columns, + None => self.position_and_size.columns as usize, + } + } + pub fn get_rows(&self) -> usize { + match &self.position_and_size_override.as_ref() { + Some(position_and_size_override) => position_and_size_override.rows, + None => self.position_and_size.rows as usize, + } + } + fn reflow_lines(&mut self) { + let rows = self.get_rows(); + let columns = self.get_columns(); + self.grid.change_size(rows, columns); + if let Some(alternative_grid) = self.alternative_grid.as_mut() { + alternative_grid.change_size(rows, columns); + } + } + + pub fn read_buffer_as_lines(&self) -> Vec<Vec<TerminalCharacter>> { + self.grid.as_character_lines() + } + #[cfg(test)] + pub fn cursor_coordinates(&self) -> Option<(usize, usize)> { + // (x, y) + self.grid.cursor_coordinates() + } + pub fn rotate_scroll_region_up(&mut self, count: usize) { + self.grid.rotate_scroll_region_up(count); + self.mark_for_rerender(); + } + pub fn rotate_scroll_region_down(&mut self, count: usize) { + self.grid.rotate_scroll_region_down(count); + self.mark_for_rerender(); + } + fn add_newline(&mut self) { + self.grid.add_canonical_line(); + // self.reset_all_ansi_codes(); // TODO: find out if we should be resetting here or not + self.mark_for_rerender(); + } + fn move_to_beginning_of_line(&mut self) { + self.grid.move_cursor_to_beginning_of_line(); + } + fn move_cursor_backwards(&mut self, count: usize) { + self.grid.move_cursor_backwards(count); + } + fn _reset_all_ansi_codes(&mut self) { + self.pending_styles.clear(); + } +} + +impl vte::Perform for TerminalPane { + fn print(&mut self, c: char) { + // apparently, building TerminalCharacter like this without a "new" method + // is a little faster + let terminal_character = TerminalCharacter { + character: c, + styles: self.pending_styles, + }; + self.grid.add_character(terminal_character); + } + + fn execute(&mut self, byte: u8) { + match byte { + 8 => { + // backspace + self.move_cursor_backwards(1); + } + 9 => { + // tab + let terminal_tab_character = TerminalCharacter { + character: '\t', + styles: self.pending_styles, + }; + // TODO: handle better with line wrapping + self.grid.add_character(terminal_tab_character); + } + 10 => { + // 0a, newline + self.add_newline(); + } + 13 => { + // 0d, carriage return + self.move_to_beginning_of_line(); + } + _ => {} + } + } + + fn hook(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) { + // TBD + } + + fn put(&mut self, _byte: u8) { + // TBD + } + + fn unhook(&mut self) { + // TBD + } + + fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) { + // TBD + } + + fn csi_dispatch(&mut self, params: &[i64], _intermediates: &[u8], _ignore: bool, c: char) { + if c == 'm' { + self.pending_styles.add_style_from_ansi_params(params); + } else if c == 'C' { + // move cursor forward + let move_by = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid.move_cursor_forward_until_edge(move_by); + } else if c == 'K' { + // clear line (0 => right, 1 => left, 2 => all) + if params[0] == 0 { + let mut char_to_replace = EMPTY_TERMINAL_CHARACTER; + char_to_replace.styles = self.pending_styles; + self.grid + .replace_characters_in_line_after_cursor(char_to_replace); + } else if params[0] == 1 { + let mut char_to_replace = EMPTY_TERMINAL_CHARACTER; + char_to_replace.styles = self.pending_styles; + self.grid + .replace_characters_in_line_before_cursor(char_to_replace); + } else if params[0] == 2 { + self.grid.clear_cursor_line(); + } + } else if c == 'J' { + // clear all (0 => below, 1 => above, 2 => all, 3 => saved) + let mut char_to_replace = EMPTY_TERMINAL_CHARACTER; + char_to_replace.styles = self.pending_styles; + if params[0] == 0 { + self.grid.clear_all_after_cursor(char_to_replace); + } else if params[0] == 2 { + self.grid.clear_all(char_to_replace); + } + // TODO: implement 1 + } else if c == 'H' { + // goto row/col + // we subtract 1 from the row/column because these are 1 indexed + // (except when they are 0, in which case they should be 1 + // don't look at me, I don't make the rules) + let (row, col) = if params.len() == 1 { + if params[0] == 0 { + (0, params[0] as usize) + } else { + (params[0] as usize - 1, params[0] as usize) + } + } else if params[0] == 0 { + (0, params[1] as usize - 1) + } else { + (params[0] as usize - 1, params[1] as usize - 1) + }; + self.grid.move_cursor_to(col, row); + } else if c == 'A' { + // move cursor up until edge of screen + let move_up_count = if params[0] == 0 { 1 } else { params[0] }; + self.grid.move_cursor_up(move_up_count as usize); + } else if c == 'B' { + // move cursor down until edge of screen + let move_down_count = if params[0] == 0 { 1 } else { params[0] }; + self.grid.move_cursor_down(move_down_count as usize); + } else if c == 'D' { + let move_back_count = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid.move_cursor_back(move_back_count); + } else if c == 'l' { + let first_intermediate_is_questionmark = match _intermediates.get(0) { + Some(b'?') => true, + None => false, + _ => false, + }; + if first_intermediate_is_questionmark { + match params.get(0) { + Some(&1049) => { + if let Some(alternative_grid) = self.alternative_grid.as_mut() { + std::mem::swap(&mut self.grid, alternative_grid); + } + self.alternative_grid = None; + self.clear_viewport_before_rendering = true; + self.mark_for_rerender(); + } + Some(&25) => { + self.grid.hide_cursor(); + self.mark_for_rerender(); + } + Some(&1) => { + self.cursor_key_mode = false; + } + _ => {} + }; + } + } else if c == 'h' { + let first_intermediate_is_questionmark = match _intermediates.get(0) { + Some(b'?') => true, + None => false, + _ => false, + }; + if first_intermediate_is_questionmark { + match params.get(0) { + Some(&25) => { + self.grid.show_cursor(); + self.mark_for_rerender(); + } + Some(&1049) => { + let columns = self + .position_and_size_override + .map(|x| x.columns) + .unwrap_or(self.position_and_size.columns); + let rows = self + .position_and_size_override + .map(|x| x.rows) + .unwrap_or(self.position_and_size.rows); + let current_grid = + std::mem::replace(&mut self.grid, Grid::new(rows, columns)); + self.alternative_grid = Some(current_grid); + self.clear_viewport_before_rendering = true; + } + Some(&1) => { + self.cursor_key_mode = true; + } + _ => {} + }; + } + } else if c == 'r' { + if params.len() > 1 { + // minus 1 because these are 1 indexed + let top_line_index = params[0] as usize - 1; + let bottom_line_index = params[1] as usize - 1; + self.grid + .set_scroll_region(top_line_index, bottom_line_index); + self.grid.show_cursor(); + } else { + self.grid.clear_scroll_region(); + } + } else if c == 't' { + // TBD - title? + } else if c == 'n' { + // TBD - device status report + } else if c == 'c' { + // TBD - identify terminal + } else if c == 'M' { + // delete lines if currently inside scroll region + let line_count_to_delete = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid + .delete_lines_in_scroll_region(line_count_to_delete); + } else if c == 'L' { + // insert blank lines if inside scroll region + let line_count_to_add = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid + .add_empty_lines_in_scroll_region(line_count_to_add); + } else if c == 'q' { + // ignore for now to run on mac + } else if c == 'G' { + let column = if params[0] == 0 { + 0 + } else { + params[0] as usize - 1 + }; + self.grid.move_cursor_to_column(column); + } else if c == 'd' { + // goto line + let line = if params[0] == 0 { + 1 + } else { + // minus 1 because this is 1 indexed + params[0] as usize - 1 + }; + self.grid.move_cursor_to_line(line); + } else if c == 'P' { + // erase characters + let count = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid.erase_characters(count, self.pending_styles); + } else if c == 'X' { + // erase characters and replace with empty characters of current style + let count = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid + .replace_with_empty_chars(count, self.pending_styles); + } else if c == 'T' { + /* + * 124 54 T SD + * Scroll down, new lines inserted at top of screen + * [4T = Scroll down 4, bring previous lines back into view + */ + let line_count: i64 = *params.get(0).expect("A number of lines was expected."); + + if line_count >= 0 { + self.rotate_scroll_region_up(line_count as usize); + } else { + self.rotate_scroll_region_down(line_count.abs() as usize); + } + } else if c == 'S' { + // move scroll up + let count = if params[0] == 0 { + 1 + } else { + params[0] as usize + }; + self.grid.delete_lines_in_scroll_region(count); + self.grid.add_empty_lines_in_scroll_region(count); + } else { + let _ = debug_log_to_file(format!("Unhandled csi: {}->{:?}", c, params)); + } + } + + fn esc_dispatch(&mut self, intermediates: &[u8], _ignore: bool, byte: u8) { + if let (b'M', None) = (byte, intermediates.get(0)) { + self.grid.move_cursor_up_with_scrolling(1); + } + } +} diff --git a/src/client/tab.rs b/src/client/tab.rs new file mode 100644 index 00000000..b7f0e5c2 --- /dev/null +++ b/src/client/tab.rs @@ -0,0 +1,2004 @@ +use crate::common::{AppInstruction, SenderWithContext}; +use crate::panes::{PaneId, PositionAndSize, TerminalPane}; +use crate::pty_bus::{PtyInstruction, VteEvent}; +use crate::{boundaries::Boundaries, panes::PluginPane}; +use crate::{layout::Layout, wasm_vm::PluginInstruction}; +use crate::{os_input_output::OsApi, utils::shared::pad_to_size}; +use std::os::unix::io::RawFd; +use std::{ + cmp::Reverse, + collections::{BTreeMap, HashSet}, +}; +use std::{io::Write, sync::mpsc::channel}; + +use crate::utils::logging::debug_log_to_file; + +/* + * Tab + * + * this holds multiple panes (currently terminal panes) which are currently displayed + * when this tab is active. + * it tracks their coordinates (x/y) and size, as well as how they should be resized + * + */ + +const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this +const MIN_TERMINAL_HEIGHT: usize = 2; +const MIN_TERMINAL_WIDTH: usize = 4; + +type BorderAndPaneIds = (usize, Vec<PaneId>); + +fn split_vertically_with_gap(rect: &PositionAndSize) -> (PositionAndSize, PositionAndSize) { + let width_of_each_half = (rect.columns - 1) / 2; + let mut first_rect = *rect; + let mut second_rect = *rect; + if rect.columns % 2 == 0 { + first_rect.columns = width_of_each_half + 1; + } else { + first_rect.columns = width_of_each_half; + } + second_rect.x = first_rect.x + first_rect.columns + 1; + second_rect.columns = width_of_each_half; + (first_rect, second_rect) +} + +fn split_horizontally_with_gap(rect: &PositionAndSize) -> (PositionAndSize, PositionAndSize) { + let height_of_each_half = (rect.rows - 1) / 2; + let mut first_rect = *rect; + let mut second_rect = *rect; + if rect.rows % 2 == 0 { + first_rect.rows = height_of_each_half + 1; + } else { + first_rect.rows = height_of_each_half; + } + second_rect.y = first_rect.y + first_rect.rows + 1; + second_rect.rows = height_of_each_half; + (first_rect, second_rect) +} + +pub struct Tab { + pub index: usize, + panes: BTreeMap<PaneId, Box<dyn Pane>>, + panes_to_hide: HashSet<PaneId>, + active_terminal: Option<PaneId>, + max_panes: Option<usize>, + full_screen_ws: PositionAndSize, + fullscreen_is_active: bool, + os_api: Box<dyn OsApi>, + pub send_pty_instructions: SenderWithContext<PtyInstruction>, + pub send_plugin_instructions: SenderWithContext<PluginInstruction>, + pub send_app_instructions: SenderWithContext<AppInstruction>, +} + +// FIXME: Use a struct that has a pane_type enum, to reduce all of the duplication +pub trait Pane { + fn x(&self) -> usize; + fn y(&self) -> usize; + fn rows(&self) -> usize; + fn columns(&self) -> usize; + fn reset_size_and_position_override(&mut self); + fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize); + fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize); + fn handle_event(&mut self, event: VteEvent); + fn cursor_coordinates(&self) -> Option<(usize, usize)>; + fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8>; + + fn position_and_size_override(&self) -> Option<PositionAndSize>; + fn should_render(&self) -> bool; + 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<String>; + fn pid(&self) -> PaneId; + fn reduce_height_down(&mut self, count: usize); + fn increase_height_down(&mut self, count: usize); + fn increase_height_up(&mut self, count: usize); + fn reduce_height_up(&mut self, count: usize); + fn increase_width_right(&mut self, count: usize); + fn reduce_width_right(&mut self, count: usize); + fn reduce_width_left(&mut self, count: usize); + fn increase_width_left(&mut self, count: usize); + fn scroll_up(&mut self, count: usize); + fn scroll_down(&mut self, count: usize); + fn clear_scroll(&mut self); + + fn right_boundary_x_coords(&self) -> usize { + self.x() + self.columns() + } + fn bottom_boundary_y_coords(&self) -> usize { + self.y() + self.rows() + } + fn is_directly_right_of(&self, other: &dyn Pane) -> bool { + self.x() == other.x() + other.columns() + 1 + } + fn is_directly_left_of(&self, other: &dyn Pane) -> bool { + self.x() + self.columns() + 1 == other.x() + } + fn is_directly_below(&self, other: &dyn Pane) -> bool { + self.y() == other.y() + other.rows() + 1 + } + fn is_directly_above(&self, other: &dyn Pane) -> bool { + self.y() + self.rows() + 1 == other.y() + } + fn horizontally_overlaps_with(&self, other: &dyn Pane) -> bool { + (self.y() >= other.y() && self.y() <= (other.y() + other.rows())) + || ((self.y() + self.rows()) <= (other.y() + other.rows()) + && (self.y() + self.rows()) > other.y()) + || (self.y() <= other.y() && (self.y() + self.rows() >= (other.y() + other.rows()))) + || (other.y() <= self.y() && (other.y() + other.rows() >= (self.y() + self.rows()))) + } + fn get_horizontal_overlap_with(&self, other: &dyn Pane) -> usize { + std::cmp::min(self.y() + self.rows(), other.y() + other.rows()) + - std::cmp::max(self.y(), other.y()) + } + fn vertically_overlaps_with(&self, other: &dyn Pane) -> bool { + (self.x() >= other.x() && self.x() <= (other.x() + other.columns())) + || ((self.x() + self.columns()) <= (other.x() + other.columns()) + && (self.x() + self.columns()) > other.x()) + || (self.x() <= other.x() + && (self.x() + self.columns() >= (other.x() + other.columns()))) + || (other.x() <= self.x() + && (other.x() + other.columns() >= (self.x() + self.columns()))) + } + fn get_vertical_overlap_with(&self, other: &dyn Pane) -> usize { + std::cmp::min(self.x() + self.columns(), other.x() + other.columns()) + - std::cmp::max(self.x(), other.x()) + } + fn min_width(&self) -> usize { + MIN_TERMINAL_WIDTH + } + fn min_height(&self) -> usize { + MIN_TERMINAL_HEIGHT + } + fn max_width(&self) -> Option<usize> { + None + } + fn max_height(&self) -> Option<usize> { + None + } + fn invisible_borders(&self) -> bool { + false + } +} + +impl Tab { + // FIXME: Too many arguments here! Maybe bundle all of the senders for the whole program in a struct? + pub fn new( + index: usize, + full_screen_ws: &PositionAndSize, + mut os_api: Box<dyn OsApi>, + send_pty_instructions: SenderWithContext<PtyInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + send_app_instructions: SenderWithContext<AppInstruction>, + max_panes: Option<usize>, + pane_id: Option<PaneId>, + ) -> Self { + let panes = if let Some(PaneId::Terminal(pid)) = pane_id { + let new_terminal = TerminalPane::new(pid, *full_screen_ws); + os_api.set_terminal_size_using_fd( + new_terminal.pid, + new_terminal.columns() as u16, + new_terminal.rows() as u16, + ); + let mut panes: BTreeMap<PaneId, Box<dyn Pane>> = BTreeMap::new(); + panes.insert(PaneId::Terminal(pid), Box::new(new_terminal)); + panes + } else { + BTreeMap::new() + }; + Tab { + index, + panes, + max_panes, + panes_to_hide: HashSet::new(), + active_terminal: pane_id, + full_screen_ws: *full_screen_ws, + fullscreen_is_active: false, + os_api, + send_app_instructions, + send_pty_instructions, + send_plugin_instructions, + } + } + + pub fn apply_layout(&mut self, layout: Layout, new_pids: Vec<RawFd>) { + // TODO: this should be an attribute on Screen instead of full_screen_ws + let free_space = PositionAndSize { + x: 0, + y: 0, + rows: self.full_screen_ws.rows, + columns: self.full_screen_ws.columns, + }; + self.panes_to_hide.clear(); + let positions_in_layout = layout.position_panes_in_space(&free_space); + let mut positions_and_size = positions_in_layout.iter(); + for (pane_kind, terminal_pane) in self.panes.iter_mut() { + // for now the layout only supports terminal panes + if let PaneId::Terminal(pid) = pane_kind { + match positions_and_size.next() { + Some((_, position_and_size)) => { + terminal_pane.reset_size_and_position_override(); + terminal_pane.change_pos_and_size(&position_and_size); + self.os_api.set_terminal_size_using_fd( + *pid, + position_and_size.columns as u16, + position_and_size.rows as u16, + ); + } + None => { + // we filled the entire layout, no room for this pane + // TODO: handle active terminal + self.panes_to_hide.insert(PaneId::Terminal(*pid)); + } + } + } + } + let mut new_pids = new_pids.iter(); + for (layout, position_and_size) in positions_and_size { + // Just a regular terminal + if let Some(plugin) = &layout.plugin { + let (pid_tx, pid_rx) = channel(); + self.send_plugin_instructions + .send(PluginInstruction::Load(pid_tx, plugin.clone())) + .unwrap(); + let pid = pid_rx.recv().unwrap(); + let new_plugin = PluginPane::new( + pid, + *position_and_size, + self.send_plugin_instructions.clone(), + ); + self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin)); + } else { + // there are still panes left to fill, use the pids we received in this method + let pid = new_pids.next().unwrap(); // if this crashes it means we got less pids than there are panes in this layout + let new_terminal = TerminalPane::new(*pid, *position_and_size); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + new_terminal.columns() as u16, + new_terminal.rows() as u16, + ); + self.panes + .insert(PaneId::Terminal(*pid), Box::new(new_terminal)); + } + } + for unused_pid in new_pids { + // this is a bit of a hack and happens because we don't have any central location that + // can query the screen as to how many panes it needs to create a layout + // fixing this will require a bit of an architecture change + self.send_pty_instructions + .send(PtyInstruction::ClosePane(PaneId::Terminal(*unused_pid))) + .unwrap(); + } + self.active_terminal = self.panes.iter().map(|(id, _)| id.to_owned()).next(); + self.render(); + } + pub fn new_pane(&mut self, pid: PaneId) { + self.close_down_to_max_terminals(); + if self.fullscreen_is_active { + self.toggle_active_pane_fullscreen(); + } + if !self.has_panes() { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + new_terminal.columns() as u16, + new_terminal.rows() as u16, + ); + self.panes.insert(pid, Box::new(new_terminal)); + self.active_terminal = Some(pid); + } + } else { + // TODO: check minimum size of active terminal + + let (_largest_terminal_size, terminal_id_to_split) = self.get_panes().fold( + (0, None), + |(current_largest_terminal_size, current_terminal_id_to_split), + id_and_terminal_to_check| { + let (id_of_terminal_to_check, terminal_to_check) = id_and_terminal_to_check; + let terminal_size = (terminal_to_check.rows() * CURSOR_HEIGHT_WIDTH_RATIO) + * terminal_to_check.columns(); + let terminal_can_be_split = terminal_to_check.columns() >= MIN_TERMINAL_WIDTH + && terminal_to_check.rows() >= MIN_TERMINAL_HEIGHT + && ((terminal_to_check.columns() >= terminal_to_check.min_width() * 2 + 1) + || (terminal_to_check.rows() + >= terminal_to_check.min_height() * 2 + 1)); + if terminal_can_be_split && terminal_size > current_largest_terminal_size { + (terminal_size, Some(*id_of_terminal_to_check)) + } else { + (current_largest_terminal_size, current_terminal_id_to_split) + } + }, + ); + if terminal_id_to_split.is_none() { + self.send_pty_instructions + .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty + .unwrap(); + return; // likely no terminal large enough to split + } + let terminal_id_to_split = terminal_id_to_split.unwrap(); + let terminal_to_split = self.panes.get_mut(&terminal_id_to_split).unwrap(); + let terminal_ws = PositionAndSize { + rows: terminal_to_split.rows(), + columns: terminal_to_split.columns(), + x: terminal_to_split.x(), + y: terminal_to_split.y(), + }; + if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns() + && terminal_to_split.rows() >= terminal_to_split.min_height() * 2 + 1 + { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws); + let new_terminal = TerminalPane::new(term_pid, bottom_winsize); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + bottom_winsize.columns as u16, + bottom_winsize.rows as u16, + ); + terminal_to_split.change_pos_and_size(&top_winsize); + self.panes.insert(pid, Box::new(new_terminal)); + if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split { + self.os_api.set_terminal_size_using_fd( + terminal_id_to_split, + top_winsize.columns as u16, + top_winsize.rows as u16, + ); + } + self.active_terminal = Some(pid); + } + } else if terminal_to_split.columns() >= terminal_to_split.min_width() * 2 + 1 { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws); + let new_terminal = TerminalPane::new(term_pid, right_winsize); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + right_winsize.columns as u16, + right_winsize.rows as u16, + ); + terminal_to_split.change_pos_and_size(&left_winsize); + self.panes.insert(pid, Box::new(new_terminal)); + if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split { + self.os_api.set_terminal_size_using_fd( + terminal_id_to_split, + left_winsize.columns as u16, + left_winsize.rows as u16, + ); + } + } + } + self.active_terminal = Some(pid); + self.render(); + } + } + pub fn horizontal_split(&mut self, pid: PaneId) { + self.close_down_to_max_terminals(); + if self.fullscreen_is_active { + self.toggle_active_pane_fullscreen(); + } + if !self.has_panes() { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + new_terminal.columns() as u16, + new_terminal.rows() as u16, + ); + self.panes.insert(pid, Box::new(new_terminal)); + self.active_terminal = Some(pid); + } + } else { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + // TODO: check minimum size of active terminal + let active_pane_id = &self.get_active_pane_id().unwrap(); + let active_pane = self.panes.get_mut(active_pane_id).unwrap(); + if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 { + self.send_pty_instructions + .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty + .unwrap(); + return; + } + let terminal_ws = PositionAndSize { + x: active_pane.x(), + y: active_pane.y(), + rows: active_pane.rows(), + columns: active_pane.columns(), + }; + let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws); + + active_pane.change_pos_and_size(&top_winsize); + + let new_terminal = TerminalPane::new(term_pid, bottom_winsize); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + bottom_winsize.columns as u16, + bottom_winsize.rows as u16, + ); + self.panes.insert(pid, Box::new(new_terminal)); + + if let PaneId::Terminal(active_terminal_pid) = active_pane_id { + self.os_api.set_terminal_size_using_fd( + *active_terminal_pid, + top_winsize.columns as u16, + top_winsize.rows as u16, + ); + } + + self.active_terminal = Some(pid); + self.render(); + } + } + } + pub fn vertical_split(&mut self, pid: PaneId) { + self.close_down_to_max_terminals(); + if self.fullscreen_is_active { + self.toggle_active_pane_fullscreen(); + } + if !self.has_panes() { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + let new_terminal = TerminalPane::new(term_pid, self.full_screen_ws); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + new_terminal.columns() as u16, + new_terminal.rows() as u16, + ); + self.panes.insert(pid, Box::new(new_terminal)); + self.active_terminal = Some(pid); + } + } else { + // FIXME: This could use a second look + if let PaneId::Terminal(term_pid) = pid { + // TODO: check minimum size of active terminal + let active_pane_id = &self.get_active_pane_id().unwrap(); + let active_pane = self.panes.get_mut(active_pane_id).unwrap(); + if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 { + self.send_pty_instructions + .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty + .unwrap(); + return; + } + let terminal_ws = PositionAndSize { + x: active_pane.x(), + y: active_pane.y(), + rows: active_pane.rows(), + columns: active_pane.columns(), + }; + let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws); + + active_pane.change_pos_and_size(&left_winsize); + + let new_terminal = TerminalPane::new(term_pid, right_winsize); + self.os_api.set_terminal_size_using_fd( + new_terminal.pid, + right_winsize.columns as u16, + right_winsize.rows as u16, + ); + self.panes.insert(pid, Box::new(new_terminal)); + + if let PaneId::Terminal(active_terminal_pid) = active_pane_id { + self.os_api.set_terminal_size_using_fd( + *active_terminal_pid, + left_winsize.columns as u16, + left_winsize.rows as u16, + ); + } + + self.active_terminal = Some(pid); + self.render(); + } + } + } + pub fn get_active_pane(&self) -> Option<&dyn Pane> { + // FIXME: Could use Option::map() here + match self.get_active_pane_id() { + Some(active_pane) => self.panes.get(&active_pane).map(Box::as_ref), + None => None, + } + } + fn get_active_pane_id(&self) -> Option<PaneId> { + self.active_terminal + } + fn get_active_terminal_id(&self) -> Option<RawFd> { + // FIXME: Is there a better way to do this? + if let Some(PaneId::Terminal(pid)) = self.active_terminal { + Some(pid) + } else { + None + } + } + pub fn handle_pty_event(&mut self, pid: RawFd, event: VteEvent) { + // if we don't have the terminal in self.terminals it's probably because + // of a race condition where the terminal was created in pty_bus but has not + // yet been created in Screen. These events are currently not buffered, so + // if you're debugging seemingly randomly missing stdout data, this is + // the reason + if let Some(terminal_output) = self.panes.get_mut(&PaneId::Terminal(pid)) { + terminal_output.handle_event(event); + } + } + pub fn write_to_active_terminal(&mut self, input_bytes: Vec<u8>) { + match self.get_active_pane_id() { + Some(PaneId::Terminal(active_terminal_id)) => { + let active_terminal = self.get_active_pane().unwrap(); + let mut adjusted_input = active_terminal.adjust_input_to_terminal(input_bytes); + self.os_api + .write_to_tty_stdin(active_terminal_id, &mut adjusted_input) + .expect("failed to write to terminal"); + self.os_api + .tcdrain(active_terminal_id) + .expect("failed to drain terminal"); + } + Some(PaneId::Plugin(pid)) => { + self.send_plugin_instructions + .send(PluginInstruction::Input(pid, input_bytes)) + .unwrap(); + } + _ => {} + } + } + pub fn get_active_terminal_cursor_position(&self) -> Option<(usize, usize)> { + // (x, y) + let active_terminal = &self.get_active_pane()?; + active_terminal + .cursor_coordinates() + .map(|(x_in_terminal, y_in_terminal)| { + let x = active_terminal.x() + x_in_terminal; + let y = active_terminal.y() + y_in_terminal; + (x, y) + }) + } + pub fn toggle_active_pane_fullscreen(&mut self) { + if let Some(active_pane_id) = self.get_active_pane_id() { + if self + .get_active_pane() + .unwrap() + .position_and_size_override() + .is_some() + { + for terminal_id in self.panes_to_hide.iter() { + self.panes + .get_mut(terminal_id) + .unwrap() + .set_should_render(true); + } + self.panes_to_hide.clear(); + let active_terminal = self.panes.get_mut(&active_pane_id).unwrap(); + active_terminal.reset_size_and_position_override(); + } else { + let terminals = self.get_panes(); + let all_ids_except_current = + terminals.filter_map( + |(&id, _)| { + if id != active_pane_id { + Some(id) + } else { + None + } + }, + ); + self.panes_to_hide = all_ids_except_current.collect(); + let active_terminal = self.panes.get_mut(&active_pane_id).unwrap(); + active_terminal.override_size_and_position(0, 0, &self.full_screen_ws); + } + let active_terminal = self.panes.get(&active_pane_id).unwrap(); + if let PaneId::Terminal(active_pid) = active_pane_id { + self.os_api.set_terminal_size_using_fd( + active_pid, + active_terminal.columns() as u16, + active_terminal.rows() as u16, + ); + } + self.render(); + self.toggle_fullscreen_is_active(); + } + } + pub fn toggle_fullscreen_is_active(&mut self) { + self.fullscreen_is_active = !self.fullscreen_is_active; + } + pub fn render(&mut self) { + if self.active_terminal.is_none() { + // we might not have an active terminal if we closed the last pane + // in that case, we should not render as the app is exiting + return; + } + let mut stdout = self.os_api.get_stdout_writer(); + let mut boundaries = Boundaries::new( + self.full_screen_ws.columns as u16, + self.full_screen_ws.rows as u16, + ); + for (kind, terminal) in self.panes.iter_mut() { + if !self.panes_to_hide.contains(&terminal.pid()) { + boundaries.add_rect(terminal.as_ref()); + if let Some(vte_output) = terminal.render() { + let vte_output = if let PaneId::Terminal(_) = kind { + vte_output + } else { + pad_to_size(&vte_output, terminal.rows(), terminal.columns()) + }; + // FIXME: Use Termion for cursor and style clearing? + write!( + stdout, + "\u{1b}[{};{}H\u{1b}[m{}", + terminal.y() + 1, + terminal.x() + 1, + vte_output + ) + .expect("cannot write to stdout"); + } + } + } + + // TODO: only render (and calculate) boundaries if there was a resize + let vte_output = boundaries.vte_output(); + stdout + .write_all(&vte_output.as_bytes()) + .expect("cannot write to stdout"); + + match self.get_active_terminal_cursor_position() { + Some((cursor_position_x, cursor_position_y)) => { + let show_cursor = "\u{1b}[?25h"; + let goto_cursor_position = format!( + "\u{1b}[{};{}H\u{1b}[m", + cursor_position_y + 1, + cursor_position_x + 1 + ); // goto row/col + stdout + .write_all(&show_cursor.as_bytes()) + .expect("cannot write to stdout"); + stdout + .write_all(&goto_cursor_position.as_bytes()) + .expect("cannot write to stdout"); + stdout.flush().expect("could not flush"); + } + None => { + let hide_cursor = "\u{1b}[?25l"; + stdout + .write_all(&hide_cursor.as_bytes()) + .expect("cannot write to stdout"); + stdout.flush().expect("could not flush"); + } + } + } + fn get_panes(&self) -> impl Iterator<Item = (&PaneId, &Box<dyn Pane>)> { + self.panes.iter() + } + // FIXME: This is some shameful duplication... + fn get_selectable_panes(&self) -> impl Iterator<Item = (&PaneId, &Box<dyn Pane>)> { + self.panes.iter().filter(|(_, p)| p.selectable()) + } + fn has_panes(&self) -> bool { + let mut all_terminals = self.get_panes(); + all_terminals.next().is_some() + } + fn has_selectable_panes(&self) -> bool { + let mut all_terminals = self.get_selectable_panes(); + all_terminals.next().is_some() + } + fn next_active_pane(&self, panes: Vec<PaneId>) -> Option<PaneId> { + panes + .into_iter() + .rev() + .find(|pid| self.panes.get(pid).unwrap().selectable()) + } + fn pane_ids_directly_left_of(&self, id: &PaneId) -> Option<Vec<PaneId>> { + let mut ids = vec![]; + let terminal_to_check = self.panes.get(id).unwrap(); + if terminal_to_check.x() == 0 { + return None; + } + for (&pid, terminal) in self.get_panes() { + if terminal.x() + terminal.columns() == terminal_to_check.x() - 1 { + ids.push(pid); + } + } + if ids.is_empty() { + None + } else { + Some(ids) + } + } + fn pane_ids_directly_right_of(&self, id: &PaneId) -> Option<Vec<PaneId>> { + let mut ids = vec![]; + let terminal_to_check = self.panes.get(id).unwrap(); + for (&pid, terminal) in self.get_panes() { + if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 { + ids.push(pid); + } + } + if ids.is_empty() { + None + } else { + Some(ids) + } + } + fn pane_ids_directly_below(&self, id: &PaneId) -> Option<Vec<PaneId>> { + let mut ids = vec![]; + let terminal_to_check = self.panes.get(id).unwrap(); + for (&pid, terminal) in self.get_panes() { + if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 { + ids.push(pid); + } + } + if ids.is_empty() { + None + } else { + Some(ids) + } + } + fn pane_ids_directly_above(&self, id: &PaneId) -> Option<Vec<PaneId>> { + let mut ids = vec![]; + let terminal_to_check = self.panes.get(id).unwrap(); + for (&pid, terminal) in self.get_panes() { + if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() { + ids.push(pid); + } + } + if ids.is_empty() { + None + } else { + Some(ids) + } + } + fn panes_top_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> { + self.panes + .keys() + .map(|t_id| self.panes.get(&t_id).unwrap().as_ref()) + .filter(|terminal| terminal.pid() != pane.pid() && terminal.y() == pane.y()) + .collect() + } + fn panes_bottom_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> { + self.panes + .keys() + .map(|t_id| self.panes.get(&t_id).unwrap().as_ref()) + .filter(|terminal| { + terminal.pid() != pane.pid() + && terminal.y() + terminal.rows() == pane.y() + pane.rows() + }) + .collect() + } + fn panes_right_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> { + self.panes + .keys() + .map(|t_id| self.panes.get(&t_id).unwrap().as_ref()) + .filter(|terminal| { + terminal.pid() != pane.pid() + && terminal.x() + terminal.columns() == pane.x() + pane.columns() + }) + .collect() + } + fn panes_left_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> { + self.panes + .keys() + .map(|t_id| self.panes.get(&t_id).unwrap().as_ref()) + .filter(|terminal| terminal.pid() != pane.pid() && terminal.x() == pane.x()) + .collect() + } + fn right_aligned_contiguous_panes_above( + &self, + id: &PaneId, + terminal_borders_to_the_right: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self + .panes + .get(id) + .expect("terminal id does not exist") + .as_ref(); + let mut right_aligned_terminals = self.panes_right_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + right_aligned_terminals.sort_by_key(|a| Reverse(a.y())); + for terminal in right_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() { + terminals.push(terminal); + } + } + // top-most border aligned with a pane border to the right + let mut top_resize_border = 0; + for terminal in &terminals { + let bottom_terminal_boundary = terminal.y() + terminal.rows(); + if terminal_borders_to_the_right + .get(&(bottom_terminal_boundary + 1)) + .is_some() + && top_resize_border < bottom_terminal_boundary + { + top_resize_border = bottom_terminal_boundary + 1; + } + } + terminals.retain(|terminal| terminal.y() >= top_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let top_resize_border = if terminals.is_empty() { + terminal_to_check.y() + } else { + top_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (top_resize_border, terminal_ids) + } + fn right_aligned_contiguous_panes_below( + &self, + id: &PaneId, + terminal_borders_to_the_right: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self + .panes + .get(id) + .expect("terminal id does not exist") + .as_ref(); + let mut right_aligned_terminals = self.panes_right_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + right_aligned_terminals.sort_by_key(|a| a.y()); + for terminal in right_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 { + terminals.push(terminal); + } + } + // bottom-most border aligned with a pane border to the right + let mut bottom_resize_border = self.full_screen_ws.rows; + for terminal in &terminals { + let top_terminal_boundary = terminal.y(); + if terminal_borders_to_the_right + .get(&(top_terminal_boundary)) + .is_some() + && top_terminal_boundary < bottom_resize_border + { + bottom_resize_border = top_terminal_boundary; + } + } + terminals.retain(|terminal| terminal.y() + terminal.rows() <= bottom_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let bottom_resize_border = if terminals.is_empty() { + terminal_to_check.y() + terminal_to_check.rows() + } else { + bottom_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (bottom_resize_border, terminal_ids) + } + fn left_aligned_contiguous_panes_above( + &self, + id: &PaneId, + terminal_borders_to_the_left: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self + .panes + .get(id) + .expect("terminal id does not exist") + .as_ref(); + let mut left_aligned_terminals = self.panes_left_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + left_aligned_terminals.sort_by_key(|a| Reverse(a.y())); + for terminal in left_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() { + terminals.push(terminal); + } + } + // top-most border aligned with a pane border to the right + let mut top_resize_border = 0; + for terminal in &terminals { + let bottom_terminal_boundary = terminal.y() + terminal.rows(); + if terminal_borders_to_the_left + .get(&(bottom_terminal_boundary + 1)) + .is_some() + && top_resize_border < bottom_terminal_boundary + { + top_resize_border = bottom_terminal_boundary + 1; + } + } + terminals.retain(|terminal| terminal.y() >= top_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let top_resize_border = if terminals.is_empty() { + terminal_to_check.y() + } else { + top_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (top_resize_border, terminal_ids) + } + fn left_aligned_contiguous_panes_below( + &self, + id: &PaneId, + terminal_borders_to_the_left: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self + .panes + .get(id) + .expect("terminal id does not exist") + .as_ref(); + let mut left_aligned_terminals = self.panes_left_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + left_aligned_terminals.sort_by_key(|a| a.y()); + for terminal in left_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 { + terminals.push(terminal); + } + } + // bottom-most border aligned with a pane border to the left + let mut bottom_resize_border = self.full_screen_ws.rows; + for terminal in &terminals { + let top_terminal_boundary = terminal.y(); + if terminal_borders_to_the_left + .get(&(top_terminal_boundary)) + .is_some() + && top_terminal_boundary < bottom_resize_border + { + bottom_resize_border = top_terminal_boundary; + } + } + terminals.retain(|terminal| { + // terminal.y() + terminal.rows() < bottom_resize_border + terminal.y() + terminal.rows() <= bottom_resize_border + }); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let bottom_resize_border = if terminals.is_empty() { + terminal_to_check.y() + terminal_to_check.rows() + } else { + bottom_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (bottom_resize_border, terminal_ids) + } + fn top_aligned_contiguous_panes_to_the_left( + &self, + id: &PaneId, + terminal_borders_above: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self + .panes + .get(id) + .expect("terminal id does not exist") + .as_ref(); + let mut top_aligned_terminals = self.panes_top_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + top_aligned_terminals.sort_by_key(|a| Reverse(a.x())); + for terminal in top_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.x() + terminal.columns() + 1 == terminal_to_check.x() { + terminals.push(terminal); + } + } + // leftmost border aligned with a pane border above + let mut left_resize_border = 0; + for terminal in &terminals { + let right_terminal_boundary = terminal.x() + terminal.columns(); + if terminal_borders_above + .get(&(right_terminal_boundary + 1)) + .is_some() + && left_resize_border < right_terminal_boundary + { + left_resize_border = right_terminal_boundary + 1; + } + } + terminals.retain(|terminal| terminal.x() >= left_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let left_resize_border = if terminals.is_empty() { + terminal_to_check.x() + } else { + left_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (left_resize_border, terminal_ids) + } + fn top_aligned_contiguous_panes_to_the_right( + &self, + id: &PaneId, + terminal_borders_above: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self.panes.get(id).unwrap().as_ref(); + let mut top_aligned_terminals = self.panes_top_aligned_with_pane(terminal_to_check); + // terminals that are next to each other up to current + top_aligned_terminals.sort_by_key(|a| a.x()); + for terminal in top_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 { + terminals.push(terminal); + } + } + // rightmost border aligned with a pane border above + let mut right_resize_border = self.full_screen_ws.columns; + for terminal in &terminals { + let left_terminal_boundary = terminal.x(); + if terminal_borders_above + .get(&left_terminal_boundary) + .is_some() + && right_resize_border > left_terminal_boundary + { + right_resize_border = left_terminal_boundary; + } + } + terminals.retain(|terminal| terminal.x() + terminal.columns() <= right_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let right_resize_border = if terminals.is_empty() { + terminal_to_check.x() + terminal_to_check.columns() + } else { + right_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (right_resize_border, terminal_ids) + } + fn bottom_aligned_contiguous_panes_to_the_left( + &self, + id: &PaneId, + terminal_borders_below: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self.panes.get(id).unwrap().as_ref(); + let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(terminal_to_check); + bottom_aligned_terminals.sort_by_key(|a| Reverse(a.x())); + // terminals that are next to each other up to current + for terminal in bottom_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.x() + terminal.columns() + 1 == terminal_to_check.x() { + terminals.push(terminal); + } + } + // leftmost border aligned with a pane border above + let mut left_resize_border = 0; + for terminal in &terminals { + let right_terminal_boundary = terminal.x() + terminal.columns(); + if terminal_borders_below + .get(&(right_terminal_boundary + 1)) + .is_some() + && left_resize_border < right_terminal_boundary + { + left_resize_border = right_terminal_boundary + 1; + } + } + terminals.retain(|terminal| terminal.x() >= left_resize_border); + // if there are no adjacent panes to resize, we use the border of the main pane we're + // resizing + let left_resize_border = if terminals.is_empty() { + terminal_to_check.x() + } else { + left_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (left_resize_border, terminal_ids) + } + fn bottom_aligned_contiguous_panes_to_the_right( + &self, + id: &PaneId, + terminal_borders_below: &HashSet<usize>, + ) -> BorderAndPaneIds { + let mut terminals = vec![]; + let terminal_to_check = self.panes.get(id).unwrap().as_ref(); + let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(terminal_to_check); + bottom_aligned_terminals.sort_by_key(|a| a.x()); + // terminals that are next to each other up to current + for terminal in bottom_aligned_terminals { + let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check); + if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 { + terminals.push(terminal); + } + } + // leftmost border aligned with a pane border above + let mut right_resize_border = self.full_screen_ws.columns; + for terminal in &terminals { + let left_terminal_boundary = terminal.x(); + if terminal_borders_below + .get(&left_terminal_boundary) + .is_some() + && right_resize_border > left_terminal_boundary + { + right_resize_border = left_terminal_boundary; + } + } + terminals.retain(|terminal| terminal.x() + terminal.columns() <= right_resize_border); + let right_resize_border = if terminals.is_empty() { + terminal_to_check.x() + terminal_to_check.columns() + } else { + right_resize_border + }; + let terminal_ids: Vec<PaneId> = terminals.iter().map(|t| t.pid()).collect(); + (right_resize_border, terminal_ids) + } + fn reduce_pane_height_down(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.reduce_height_down(count); + if let PaneId::Terminal(pid) = id { + self.os_api.set_terminal_size_using_fd( + *pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn reduce_pane_height_up(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.reduce_height_up(count); + if let PaneId::Terminal(pid) = id { + self.os_api.set_terminal_size_using_fd( + *pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn increase_pane_height_down(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.increase_height_down(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn increase_pane_height_up(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.increase_height_up(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn increase_pane_width_right(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.increase_width_right(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn increase_pane_width_left(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.increase_width_left(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn reduce_pane_width_right(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.reduce_width_right(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn reduce_pane_width_left(&mut self, id: &PaneId, count: usize) { + let terminal = self.panes.get_mut(id).unwrap(); + terminal.reduce_width_left(count); + if let PaneId::Terminal(pid) = terminal.pid() { + self.os_api.set_terminal_size_using_fd( + pid, + terminal.columns() as u16, + terminal.rows() as u16, + ); + } + } + fn pane_is_between_vertical_borders( + &self, + id: &PaneId, + left_border_x: usize, + right_border_x: usize, + ) -> bool { + let terminal = self + .panes + .get(id) + .expect("could not find terminal to check between borders"); + terminal.x() >= left_border_x && terminal.x() + terminal.columns() <= right_border_x + } + fn pane_is_between_horizontal_borders( + &self, + id: &PaneId, + top_border_y: usize, + bottom_border_y: usize, + ) -> bool { + let terminal = self + .panes + .get(id) + .expect("could not find terminal to check between borders"); + terminal.y() >= top_border_y && terminal.y() + terminal.rows() <= bottom_border_y + } + fn reduce_pane_and_surroundings_up(&mut self, id: &PaneId, count: usize) { + let mut terminals_below = self + .pane_ids_directly_below(&id) + .expect("can't reduce pane size up if there are no terminals below"); + let terminal_borders_below: HashSet<usize> = terminals_below + .iter() + .map(|t| self.panes.get(t).unwrap().x()) + .collect(); + let (left_resize_border, terminals_to_the_left) = + self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below); + let (right_resize_border, terminals_to_the_right) = + self.bottom_aligned_contiguous_panes_to_the_right(&id, &terminal_borders_below); + terminals_below.retain(|t| { + self.pane_is_between_vertical_borders(t, left_resize_border, right_resize_border) + }); + self.reduce_pane_height_up(&id, count); + for terminal_id in terminals_below { + self.increase_pane_height_up(&terminal_id, count); + } + for terminal_id in terminals_to_the_left + .iter() + .chain(terminals_to_the_right.iter()) + { + self.reduce_pane_height_up(&terminal_id, count); + } + } + fn reduce_pane_and_surroundings_down(&mut self, id: &PaneId, count: usize) { + let mut terminals_above = self + .pane_ids_directly_above(&id) + .expect("can't reduce pane size down if there are no terminals above"); + let terminal_borders_above: HashSet<usize> = terminals_above + .iter() + .map(|t| self.panes.get(t).unwrap().x()) + .collect(); + let (left_resize_border, terminals_to_the_left) = + self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above); + let (right_resize_border, terminals_to_the_right) = + self.top_aligned_contiguous_panes_to_the_right(&id, &terminal_borders_above); + terminals_above.retain(|t| { + self.pane_is_between_vertical_borders(t, left_resize_border, right_resize_border) + }); + self.reduce_pane_height_down(&id, count); + for terminal_id in terminals_above { + self.increase_pane_height_down(&terminal_id, count); + } + for terminal_id in terminals_to_the_left + .iter() + .chain(terminals_to_the_right.iter()) + { + self.reduce_pane_height_down(&terminal_id, count); + } + } + fn reduce_pane_and_surroundings_right(&mut self, id: &PaneId, count: usize) { + let mut terminals_to_the_left = self + .pane_ids_directly_left_of(&id) + .expect("can't reduce pane size right if there are no terminals to the left"); + let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left + .iter() + .map(|t| self.panes.get(t).unwrap().y()) + .collect(); + let (top_resize_border, terminals_above) = + self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left); + let (bottom_resize_border, terminals_below) = + self.left_aligned_contiguous_panes_below(&id, &terminal_borders_to_the_left); + terminals_to_the_left.retain(|t| { + self.pane_is_between_horizontal_borders(t, top_resize_border, bottom_resize_border) + }); + self.reduce_pane_width_right(&id, count); + for terminal_id in terminals_to_the_left { + self.increase_pane_width_right(&terminal_id, count); + } + for terminal_id in terminals_above.iter().chain(terminals_below.iter()) { + self.reduce_pane_width_right(&terminal_id, count); + } + } + fn reduce_pane_and_surroundings_left(&mut self, id: &PaneId, count: usize) { + let mut terminals_to_the_right = self + .pane_ids_directly_right_of(&id) + .expect("can't reduce pane size left if there are no terminals to the right"); + let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right + .iter() + .map(|t| self.panes.get(t).unwrap().y()) + .collect(); + let (top_resize_border, terminals_above) = + self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right); + let (bottom_resize_border, terminals_below) = + self.right_aligned_contiguous_panes_below(&id, &terminal_borders_to_the_right); + terminals_to_the_right.retain(|t| { + self.pane_is_between_horizontal_borders(t, top_resize_border, bottom_resize_border) + }); + self.reduce_pane_width_left(&id, count); + for terminal_id in terminals_to_the_right { + self.increase_pane_width_left(&terminal_id, count); + } + for terminal_id in terminals_above.iter().chain(terminals_below.iter()) { + self.reduce_pane_width_left(&terminal_id, count); + } + } + fn increase_pane_and_surroundings_up(&mut self, id: &PaneId, count: usize) { + let mut terminals_above = self + .pane_ids_directly_above(&id) + .expect("can't increase pane size up if there are no terminals above"); + let terminal_borders_above: HashSet<usize> = terminals_above + .iter() + .map(|t| self.panes.get(t).unwrap().x()) + .collect(); + let (left_resize_border, terminals_to_the_left) = + self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above); + let (right_resize_border, terminals_to_the_right) = + self.top_aligned_contiguous_panes_to_the_right(&id, &terminal_borders_above); + terminals_above.retain(|t| { + self.pane_is_between_vertical_borders(t, left_resize_border, right_resize_border) + }); + self.increase_pane_height_up(&id, count); + for terminal_id in terminals_above { + self.reduce_pane_height_up(&terminal_id, count); + } + for terminal_id in terminals_to_the_left + .iter() + .chain(terminals_to_the_right.iter()) + { + self.increase_pane_height_up(&terminal_id, count); + } + } + fn increase_pane_and_surroundings_down(&mut self, id: &PaneId, count: usize) { + let mut terminals_below = self + .pane_ids_directly_below(&id) + .expect("can't increase pane size down if there are no terminals below"); + let terminal_borders_below: HashSet<usize> = terminals_below + .iter() + .map(|t| self.panes.get(t).unwrap().x()) + .collect(); + let (left_resize_border, terminals_to_the_left) = + self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below); + let (right_resize_border, terminals_to_the_right) = + self.bottom_aligned_contiguous_panes_to_the_right(&id, &terminal_borders_below); + terminals_below.retain(|t| { + self.pane_is_between_vertical_borders(t, left_resize_border, right_resize_border) + }); + self.increase_pane_height_down(&id, count); + for terminal_id in terminals_below { + self.reduce_pane_height_down(&terminal_id, count); + } + for terminal_id in terminals_to_the_left + .iter() + .chain(terminals_to_the_right.iter()) + { + self.increase_pane_height_down(&terminal_id, count); + } + } + fn increase_pane_and_surroundings_right(&mut self, id: &PaneId, count: usize) { + let mut terminals_to_the_right = self + .pane_ids_directly_right_of(&id) + .expect("can't increase pane size right if there are no terminals to the right"); + let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right + .iter() + .map(|t| self.panes.get(t).unwrap().y()) + .collect(); + let (top_resize_border, terminals_above) = + self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right); + let (bottom_resize_border, terminals_below) = + self.right_aligned_contiguous_panes_below(&id, &terminal_borders_to_the_right); + terminals_to_the_right.retain(|t| { + self.pane_is_between_horizontal_borders(t, top_resize_border, bottom_resize_border) + }); + self.increase_pane_width_right(&id, count); + for terminal_id in terminals_to_the_right { + self.reduce_pane_width_right(&terminal_id, count); + } + for terminal_id in terminals_above.iter().chain(terminals_below.iter()) { + self.increase_pane_width_right(&terminal_id, count); + } + } + fn increase_pane_and_surroundings_left(&mut self, id: &PaneId, count: usize) { + let mut terminals_to_the_left = self + .pane_ids_directly_left_of(&id) + .expect("can't increase pane size right if there are no terminals to the right"); + let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left + .iter() + .map(|t| self.panes.get(t).unwrap().y()) + .collect(); + let (top_resize_border, terminals_above) = + self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left); + let (bottom_resize_border, terminals_below) = + self.left_aligned_contiguous_panes_below(&id, &terminal_borders_to_the_left); + terminals_to_the_left.retain(|t| { + self.pane_is_between_horizontal_borders(t, top_resize_border, bottom_resize_border) + }); + self.increase_pane_width_left(&id, count); + for terminal_id in terminals_to_the_left { + self.reduce_pane_width_left(&terminal_id, count); + } + for terminal_id in terminals_above.iter().chain(terminals_below.iter()) { + self.increase_pane_width_left(&terminal_id, count); + } + } + fn can_increase_pane_and_surroundings_right( + &self, + pane_id: &PaneId, + increase_by: usize, + ) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let can_increase_pane_size = pane + .max_width() + .map(|max_width| pane.columns() + increase_by <= max_width) + .unwrap_or(true); // no max width, increase to your heart's content + if !can_increase_pane_size { + return false; + } + if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) { + return panes_to_the_right.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.columns() > increase_by && p.columns() - increase_by >= p.min_width() + }); + } else { + return false; + } + } + fn can_increase_pane_and_surroundings_left( + &self, + pane_id: &PaneId, + increase_by: usize, + ) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let can_increase_pane_size = pane + .max_width() + .map(|max_width| pane.columns() + increase_by <= max_width) + .unwrap_or(true); // no max width, increase to your heart's content + if !can_increase_pane_size { + return false; + } + if let Some(panes_to_the_left) = self.pane_ids_directly_left_of(&pane_id) { + return panes_to_the_left.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.columns() > increase_by && p.columns() - increase_by >= p.min_width() + }); + } else { + return false; + } + } + fn can_increase_pane_and_surroundings_down( + &self, + pane_id: &PaneId, + increase_by: usize, + ) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let can_increase_pane_size = pane + .max_height() + .map(|max_height| pane.rows() + increase_by <= max_height) + .unwrap_or(true); // no max width, increase to your heart's content + if !can_increase_pane_size { + return false; + } + if let Some(panes_below) = self.pane_ids_directly_below(&pane_id) { + return panes_below.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.rows() > increase_by && p.rows() - increase_by >= p.min_height() + }); + } else { + return false; + } + } + fn can_increase_pane_and_surroundings_up(&self, pane_id: &PaneId, increase_by: usize) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let can_increase_pane_size = pane + .max_height() + .map(|max_height| pane.rows() + increase_by <= max_height) + .unwrap_or(true); // no max width, increase to your heart's content + if !can_increase_pane_size { + return false; + } + if let Some(panes_above) = self.pane_ids_directly_above(&pane_id) { + return panes_above.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.rows() > increase_by && p.rows() - increase_by >= p.min_height() + }); + } else { + return false; + } + } + fn can_reduce_pane_and_surroundings_right(&self, pane_id: &PaneId, reduce_by: usize) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let pane_columns = pane.columns(); + let can_reduce_pane_size = + pane_columns > reduce_by && pane_columns - reduce_by >= pane.min_width(); + if !can_reduce_pane_size { + return false; + } + if let Some(panes_to_the_left) = self.pane_ids_directly_left_of(&pane_id) { + return panes_to_the_left.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.max_width() + .map(|max_width| p.columns() + reduce_by <= max_width) + .unwrap_or(true) // no max width, increase to your heart's content + }); + } else { + return false; + } + } + fn can_reduce_pane_and_surroundings_left(&self, pane_id: &PaneId, reduce_by: usize) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let pane_columns = pane.columns(); + let can_reduce_pane_size = + pane_columns > reduce_by && pane_columns - reduce_by >= pane.min_width(); + if !can_reduce_pane_size { + return false; + } + if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) { + return panes_to_the_right.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.max_width() + .map(|max_width| p.columns() + reduce_by <= max_width) + .unwrap_or(true) // no max width, increase to your heart's content + }); + } else { + return false; + } + } + fn can_reduce_pane_and_surroundings_down(&self, pane_id: &PaneId, reduce_by: usize) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let pane_rows = pane.rows(); + let can_reduce_pane_size = + pane_rows > reduce_by && pane_rows - reduce_by >= pane.min_height(); + if !can_reduce_pane_size { + return false; + } + if let Some(panes_above) = self.pane_ids_directly_above(&pane_id) { + return panes_above.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.max_height() + .map(|max_height| p.rows() + reduce_by <= max_height) + .unwrap_or(true) // no max height, increase to your heart's content + }); + } else { + return false; + } + } + fn can_reduce_pane_and_surroundings_up(&self, pane_id: &PaneId, reduce_by: usize) -> bool { + let pane = self.panes.get(pane_id).unwrap(); + let pane_rows = pane.rows(); + let can_reduce_pane_size = + pane_rows > reduce_by && pane_rows - reduce_by >= pane.min_height(); + if !can_reduce_pane_size { + return false; + } + if let Some(panes_below) = self.pane_ids_directly_below(&pane_id) { + return panes_below.iter().all(|id| { + let p = self.panes.get(id).unwrap(); + p.max_height() + .map(|max_height| p.rows() + reduce_by <= max_height) + .unwrap_or(true) // no max height, increase to your heart's content + }); + } else { + return false; + } + } + pub fn resize_right(&mut self) { + // TODO: find out by how much we actually reduced and only reduce by that much + let count = 10; + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.can_increase_pane_and_surroundings_right(&active_pane_id, count) { + self.increase_pane_and_surroundings_right(&active_pane_id, count); + } else if self.can_reduce_pane_and_surroundings_right(&active_pane_id, count) { + self.reduce_pane_and_surroundings_right(&active_pane_id, count); + } + self.render(); + } + } + pub fn resize_left(&mut self) { + // TODO: find out by how much we actually reduced and only reduce by that much + let count = 10; + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.can_increase_pane_and_surroundings_left(&active_pane_id, count) { + self.increase_pane_and_surroundings_left(&active_pane_id, count); + } else if self.can_reduce_pane_and_surroundings_left(&active_pane_id, count) { + self.reduce_pane_and_surroundings_left(&active_pane_id, count); + } + self.render(); + } + } + pub fn resize_down(&mut self) { + // TODO: find out by how much we actually reduced and only reduce by that much + let count = 2; + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.can_increase_pane_and_surroundings_down(&active_pane_id, count) { + self.increase_pane_and_surroundings_down(&active_pane_id, count); + } else if self.can_reduce_pane_and_surroundings_down(&active_pane_id, count) { + self.reduce_pane_and_surroundings_down(&active_pane_id, count); + } + self.render(); + } + } + pub fn resize_up(&mut self) { + // TODO: find out by how much we actually reduced and only reduce by that much + let count = 2; + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.can_increase_pane_and_surroundings_up(&active_pane_id, count) { + self.increase_pane_and_surroundings_up(&active_pane_id, count); + } else if self.can_reduce_pane_and_surroundings_up(&active_pane_id, count) { + self.reduce_pane_and_surroundings_up(&active_pane_id, count); + } + self.render(); + } + } + pub fn move_focus(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_terminal_id = self.get_active_pane_id().unwrap(); + let terminal_ids: Vec<PaneId> = self.get_selectable_panes().map(|(&pid, _)| pid).collect(); // TODO: better, no allocations + let first_terminal = terminal_ids.get(0).unwrap(); + let active_terminal_id_position = terminal_ids + .iter() + .position(|id| id == &active_terminal_id) + .unwrap(); + if let Some(next_terminal) = terminal_ids.get(active_terminal_id_position + 1) { + self.active_terminal = Some(*next_terminal); + } else { + self.active_terminal = Some(*first_terminal); + } + self.render(); + } + pub fn move_focus_left(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_terminal = self.get_active_pane(); + if let Some(active) = active_terminal { + let terminals = self.get_selectable_panes(); + let next_index = terminals + .enumerate() + .filter(|(_, (_, c))| { + c.is_directly_left_of(active) && c.horizontally_overlaps_with(active) + }) + .max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(active)) + .map(|(_, (pid, _))| pid); + match next_index { + Some(&p) => { + self.active_terminal = Some(p); + } + None => { + self.active_terminal = Some(active.pid()); + } + } + } else { + self.active_terminal = Some(active_terminal.unwrap().pid()); + } + self.render(); + } + pub fn move_focus_down(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_terminal = self.get_active_pane(); + if let Some(active) = active_terminal { + let terminals = self.get_selectable_panes(); + let next_index = terminals + .enumerate() + .filter(|(_, (_, c))| { + c.is_directly_below(active) && c.vertically_overlaps_with(active) + }) + .max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(active)) + .map(|(_, (pid, _))| pid); + match next_index { + Some(&p) => { + self.active_terminal = Some(p); + } + None => { + self.active_terminal = Some(active.pid()); + } + } + } else { + self.active_terminal = Some(active_terminal.unwrap().pid()); + } + self.render(); + } + pub fn move_focus_up(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_terminal = self.get_active_pane(); + if let Some(active) = active_terminal { + let terminals = self.get_selectable_panes(); + let next_index = terminals + .enumerate() + .filter(|(_, (_, c))| { + c.is_directly_above(active) && c.vertically_overlaps_with(active) + }) + .max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(active)) + .map(|(_, (pid, _))| pid); + match next_index { + Some(&p) => { + self.active_terminal = Some(p); + } + None => { + self.active_terminal = Some(active.pid()); + } + } + } else { + self.active_terminal = Some(active_terminal.unwrap().pid()); + } + self.render(); + } + pub fn move_focus_right(&mut self) { + if !self.has_selectable_panes() { + return; + } + if self.fullscreen_is_active { + return; + } + let active_terminal = self.get_active_pane(); + if let Some(active) = active_terminal { + let terminals = self.get_selectable_panes(); + let next_index = terminals + .enumerate() + .filter(|(_, (_, c))| { + c.is_directly_right_of(active) && c.horizontally_overlaps_with(active) + }) + .max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(active)) + .map(|(_, (pid, _))| pid); + match next_index { + Some(&p) => { + self.active_terminal = Some(p); + } + None => { + self.active_terminal = Some(active.pid()); + } + } + } else { + self.active_terminal = Some(active_terminal.unwrap().pid()); + } + self.render(); + } + fn horizontal_borders(&self, terminals: &[PaneId]) -> HashSet<usize> { + terminals.iter().fold(HashSet::new(), |mut borders, t| { + let terminal = self.panes.get(t).unwrap(); + borders.insert(terminal.y()); + borders.insert(terminal.y() + terminal.rows() + 1); // 1 for the border width + borders + }) + } + fn vertical_borders(&self, terminals: &[PaneId]) -> HashSet<usize> { + terminals.iter().fold(HashSet::new(), |mut borders, t| { + let terminal = self.panes.get(t).unwrap(); + borders.insert(terminal.x()); + borders.insert(terminal.x() + terminal.columns() + 1); // 1 for the border width + borders + }) + } + fn panes_to_the_left_between_aligning_borders(&self, id: PaneId) -> Option<Vec<PaneId>> { + if let Some(terminal) = self.panes.get(&id) { + let upper_close_border = terminal.y(); + let lower_close_border = terminal.y() + terminal.rows() + 1; + + if let Some(mut terminals_to_the_left) = self.pane_ids_directly_left_of(&id) { + let terminal_borders_to_the_left = self.horizontal_borders(&terminals_to_the_left); + if terminal_borders_to_the_left.contains(&upper_close_border) + && terminal_borders_to_the_left.contains(&lower_close_border) + { + terminals_to_the_left.retain(|t| { + self.pane_is_between_horizontal_borders( + t, + upper_close_border, + lower_close_border, + ) + }); + return Some(terminals_to_the_left); + } + } + } + None + } + fn panes_to_the_right_between_aligning_borders(&self, id: PaneId) -> Option<Vec<PaneId>> { + if let Some(terminal) = self.panes.get(&id) { + let upper_close_border = terminal.y(); + let lower_close_border = terminal.y() + terminal.rows() + 1; + + if let Some(mut terminals_to_the_right) = self.pane_ids_directly_right_of(&id) { + let terminal_borders_to_the_right = + self.horizontal_borders(&terminals_to_the_right); + if terminal_borders_to_the_right.contains(&upper_close_border) + && terminal_borders_to_the_right.contains(&lower_close_border) + { + terminals_to_the_right.retain(|t| { + self.pane_is_between_horizontal_borders( + t, + upper_close_border, + lower_close_border, + ) + }); + return Some(terminals_to_the_right); + } + } + } + None + } + fn panes_above_between_aligning_borders(&self, id: PaneId) -> Option<Vec<PaneId>> { + if let Some(terminal) = self.panes.get(&id) { + let left_close_border = terminal.x(); + let right_close_border = terminal.x() + terminal.columns() + 1; + + if let Some(mut terminals_above) = self.pane_ids_directly_above(&id) { + let terminal_borders_above = self.vertical_borders(&terminals_above); + if terminal_borders_above.contains(&left_close_border) + && terminal_borders_above.contains(&right_close_border) + { + terminals_above.retain(|t| { + self.pane_is_between_vertical_borders( + t, + left_close_border, + right_close_border, + ) + }); + return Some(terminals_above); + } + } + } + None + } + fn panes_below_between_aligning_borders(&self, id: PaneId) -> Option<Vec<PaneId>> { + if let Some(terminal) = self.panes.get(&id) { + let left_close_border = terminal.x(); + let right_close_border = terminal.x() + terminal.columns() + 1; + + if let Some(mut terminals_below) = self.pane_ids_directly_below(&id) { + let terminal_borders_below = self.vertical_borders(&terminals_below); + if terminal_borders_below.contains(&left_close_border) + && terminal_borders_below.contains(&right_close_border) + { + terminals_below.retain(|t| { + self.pane_is_between_vertical_borders( + t, + left_close_border, + right_close_border, + ) + }); + return Some(terminals_below); + } + } + } + None + } + fn close_down_to_max_terminals(&mut self) { + if let Some(max_panes) = self.max_panes { + let terminals = self.get_pane_ids(); + for &pid in terminals.iter().skip(max_panes - 1) { + self.send_pty_instructions + .send(PtyInstruction::ClosePane(pid)) + .unwrap(); + self.close_pane_without_rerender(pid); + } + } + } + pub fn get_pane_ids(&self) -> Vec<PaneId> { + self.get_panes().map(|(&pid, _)| pid).collect() + } + pub fn set_pane_selectable(&mut self, id: PaneId, selectable: bool) { + if let Some(pane) = self.panes.get_mut(&id) { + pane.set_selectable(selectable); + if self.get_active_pane_id() == Some(id) && !selectable { + self.active_terminal = self.next_active_pane(self.get_pane_ids()) + } + } + } + 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); + } + } + pub fn close_pane(&mut self, id: PaneId) { + if self.panes.get(&id).is_some() { + self.close_pane_without_rerender(id); + } + } + pub fn close_pane_without_rerender(&mut self, id: PaneId) { + if let Some(terminal_to_close) = self.panes.get(&id) { + let terminal_to_close_width = terminal_to_close.columns(); + let terminal_to_close_height = terminal_to_close.rows(); + if let Some(terminals) = self.panes_to_the_left_between_aligning_borders(id) { + for terminal_id in terminals.iter() { + self.increase_pane_width_right(&terminal_id, terminal_to_close_width + 1); + // 1 for the border + } + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(terminals); + } + } else if let Some(terminals) = self.panes_to_the_right_between_aligning_borders(id) { + for terminal_id in terminals.iter() { + self.increase_pane_width_left(&terminal_id, terminal_to_close_width + 1); + // 1 for the border + } + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(terminals); + } + } else if let Some(terminals) = self.panes_above_between_aligning_borders(id) { + for terminal_id in terminals.iter() { + self.increase_pane_height_down(&terminal_id, terminal_to_close_height + 1); + // 1 for the border + } + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(terminals); + } + } else if let Some(terminals) = self.panes_below_between_aligning_borders(id) { + for terminal_id in terminals.iter() { + self.increase_pane_height_up(&terminal_id, terminal_to_close_height + 1); + // 1 for the border + } + if self.active_terminal == Some(id) { + self.active_terminal = self.next_active_pane(terminals); + } + } else { + } + self.panes.remove(&id); + if self.active_terminal.is_none() { + self.active_terminal = self.next_active_pane(self.get_pane_ids()); + } + } + } + pub fn close_focused_pane(&mut self) { + if let Some(active_pane_id) = self.get_active_pane_id() { + self.close_pane(active_pane_id); + self.send_pty_instructions + .send(PtyInstruction::ClosePane(active_pane_id)) + .unwrap(); + } + } + pub fn scroll_active_terminal_up(&mut self) { + if let Some(active_terminal_id) = self.get_active_terminal_id() { + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + active_terminal.scroll_up(1); + self.render(); + } + } + pub fn scroll_active_terminal_down(&mut self) { + if let Some(active_terminal_id) = self.get_active_terminal_id() { + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + active_terminal.scroll_down(1); + self.render(); + } + } + pub fn clear_active_terminal_scroll(&mut self) { + if let Some(active_terminal_id) = self.get_active_terminal_id() { + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + active_terminal.clear_scroll(); + } + } +} diff --git a/src/common/command_is_executing.rs b/src/common/command_is_executing.rs new file mode 100644 index 00000000..93c44eb6 --- /dev/null +++ b/src/common/command_is_executing.rs @@ -0,0 +1,53 @@ +#![allow(clippy::mutex_atomic)] +use std::sync::{Arc, Condvar, Mutex}; + +#[derive(Clone)] +pub struct CommandIsExecuting { + opening_new_pane: Arc<(Mutex<bool>, Condvar)>, + closing_pane: Arc<(Mutex<bool>, Condvar)>, +} + +impl CommandIsExecuting { + pub fn new() -> Self { + CommandIsExecuting { + opening_new_pane: Arc::new((Mutex::new(false), Condvar::new())), + closing_pane: Arc::new((Mutex::new(false), Condvar::new())), + } + } + pub fn closing_pane(&mut self) { + let (lock, _cvar) = &*self.closing_pane; + let mut closing_pane = lock.lock().unwrap(); + *closing_pane = true; + } + pub fn done_closing_pane(&mut self) { + let (lock, cvar) = &*self.closing_pane; + let mut closing_pane = lock.lock().unwrap(); + *closing_pane = false; + cvar.notify_one(); + } + pub fn opening_new_pane(&mut self) { + let (lock, _cvar) = &*self.opening_new_pane; + let mut opening_new_pane = lock.lock().unwrap(); + *opening_new_pane = true; + } + pub fn done_opening_new_pane(&mut self) { + let (lock, cvar) = &*self.opening_new_pane; + let mut opening_new_pane = lock.lock().unwrap(); + *opening_new_pane = false; + cvar.notify_one(); + } + pub fn wait_until_pane_is_closed(&self) { + let (lock, cvar) = &*self.closing_pane; + let mut closing_pane = lock.lock().unwrap(); + while *closing_pane { + closing_pane = cvar.wait(closing_pane).unwrap(); + } + } + pub fn wait_until_new_pane_is_opened(&self) { + let (lock, cvar) = &*self.opening_new_pane; + let mut opening_new_pane = lock.lock().unwrap(); + while *opening_new_pane { + opening_new_pane = cvar.wait(opening_new_pane).unwrap(); + } + } +} diff --git a/src/common/errors.rs b/src/common/errors.rs new file mode 100644 index 00000000..27fe3103 --- /dev/null +++ b/src/common/errors.rs @@ -0,0 +1,288 @@ +use super::{AppInstruction, OPENCALLS}; +use crate::pty_bus::PtyInstruction; +use crate::screen::ScreenInstruction; + +use std::fmt::{Display, Error, Formatter}; + +const MAX_THREAD_CALL_STACK: usize = 6; + +#[cfg(not(test))] +use super::SenderWithContext; +#[cfg(not(test))] +use std::panic::PanicInfo; +#[cfg(not(test))] +pub fn handle_panic( + info: &PanicInfo<'_>, + send_app_instructions: &SenderWithContext<AppInstruction>, +) { + use backtrace::Backtrace; + use std::{process, thread}; + let backtrace = Backtrace::new(); + let thread = thread::current(); + let thread = thread.name().unwrap_or("unnamed"); + + let msg = match info.payload().downcast_ref::<&'static str>() { + Some(s) => Some(*s), + None => info.payload().downcast_ref::<String>().map(|s| &**s), + }; + + let err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + + let backtrace = match (info.location(), msg) { + (Some(location), Some(msg)) => format!( + "{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked at '{}': {}:{}\n\u{1b}[0;0m{:?}", + err_ctx, + thread, + msg, + location.file(), + location.line(), + backtrace + ), + (Some(location), None) => format!( + "{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked: {}:{}\n\u{1b}[0;0m{:?}", + err_ctx, + thread, + location.file(), + location.line(), + backtrace + ), + (None, Some(msg)) => format!( + "{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked at '{}'\n\u{1b}[0;0m{:?}", + err_ctx, thread, msg, backtrace + ), + (None, None) => format!( + "{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked\n\u{1b}[0;0m{:?}", + err_ctx, thread, backtrace + ), + }; + + if thread == "main" { + println!("{}", backtrace); + process::exit(1); + } else { + send_app_instructions + .send(AppInstruction::Error(backtrace)) + .unwrap(); + } +} + +#[derive(Clone, Copy)] +pub struct ErrorContext { + calls: [ContextType; MAX_THREAD_CALL_STACK], +} + +impl ErrorContext { + pub fn new() -> Self { + Self { + calls: [ContextType::Empty; MAX_THREAD_CALL_STACK], + } + } + + pub fn add_call(&mut self, call: ContextType) { + for ctx in self.calls.iter_mut() { + if *ctx == ContextType::Empty { + *ctx = call; + break; + } + } + OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self); + } +} + +impl Default for ErrorContext { + fn default() -> Self { + Self::new() + } +} + +impl Display for ErrorContext { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + writeln!(f, "Originating Thread(s):")?; + for (index, ctx) in self.calls.iter().enumerate() { + if *ctx == ContextType::Empty { + break; + } + writeln!(f, "\u{1b}[0;0m{}. {}", index + 1, ctx)?; + } + Ok(()) + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum ContextType { + Screen(ScreenContext), + Pty(PtyContext), + + Plugin(PluginContext), + App(AppContext), + IPCServer, + StdinHandler, + AsyncTask, + Empty, +} + +impl Display for ContextType { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + let purple = "\u{1b}[1;35m"; + let green = "\u{1b}[0;32m"; + match *self { + ContextType::Screen(c) => write!(f, "{}screen_thread: {}{:?}", purple, green, c), + ContextType::Pty(c) => write!(f, "{}pty_thread: {}{:?}", purple, green, c), + + ContextType::Plugin(c) => write!(f, "{}plugin_thread: {}{:?}", purple, green, c), + ContextType::App(c) => write!(f, "{}main_thread: {}{:?}", purple, green, c), + ContextType::IPCServer => write!(f, "{}ipc_server: {}AcceptInput", purple, green), + ContextType::StdinHandler => { + write!(f, "{}stdin_handler_thread: {}AcceptInput", purple, green) + } + ContextType::AsyncTask => { + write!(f, "{}stream_terminal_bytes: {}AsyncTask", purple, green) + } + ContextType::Empty => write!(f, ""), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ScreenContext { + HandlePtyEvent, + Render, + NewPane, + HorizontalSplit, + VerticalSplit, + WriteCharacter, + ResizeLeft, + ResizeRight, + ResizeDown, + ResizeUp, + MoveFocus, + MoveFocusLeft, + MoveFocusDown, + MoveFocusUp, + MoveFocusRight, + Quit, + ScrollUp, + ScrollDown, + ClearScroll, + CloseFocusedPane, + ToggleActiveTerminalFullscreen, + SetSelectable, + SetInvisibleBorders, + SetMaxHeight, + ClosePane, + ApplyLayout, + NewTab, + SwitchTabNext, + SwitchTabPrev, + CloseTab, +} + +impl From<&ScreenInstruction> for ScreenContext { + fn from(screen_instruction: &ScreenInstruction) -> Self { + match *screen_instruction { + ScreenInstruction::Pty(..) => ScreenContext::HandlePtyEvent, + ScreenInstruction::Render => ScreenContext::Render, + ScreenInstruction::NewPane(_) => ScreenContext::NewPane, + ScreenInstruction::HorizontalSplit(_) => ScreenContext::HorizontalSplit, + ScreenInstruction::VerticalSplit(_) => ScreenContext::VerticalSplit, + ScreenInstruction::WriteCharacter(_) => ScreenContext::WriteCharacter, + ScreenInstruction::ResizeLeft => ScreenContext::ResizeLeft, + ScreenInstruction::ResizeRight => ScreenContext::ResizeRight, + ScreenInstruction::ResizeDown => ScreenContext::ResizeDown, + ScreenInstruction::ResizeUp => ScreenContext::ResizeUp, + ScreenInstruction::MoveFocus => ScreenContext::MoveFocus, + ScreenInstruction::MoveFocusLeft => ScreenContext::MoveFocusLeft, + ScreenInstruction::MoveFocusDown => ScreenContext::MoveFocusDown, + ScreenInstruction::MoveFocusUp => ScreenContext::MoveFocusUp, + ScreenInstruction::MoveFocusRight => ScreenContext::MoveFocusRight, + ScreenInstruction::Quit => ScreenContext::Quit, + ScreenInstruction::ScrollUp => ScreenContext::ScrollUp, + ScreenInstruction::ScrollDown => ScreenContext::ScrollDown, + ScreenInstruction::ClearScroll => ScreenContext::ClearScroll, + ScreenInstruction::CloseFocusedPane => ScreenContext::CloseFocusedPane, + ScreenInstruction::ToggleActiveTerminalFullscreen => { + ScreenContext::ToggleActiveTerminalFullscreen + } + ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable, + ScreenInstruction::SetInvisibleBorders(..) => ScreenContext::SetInvisibleBorders, + ScreenInstruction::SetMaxHeight(..) => ScreenContext::SetMaxHeight, + ScreenInstruction::ClosePane(_) => ScreenContext::ClosePane, + ScreenInstruction::ApplyLayout(_) => ScreenContext::ApplyLayout, + ScreenInstruction::NewTab(_) => ScreenContext::NewTab, + ScreenInstruction::SwitchTabNext => ScreenContext::SwitchTabNext, + ScreenInstruction::SwitchTabPrev => ScreenContext::SwitchTabPrev, + ScreenInstruction::CloseTab => ScreenContext::CloseTab, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum PtyContext { + SpawnTerminal, + SpawnTerminalVertically, + SpawnTerminalHorizontally, + NewTab, + ClosePane, + CloseTab, + Quit, +} + +impl From<&PtyInstruction> for PtyContext { + fn from(pty_instruction: &PtyInstruction) -> Self { + match *pty_instruction { + PtyInstruction::SpawnTerminal(_) => PtyContext::SpawnTerminal, + PtyInstruction::SpawnTerminalVertically(_) => PtyContext::SpawnTerminalVertically, + PtyInstruction::SpawnTerminalHorizontally(_) => PtyContext::SpawnTerminalHorizontally, + PtyInstruction::ClosePane(_) => PtyContext::ClosePane, + PtyInstruction::CloseTab(_) => PtyContext::CloseTab, + PtyInstruction::NewTab => PtyContext::NewTab, + PtyInstruction::Quit => PtyContext::Quit, + } + } +} + +// FIXME: This whole pattern *needs* a macro eventually, it's soul-crushing to write + +use crate::wasm_vm::PluginInstruction; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum PluginContext { + Load, + Draw, + Input, + GlobalInput, + Unload, + Quit, +} + +impl From<&PluginInstruction> for PluginContext { + fn from(plugin_instruction: &PluginInstruction) -> Self { + match *plugin_instruction { + PluginInstruction::Load(..) => PluginContext::Load, + PluginInstruction::Draw(..) => PluginContext::Draw, + PluginInstruction::Input(..) => PluginContext::Input, + PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput, + PluginInstruction::Unload(_) => PluginContext::Unload, + PluginInstruction::Quit => PluginContext::Quit, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum AppContext { + GetState, + SetState, + Exit, + Error, +} + +impl From<&AppInstruction> for AppContext { + fn from(app_instruction: &AppInstruction) -> Self { + match *app_instruction { + AppInstruction::GetState(_) => AppContext::GetState, + AppInstruction::SetState(_) => AppContext::SetState, + AppInstruction::Exit => AppContext::Exit, + AppInstruction::Error(_) => AppContext::Error, + } + } +} diff --git a/src/common/input/actions.rs b/src/common/input/actions.rs new file mode 100644 index 00000000..6f4a4521 --- /dev/null +++ b/src/common/input/actions.rs @@ -0,0 +1,47 @@ +/// This module is for defining the set of actions that can be taken in response to a keybind +/// and also passing actions back to the handler for dispatch. +use super::handler; + +#[derive(Clone)] +pub enum Direction { + Left, + Right, + Up, + Down, +} + +#[derive(Clone)] +pub enum Action { + /// Quit mosaic + Quit, + /// Write to terminal + Write(Vec<u8>), + /// 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 + SwitchFocus(Direction), + /// Move the focus pane in specified direction + MoveFocus(Direction), + /// Scroll up in focus pane + ScrollUp, + /// Scroll down in focus pane + ScrollDown, + /// Toggle focus pane between fullscreen and normal layout + ToggleFocusFullscreen, + /// Open a new pane in specified direction (relative to focus) + /// If no direction is specified, will try to use the biggest available space + NewPane(Option<Direction>), + /// Close focus pane + CloseFocus, + // Create a new tab + NewTab, + // Go to next tab + GoToNextTab, + // Go to previous tab + GoToPreviousTab, + // Close the current tab + CloseTab, +} diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs new file mode 100644 index 00000000..2a1c2c72 --- /dev/null +++ b/src/common/input/handler.rs @@ -0,0 +1,349 @@ +use super::actions::Action; +use super::keybinds::get_default_keybinds; +use crate::common::{update_state, AppInstruction, AppState, SenderWithContext, OPENCALLS}; +/// Module for handling input +use crate::errors::ContextType; +use crate::os_input_output::OsApi; +use crate::pty_bus::PtyInstruction; +use crate::screen::ScreenInstruction; +use crate::wasm_vm::PluginInstruction; +use crate::CommandIsExecuting; + +use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; +use termion::input::TermReadEventsAndRaw; + +use super::keybinds::key_to_action; + +struct InputHandler { + mode: InputMode, + mode_is_persistent: bool, + os_input: Box<dyn OsApi>, + command_is_executing: CommandIsExecuting, + send_screen_instructions: SenderWithContext<ScreenInstruction>, + send_pty_instructions: SenderWithContext<PtyInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + send_app_instructions: SenderWithContext<AppInstruction>, +} + +impl InputHandler { + fn new( + os_input: Box<dyn OsApi>, + command_is_executing: CommandIsExecuting, + send_screen_instructions: SenderWithContext<ScreenInstruction>, + send_pty_instructions: SenderWithContext<PtyInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + send_app_instructions: SenderWithContext<AppInstruction>, + ) -> Self { + InputHandler { + mode: InputMode::Normal, + mode_is_persistent: false, + os_input, + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + } + } + + /// Main event loop + fn get_input(&mut self) { + let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + err_ctx.add_call(ContextType::StdinHandler); + self.send_pty_instructions.update(err_ctx); + self.send_app_instructions.update(err_ctx); + self.send_screen_instructions.update(err_ctx); + if let Ok(keybinds) = get_default_keybinds() { + 'input_loop: loop { + let entry_mode = self.mode; + //@@@ I think this should actually just iterate over stdin directly + let stdin_buffer = self.os_input.read_from_stdin(); + drop( + self.send_plugin_instructions + .send(PluginInstruction::GlobalInput(stdin_buffer.clone())), + ); + for key_result in stdin_buffer.events_and_raw() { + match key_result { + Ok((event, raw_bytes)) => match event { + termion::event::Event::Key(key) => { + let should_break = self.dispatch_action(key_to_action( + &key, raw_bytes, &self.mode, &keybinds, + )); + //@@@ This is a hack until we dispatch more than one action per key stroke + if entry_mode == self.mode && !self.mode_is_persistent { + self.mode = InputMode::Normal; + update_state(&self.send_app_instructions, |_| AppState { + input_state: InputState { + mode: self.mode, + persistent: self.mode_is_persistent, + }, + }); + } + if should_break { + break 'input_loop; + } + } + termion::event::Event::Mouse(_) + | termion::event::Event::Unsupported(_) => { + unimplemented!("Mouse and unsupported events aren't supported!"); + } + }, + Err(err) => panic!("Encountered read error: {:?}", err), + } + } + } + } else { + //@@@ Error handling? + self.exit(); + } + } + + fn dispatch_action(&mut self, action: Action) -> bool { + let mut interrupt_loop = false; + + match action { + Action::Write(val) => { + self.send_screen_instructions + .send(ScreenInstruction::ClearScroll) + .unwrap(); + self.send_screen_instructions + .send(ScreenInstruction::WriteCharacter(val)) + .unwrap(); + } + Action::Quit => { + self.exit(); + interrupt_loop = true; + } + Action::SwitchToMode(mode) => { + self.mode = mode; + if mode == InputMode::Normal { + self.mode_is_persistent = false; + } + update_state(&self.send_app_instructions, |_| AppState { + 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, + super::actions::Direction::Right => ScreenInstruction::ResizeRight, + super::actions::Direction::Up => ScreenInstruction::ResizeUp, + super::actions::Direction::Down => ScreenInstruction::ResizeDown, + }; + self.send_screen_instructions.send(screen_instr).unwrap(); + } + Action::SwitchFocus(_) => { + self.send_screen_instructions + .send(ScreenInstruction::MoveFocus) + .unwrap(); + } + Action::MoveFocus(direction) => { + let screen_instr = match direction { + super::actions::Direction::Left => ScreenInstruction::MoveFocusLeft, + super::actions::Direction::Right => ScreenInstruction::MoveFocusRight, + super::actions::Direction::Up => ScreenInstruction::MoveFocusUp, + super::actions::Direction::Down => ScreenInstruction::MoveFocusDown, + }; + self.send_screen_instructions.send(screen_instr).unwrap(); + } + Action::ScrollUp => { + self.send_screen_instructions + .send(ScreenInstruction::ScrollUp) + .unwrap(); + } + Action::ScrollDown => { + self.send_screen_instructions + .send(ScreenInstruction::ScrollDown) + .unwrap(); + } + Action::ToggleFocusFullscreen => { + self.send_screen_instructions + .send(ScreenInstruction::ToggleActiveTerminalFullscreen) + .unwrap(); + } + Action::NewPane(direction) => { + let pty_instr = match direction { + Some(super::actions::Direction::Left) => { + PtyInstruction::SpawnTerminalVertically(None) + } + Some(super::actions::Direction::Right) => { + PtyInstruction::SpawnTerminalVertically(None) + } + Some(super::actions::Direction::Up) => { + PtyInstruction::SpawnTerminalHorizontally(None) + } + Some(super::actions::Direction::Down) => { + PtyInstruction::SpawnTerminalHorizontally(None) + } + // No direction specified - try to put it in the biggest available spot + None => PtyInstruction::SpawnTerminal(None), + }; + self.command_is_executing.opening_new_pane(); + self.send_pty_instructions.send(pty_instr).unwrap(); + self.command_is_executing.wait_until_new_pane_is_opened(); + } + Action::CloseFocus => { + self.command_is_executing.closing_pane(); + self.send_screen_instructions + .send(ScreenInstruction::CloseFocusedPane) + .unwrap(); + self.command_is_executing.wait_until_pane_is_closed(); + } + Action::NewTab => { + self.command_is_executing.opening_new_pane(); + self.send_pty_instructions + .send(PtyInstruction::NewTab) + .unwrap(); + self.command_is_executing.wait_until_new_pane_is_opened(); + } + Action::GoToNextTab => { + self.send_screen_instructions + .send(ScreenInstruction::SwitchTabNext) + .unwrap(); + } + Action::GoToPreviousTab => { + self.send_screen_instructions + .send(ScreenInstruction::SwitchTabPrev) + .unwrap(); + } + Action::CloseTab => { + self.command_is_executing.closing_pane(); + self.send_screen_instructions + .send(ScreenInstruction::CloseTab) + .unwrap(); + self.command_is_executing.wait_until_pane_is_closed(); + } + } + + interrupt_loop + } + + /// Routine to be called when the input handler exits (at the moment this is the + /// same as quitting mosaic) + fn exit(&mut self) { + self.send_app_instructions + .send(AppInstruction::Exit) + .unwrap(); + } +} + +#[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 +/// - Command mode intercepts characters to control mosaic itself, before switching immediately +/// 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, Serialize, Deserialize)] +pub enum InputMode { + Normal, + Command, + Resize, + Pane, + Tab, + Scroll, + Exiting, +} + +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct Help { + pub mode: InputMode, + pub mode_is_persistent: bool, + pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description> +} + +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::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, + } +} + +/// Entry point to the module that instantiates a new InputHandler and calls its +/// reading loop +pub fn input_loop( + os_input: Box<dyn OsApi>, + command_is_executing: CommandIsExecuting, + send_screen_instructions: SenderWithContext<ScreenInstruction>, + send_pty_instructions: SenderWithContext<PtyInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + send_app_instructions: SenderWithContext<AppInstruction>, +) { + let _handler = InputHandler::new( + os_input, + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + ) + .get_input(); +} diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs new file mode 100644 index 00000000..d6ace68d --- /dev/null +++ b/src/common/input/keybinds.rs @@ -0,0 +1,143 @@ +// This module is for mapping particular input keys to their corresponding actions. + +use super::actions::{Action, Direction}; +use super::handler::InputMode; + +use std::collections::HashMap; + +use strum::IntoEnumIterator; +use termion::event::Key; + +type Keybinds = HashMap<InputMode, ModeKeybinds>; +type ModeKeybinds = HashMap<Key, Action>; + +/// Populate the default hashmap of keybinds +/// @@@khs26 What about an input config file? +pub fn get_default_keybinds() -> Result<Keybinds, String> { + let mut defaults = Keybinds::new(); + + for mode in InputMode::iter() { + defaults.insert(mode, get_defaults_for_mode(&mode)?); + } + + Ok(defaults) +} + +fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> { + let mut defaults = ModeKeybinds::new(); + + match *mode { + InputMode::Normal => { + defaults.insert(Key::Ctrl('g'), Action::SwitchToMode(InputMode::Command)); + } + 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)); + 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('l'), Action::Resize(Direction::Right)); + + 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 => {} + } + + Ok(defaults) +} + +pub fn key_to_action(key: &Key, input: Vec<u8>, mode: &InputMode, keybinds: &Keybinds) -> Action { + if let Some(mode_keybinds) = keybinds.get(mode) { + mode_keybinds + .get(key) + .cloned() + .unwrap_or(Action::Write(input)) + } else { + // Unrecognized mode - panic? + panic!("Unrecognized mode: {:?}", mode); + } +} diff --git a/src/common/input/mod.rs b/src/common/input/mod.rs new file mode 100644 index 00000000..094054e8 --- /dev/null +++ b/src/common/input/mod.rs @@ -0,0 +1,3 @@ +pub mod actions; +pub mod handler; +pub mod keybinds; diff --git a/src/common/ipc.rs b/src/common/ipc.rs new file mode 100644 index 00000000..425d81d6 --- /dev/null +++ b/src/common/ipc.rs @@ -0,0 +1,46 @@ +// IPC stuff for starting to split things into a client and server model +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + +type SessionID = u64; + +#[derive(PartialEq, Eq, Serialize, Deserialize, Hash)] +pub struct Session { + // Unique ID for this session + id: SessionID, + // Identifier for the underlying IPC primitive (socket, pipe) + conn_name: String, + // User configured alias for the session + alias: String, +} + +// How do we want to connect to a session? +#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum ClientType { + Reader, + Writer, +} + +// Types of messages sent from the client to the server +#[derive(Serialize, Deserialize)] +pub enum ClientToServerMsg { + // List which sessions are available + ListSessions, + // Create a new session + CreateSession, + // Attach to a running session + AttachToSession(SessionID, ClientType), + // Force detach + DetachSession(SessionID), + // Disconnect from the session we're connected to + DisconnectFromSession, +} + +// Types of messages sent from the server to the client +// @@@ Implement Serialize and Deserialize for this... +pub enum ServerToClientMsg { + // Info about a particular session + SessionInfo(Session), + // A list of sessions + SessionList(HashSet<Session>), +} diff --git a/src/common/mod.rs b/src/common/mod.rs new file mode 100644 index 00000000..de0b9f76 --- /dev/null +++ b/src/common/mod.rs @@ -0,0 +1,659 @@ +pub mod command_is_executing; +pub mod errors; +pub mod input; +pub mod ipc; +pub mod os_input_output; +pub mod pty_bus; +pub mod screen; +pub mod utils; +pub mod wasm_vm; + +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::sync::mpsc::{channel, sync_channel, Receiver, SendError, Sender, SyncSender}; +use std::thread; +use std::{cell::RefCell, sync::mpsc::TrySendError}; +use std::{collections::HashMap, fs}; + +use crate::panes::PaneId; +use directories_next::ProjectDirs; +use input::handler::InputState; +use serde::{Deserialize, Serialize}; +use termion::input::TermRead; +use wasm_vm::PluginEnv; +use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; +use wasmer_wasi::{Pipe, WasiState}; + +use crate::cli::CliArgs; +use crate::layout::Layout; +use command_is_executing::CommandIsExecuting; +use errors::{AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext}; +use input::handler::input_loop; +use os_input_output::OsApi; +use pty_bus::{PtyBus, PtyInstruction}; +use screen::{Screen, ScreenInstruction}; +use utils::consts::{MOSAIC_IPC_PIPE, MOSAIC_ROOT_PLUGIN_DIR}; +use wasm_vm::{mosaic_imports, wasi_stdout, wasi_write_string, PluginInstruction}; + +#[derive(Serialize, Deserialize, Debug)] +pub enum ApiCommand { + OpenFile(PathBuf), + SplitHorizontally, + SplitVertically, + MoveFocus, +} +// FIXME: It would be good to add some more things to this over time +#[derive(Debug, Clone, Default)] +pub struct AppState { + pub input_state: InputState, +} + +// 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( + app_tx: &SenderWithContext<AppInstruction>, + update_fn: impl FnOnce(AppState) -> AppState, +) { + let (state_tx, state_rx) = channel(); + + drop(app_tx.send(AppInstruction::GetState(state_tx))); + let state = state_rx.recv().unwrap(); + + drop(app_tx.send(AppInstruction::SetState(update_fn(state)))) +} + +pub type ChannelWithContext<T> = (Sender<(T, ErrorContext)>, Receiver<(T, ErrorContext)>); +pub type SyncChannelWithContext<T> = (SyncSender<(T, ErrorContext)>, Receiver<(T, ErrorContext)>); + +#[derive(Clone)] +enum SenderType<T: Clone> { + Sender(Sender<(T, ErrorContext)>), + SyncSender(SyncSender<(T, ErrorContext)>), +} + +#[derive(Clone)] +pub struct SenderWithContext<T: Clone> { + err_ctx: ErrorContext, + sender: SenderType<T>, +} + +impl<T: Clone> SenderWithContext<T> { + fn new(err_ctx: ErrorContext, sender: SenderType<T>) -> Self { + Self { err_ctx, sender } + } + + pub fn send(&self, event: T) -> Result<(), SendError<(T, ErrorContext)>> { + match self.sender { + SenderType::Sender(ref s) => s.send((event, self.err_ctx)), + SenderType::SyncSender(ref s) => s.send((event, self.err_ctx)), + } + } + + pub fn try_send(&self, event: T) -> Result<(), TrySendError<(T, ErrorContext)>> { + if let SenderType::SyncSender(ref s) = self.sender { + s.try_send((event, self.err_ctx)) + } else { + panic!("try_send can only be called on SyncSenders!") + } + } + + pub fn update(&mut self, new_ctx: ErrorContext) { + self.err_ctx = new_ctx; + } +} + +unsafe impl<T: Clone> Send for SenderWithContext<T> {} +unsafe impl<T: Clone> Sync for SenderWithContext<T> {} + +thread_local!(static OPENCALLS: RefCell<ErrorContext> = RefCell::default()); + +#[derive(Clone)] +pub enum AppInstruction { + GetState(Sender<AppState>), + SetState(AppState), + Exit, + Error(String), +} + +pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { + let take_snapshot = "\u{1b}[?1049h"; + os_input.unset_raw_mode(0); + let _ = os_input + .get_stdout_writer() + .write(take_snapshot.as_bytes()) + .unwrap(); + let mut app_state = AppState::default(); + + let command_is_executing = CommandIsExecuting::new(); + + let full_screen_ws = os_input.get_terminal_size_using_fd(0); + os_input.set_raw_mode(0); + let (send_screen_instructions, receive_screen_instructions): ChannelWithContext< + ScreenInstruction, + > = channel(); + let err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + let mut send_screen_instructions = + SenderWithContext::new(err_ctx, SenderType::Sender(send_screen_instructions)); + + let (send_pty_instructions, receive_pty_instructions): ChannelWithContext<PtyInstruction> = + channel(); + let mut send_pty_instructions = + SenderWithContext::new(err_ctx, SenderType::Sender(send_pty_instructions)); + + let (send_plugin_instructions, receive_plugin_instructions): ChannelWithContext< + PluginInstruction, + > = channel(); + let send_plugin_instructions = + SenderWithContext::new(err_ctx, SenderType::Sender(send_plugin_instructions)); + + let (send_app_instructions, receive_app_instructions): SyncChannelWithContext<AppInstruction> = + sync_channel(0); + let send_app_instructions = + SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions)); + + let mut pty_bus = PtyBus::new( + receive_pty_instructions, + send_screen_instructions.clone(), + send_plugin_instructions.clone(), + os_input.clone(), + opts.debug, + ); + + // Don't use default layouts in tests, but do everywhere else + #[cfg(not(test))] + let default_layout = Some(PathBuf::from("default")); + #[cfg(test)] + let default_layout = None; + let maybe_layout = opts.layout.or(default_layout).map(Layout::new); + + #[cfg(not(test))] + std::panic::set_hook({ + use crate::errors::handle_panic; + let send_app_instructions = send_app_instructions.clone(); + Box::new(move |info| { + handle_panic(info, &send_app_instructions); + }) + }); + + let pty_thread = thread::Builder::new() + .name("pty".to_string()) + .spawn({ + let mut command_is_executing = command_is_executing.clone(); + send_pty_instructions.send(PtyInstruction::NewTab).unwrap(); + move || loop { + let (event, mut err_ctx) = pty_bus + .receive_pty_instructions + .recv() + .expect("failed to receive event on channel"); + err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); + pty_bus.send_screen_instructions.update(err_ctx); + match event { + PtyInstruction::SpawnTerminal(file_to_open) => { + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions + .send(ScreenInstruction::NewPane(PaneId::Terminal(pid))) + .unwrap(); + } + PtyInstruction::SpawnTerminalVertically(file_to_open) => { + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions + .send(ScreenInstruction::VerticalSplit(PaneId::Terminal(pid))) + .unwrap(); + } + PtyInstruction::SpawnTerminalHorizontally(file_to_open) => { + let pid = pty_bus.spawn_terminal(file_to_open); + pty_bus + .send_screen_instructions + .send(ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid))) + .unwrap(); + } + PtyInstruction::NewTab => { + if let Some(layout) = maybe_layout.clone() { + pty_bus.spawn_terminals_for_layout(layout); + } else { + let pid = pty_bus.spawn_terminal(None); + pty_bus + .send_screen_instructions + .send(ScreenInstruction::NewTab(pid)) + .unwrap(); + } + } + PtyInstruction::ClosePane(id) => { + pty_bus.close_pane(id); + command_is_executing.done_closing_pane(); + } + PtyInstruction::CloseTab(ids) => { + pty_bus.close_tab(ids); + command_is_executing.done_closing_pane(); + } + PtyInstruction::Quit => { + break; + } + } + } + }) + .unwrap(); + + let screen_thread = thread::Builder::new() + .name("screen".to_string()) + .spawn({ + let mut command_is_executing = command_is_executing.clone(); + let os_input = os_input.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_plugin_instructions = send_plugin_instructions.clone(); + let send_app_instructions = send_app_instructions.clone(); + let max_panes = opts.max_panes; + + move || { + let mut screen = Screen::new( + receive_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + &full_screen_ws, + os_input, + max_panes, + ); + loop { + let (event, mut err_ctx) = screen + .receiver + .recv() + .expect("failed to receive event on channel"); + err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); + screen.send_app_instructions.update(err_ctx); + screen.send_pty_instructions.update(err_ctx); + match event { + ScreenInstruction::Pty(pid, vte_event) => { + screen + .get_active_tab_mut() + .unwrap() + .handle_pty_event(pid, vte_event); + } + ScreenInstruction::Render => { + screen.render(); + } + ScreenInstruction::NewPane(pid) => { + screen.get_active_tab_mut().unwrap().new_pane(pid); + command_is_executing.done_opening_new_pane(); + } + ScreenInstruction::HorizontalSplit(pid) => { + screen.get_active_tab_mut().unwrap().horizontal_split(pid); + command_is_executing.done_opening_new_pane(); + } + ScreenInstruction::VerticalSplit(pid) => { + screen.get_active_tab_mut().unwrap().vertical_split(pid); + command_is_executing.done_opening_new_pane(); + } + ScreenInstruction::WriteCharacter(bytes) => { + screen + .get_active_tab_mut() + .unwrap() + .write_to_active_terminal(bytes); + } + ScreenInstruction::ResizeLeft => { + screen.get_active_tab_mut().unwrap().resize_left(); + } + ScreenInstruction::ResizeRight => { + screen.get_active_tab_mut().unwrap().resize_right(); + } + ScreenInstruction::ResizeDown => { + screen.get_active_tab_mut().unwrap().resize_down(); + } + ScreenInstruction::ResizeUp => { + screen.get_active_tab_mut().unwrap().resize_up(); + } + ScreenInstruction::MoveFocus => { + screen.get_active_tab_mut().unwrap().move_focus(); + } + ScreenInstruction::MoveFocusLeft => { + screen.get_active_tab_mut().unwrap().move_focus_left(); + } + ScreenInstruction::MoveFocusDown => { + screen.get_active_tab_mut().unwrap().move_focus_down(); + } + ScreenInstruction::MoveFocusRight => { + screen.get_active_tab_mut().unwrap().move_focus_right(); + } + ScreenInstruction::MoveFocusUp => { + screen.get_active_tab_mut().unwrap().move_focus_up(); + } + ScreenInstruction::ScrollUp => { + screen + .get_active_tab_mut() + .unwrap() + .scroll_active_terminal_up(); + } + ScreenInstruction::ScrollDown => { + screen + .get_active_tab_mut() + .unwrap() + .scroll_active_terminal_down(); + } + ScreenInstruction::ClearScroll => { + screen + .get_active_tab_mut() + .unwrap() + .clear_active_terminal_scroll(); + } + ScreenInstruction::CloseFocusedPane => { + screen.get_active_tab_mut().unwrap().close_focused_pane(); + screen.render(); + } + ScreenInstruction::SetSelectable(id, selectable) => { + screen + .get_active_tab_mut() + .unwrap() + .set_pane_selectable(id, selectable); + // FIXME: Is this needed? + screen.render(); + } + ScreenInstruction::SetMaxHeight(id, max_height) => { + screen + .get_active_tab_mut() + .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(); + } + ScreenInstruction::ToggleActiveTerminalFullscreen => { + screen + .get_active_tab_mut() + .unwrap() + .toggle_active_pane_fullscreen(); + } + ScreenInstruction::NewTab(pane_id) => { + screen.new_tab(pane_id); + command_is_executing.done_opening_new_pane(); + } + ScreenInstruction::SwitchTabNext => screen.switch_tab_next(), + ScreenInstruction::SwitchTabPrev => screen.switch_tab_prev(), + ScreenInstruction::CloseTab => screen.close_tab(), + ScreenInstruction::ApplyLayout((layout, new_pane_pids)) => { + screen.apply_layout(layout, new_pane_pids); + command_is_executing.done_opening_new_pane(); + } + ScreenInstruction::Quit => { + break; + } + } + } + } + }) + .unwrap(); + + let wasm_thread = thread::Builder::new() + .name("wasm".to_string()) + .spawn({ + let mut send_pty_instructions = send_pty_instructions.clone(); + let mut send_screen_instructions = send_screen_instructions.clone(); + let mut send_app_instructions = send_app_instructions.clone(); + + let store = Store::default(); + let mut plugin_id = 0; + let mut plugin_map = HashMap::new(); + + move || loop { + let (event, mut err_ctx) = receive_plugin_instructions + .recv() + .expect("failed to receive event on channel"); + err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); + send_screen_instructions.update(err_ctx); + send_pty_instructions.update(err_ctx); + send_app_instructions.update(err_ctx); + match event { + PluginInstruction::Load(pid_tx, path) => { + let project_dirs = + ProjectDirs::from("org", "Mosaic Contributors", "Mosaic").unwrap(); + let plugin_dir = project_dirs.data_dir().join("plugins/"); + let root_plugin_dir = Path::new(MOSAIC_ROOT_PLUGIN_DIR); + let wasm_bytes = fs::read(&path) + .or_else(|_| fs::read(&path.with_extension("wasm"))) + .or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm"))) + .or_else(|_| { + fs::read(&root_plugin_dir.join(&path).with_extension("wasm")) + }) + .unwrap_or_else(|_| panic!("cannot find plugin {}", &path.display())); + + // FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that + let module = Module::new(&store, &wasm_bytes).unwrap(); + + let output = Pipe::new(); + let input = Pipe::new(); + let mut wasi_env = WasiState::new("mosaic") + .env("CLICOLOR_FORCE", "1") + .preopen(|p| { + p.directory(".") // FIXME: Change this to a more meaningful dir + .alias(".") + .read(true) + .write(true) + .create(true) + }) + .unwrap() + .stdin(Box::new(input)) + .stdout(Box::new(output)) + .finalize() + .unwrap(); + + let wasi = wasi_env.import_object(&module).unwrap(); + + let plugin_env = PluginEnv { + plugin_id, + send_pty_instructions: send_pty_instructions.clone(), + send_screen_instructions: send_screen_instructions.clone(), + send_app_instructions: send_app_instructions.clone(), + wasi_env, + }; + + let mosaic = mosaic_imports(&store, &plugin_env); + let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap(); + + let start = instance.exports.get_function("_start").unwrap(); + + // This eventually calls the `.init()` method + start.call(&[]).unwrap(); + + plugin_map.insert(plugin_id, (instance, plugin_env)); + pid_tx.send(plugin_id).unwrap(); + plugin_id += 1; + } + PluginInstruction::Draw(buf_tx, pid, rows, cols) => { + let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); + + let draw = instance.exports.get_function("draw").unwrap(); + + draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]) + .unwrap(); + + buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap(); + } + // FIXME: Deduplicate this with the callback below! + PluginInstruction::Input(pid, input_bytes) => { + let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); + + let handle_key = instance.exports.get_function("handle_key").unwrap(); + for key in input_bytes.keys() { + if let Ok(key) = key { + wasi_write_string( + &plugin_env.wasi_env, + &serde_json::to_string(&key).unwrap(), + ); + handle_key.call(&[]).unwrap(); + } + } + + drop(send_screen_instructions.send(ScreenInstruction::Render)); + } + PluginInstruction::GlobalInput(input_bytes) => { + // FIXME: Set up an event subscription system, and timed callbacks + for (instance, plugin_env) in plugin_map.values() { + let handler = + instance.exports.get_function("handle_global_key").unwrap(); + for key in input_bytes.keys() { + if let Ok(key) = key { + wasi_write_string( + &plugin_env.wasi_env, + &serde_json::to_string(&key).unwrap(), + ); + handler.call(&[]).unwrap(); + } + } + } + + drop(send_screen_instructions.send(ScreenInstruction::Render)); + } + PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)), + PluginInstruction::Quit => break, + } + } + }) + .unwrap(); + + // TODO: currently we don't wait for this to quit + // because otherwise the app will hang. Need to fix this so it both + // listens to the ipc-bus and is able to quit cleanly + #[cfg(not(test))] + let _ipc_thread = thread::Builder::new() + .name("ipc_server".to_string()) + .spawn({ + use std::io::Read; + let mut send_pty_instructions = send_pty_instructions.clone(); + let mut send_screen_instructions = send_screen_instructions.clone(); + move || { + std::fs::remove_file(MOSAIC_IPC_PIPE).ok(); + let listener = std::os::unix::net::UnixListener::bind(MOSAIC_IPC_PIPE) + .expect("could not listen on ipc socket"); + let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + err_ctx.add_call(ContextType::IPCServer); + send_pty_instructions.update(err_ctx); + send_screen_instructions.update(err_ctx); + + for stream in listener.incoming() { + match stream { + Ok(mut stream) => { + let mut buffer = [0; 65535]; // TODO: more accurate + let _ = stream + .read(&mut buffer) + .expect("failed to parse ipc message"); + let decoded: ApiCommand = bincode::deserialize(&buffer) + .expect("failed to deserialize ipc message"); + match &decoded { + ApiCommand::OpenFile(file_name) => { + let path = PathBuf::from(file_name); + send_pty_instructions + .send(PtyInstruction::SpawnTerminal(Some(path))) + .unwrap(); + } + ApiCommand::SplitHorizontally => { + send_pty_instructions + .send(PtyInstruction::SpawnTerminalHorizontally(None)) + .unwrap(); + } + ApiCommand::SplitVertically => { + send_pty_instructions + .send(PtyInstruction::SpawnTerminalVertically(None)) + .unwrap(); + } + ApiCommand::MoveFocus => { + send_screen_instructions + .send(ScreenInstruction::MoveFocus) + .unwrap(); + } + } + } + Err(err) => { + panic!("err {:?}", err); + } + } + } + } + }) + .unwrap(); + + let _stdin_thread = thread::Builder::new() + .name("stdin_handler".to_string()) + .spawn({ + let send_screen_instructions = send_screen_instructions.clone(); + let send_pty_instructions = send_pty_instructions.clone(); + let send_plugin_instructions = send_plugin_instructions.clone(); + let os_input = os_input.clone(); + move || { + input_loop( + os_input, + command_is_executing, + send_screen_instructions, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + ) + } + }); + + #[warn(clippy::never_loop)] + loop { + let (app_instruction, mut err_ctx) = receive_app_instructions + .recv() + .expect("failed to receive app instruction on channel"); + + err_ctx.add_call(ContextType::App(AppContext::from(&app_instruction))); + send_screen_instructions.update(err_ctx); + send_pty_instructions.update(err_ctx); + match app_instruction { + AppInstruction::GetState(state_tx) => drop(state_tx.send(app_state.clone())), + AppInstruction::SetState(state) => app_state = state, + AppInstruction::Exit => { + break; + } + AppInstruction::Error(backtrace) => { + let _ = send_screen_instructions.send(ScreenInstruction::Quit); + let _ = screen_thread.join(); + let _ = send_pty_instructions.send(PtyInstruction::Quit); + let _ = pty_thread.join(); + let _ = send_plugin_instructions.send(PluginInstruction::Quit); + let _ = wasm_thread.join(); + os_input.unset_raw_mode(0); + let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1); + let error = format!("{}\n{}", goto_start_of_last_line, backtrace); + let _ = os_input + .get_stdout_writer() + .write(error.as_bytes()) + .unwrap(); + std::process::exit(1); + } + } + } + + let _ = send_pty_instructions.send(PtyInstruction::Quit); + pty_thread.join().unwrap(); + let _ = send_screen_instructions.send(ScreenInstruction::Quit); + screen_thread.join().unwrap(); + let _ = send_plugin_instructions.send(PluginInstruction::Quit); + wasm_thread.join().unwrap(); + + // cleanup(); + let reset_style = "\u{1b}[m"; + let show_cursor = "\u{1b}[?25h"; + let restore_snapshot = "\u{1b}[?1049l"; + let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1); + let goodbye_message = format!( + "{}\n{}{}{}Bye from Mosaic!", + goto_start_of_last_line, restore_snapshot, reset_style, show_cursor + ); + + os_input.unset_raw_mode(0); + let _ = os_input + .get_stdout_writer() + .write(goodbye_message.as_bytes()) + .unwrap(); + os_input.get_stdout_writer().flush().unwrap(); +} diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs new file mode 100644 index 00000000..41ee3b3c --- /dev/null +++ b/src/common/os_input_output.rs @@ -0,0 +1,217 @@ +use crate::panes::PositionAndSize; +use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::pty::{forkpty, Winsize}; +use nix::sys::signal::{kill, Signal}; +use nix::sys::termios::{cfmakeraw, tcdrain, tcgetattr, tcsetattr, SetArg, Termios}; +use nix::sys::wait::waitpid; +use nix::unistd::{read, write, ForkResult, Pid}; +use std::io::prelude::*; +use std::io::{stdin, Write}; +use std::os::unix::io::RawFd; +use std::path::PathBuf; +use std::process::{Child, Command}; +use std::sync::{Arc, Mutex}; + +use std::env; + +fn into_raw_mode(pid: RawFd) { + let mut tio = tcgetattr(pid).expect("could not get terminal attribute"); + cfmakeraw(&mut tio); + match tcsetattr(pid, SetArg::TCSANOW, &tio) { + Ok(_) => {} + Err(e) => panic!("error {:?}", e), + }; +} + +fn unset_raw_mode(pid: RawFd, orig_termios: Termios) { + match tcsetattr(pid, SetArg::TCSANOW, &orig_termios) { + Ok(_) => {} + Err(e) => panic!("error {:?}", e), + }; +} + +pub fn get_terminal_size_using_fd(fd: RawFd) -> PositionAndSize { + // TODO: do this with the nix ioctl + use libc::ioctl; + use libc::TIOCGWINSZ; + + let mut winsize = Winsize { + ws_row: 0, + ws_col: 0, + ws_xpixel: 0, + ws_ypixel: 0, + }; + + unsafe { ioctl(fd, TIOCGWINSZ, &mut winsize) }; + PositionAndSize::from(winsize) +} + +pub fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) { + // TODO: do this with the nix ioctl + use libc::ioctl; + use libc::TIOCSWINSZ; + + let winsize = Winsize { + ws_col: columns, + ws_row: rows, + ws_xpixel: 0, + ws_ypixel: 0, + }; + unsafe { ioctl(fd, TIOCSWINSZ, &winsize) }; +} + +fn handle_command_exit(mut child: Child) { + let signals = ::signal_hook::iterator::Signals::new(&[::signal_hook::SIGINT]).unwrap(); + 'handle_exit: loop { + match child.try_wait() { + Ok(Some(_status)) => { + // TODO: handle errors? + break; + } + Ok(None) => { + ::std::thread::sleep(::std::time::Duration::from_millis(100)); + } + Err(e) => panic!("error attempting to wait: {}", e), + } + + for signal in signals.pending() { + // FIXME: We need to handle more signals here! + match signal { + signal_hook::SIGINT => { + child.kill().unwrap(); + child.wait().unwrap(); + break 'handle_exit; + } + _ => {} + } + } + } +} + +fn spawn_terminal(file_to_open: Option<PathBuf>, orig_termios: Termios) -> (RawFd, RawFd) { + let (pid_primary, pid_secondary): (RawFd, RawFd) = { + match forkpty(None, Some(&orig_termios)) { + Ok(fork_pty_res) => { + let pid_primary = fork_pty_res.master; + let pid_secondary = match fork_pty_res.fork_result { + ForkResult::Parent { child } => { + // fcntl(pid_primary, FcntlArg::F_SETFL(OFlag::empty())).expect("could not fcntl"); + fcntl(pid_primary, FcntlArg::F_SETFL(OFlag::O_NONBLOCK)) + .expect("could not fcntl"); + child + } + ForkResult::Child => match file_to_open { + Some(file_to_open) => { + if env::var("EDITOR").is_err() && env::var("VISUAL").is_err() { + panic!("Can't edit files if an editor is not defined. To fix: define the EDITOR or VISUAL environment variables with the path to your editor (eg. /usr/bin/vim)"); + } + let editor = + env::var("EDITOR").unwrap_or_else(|_| env::var("VISUAL").unwrap()); + + let child = Command::new(editor) + .args(&[file_to_open]) + .spawn() + .expect("failed to spawn"); + handle_command_exit(child); + ::std::process::exit(0); + } + None => { + let child = Command::new(env::var("SHELL").unwrap()) + .spawn() + .expect("failed to spawn"); + handle_command_exit(child); + ::std::process::exit(0); + } + }, + }; + (pid_primary, pid_secondary.as_raw()) + } + Err(e) => { + panic!("failed to fork {:?}", e); + } + } + }; + (pid_primary, pid_secondary) +} + +#[derive(Clone)] +pub struct OsInputOutput { + orig_termios: Arc<Mutex<Termios>>, +} + +pub trait OsApi: Send + Sync { + fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize; + fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16); + fn set_raw_mode(&mut self, pid: RawFd); + fn unset_raw_mode(&mut self, pid: RawFd); + fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd); + fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>; + fn write_to_tty_stdin(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>; + fn tcdrain(&mut self, pid: RawFd) -> Result<(), nix::Error>; + fn kill(&mut self, pid: RawFd) -> Result<(), nix::Error>; + fn read_from_stdin(&self) -> Vec<u8>; + fn get_stdout_writer(&self) -> Box<dyn Write>; + fn box_clone(&self) -> Box<dyn OsApi>; +} + +impl OsApi for OsInputOutput { + fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize { + get_terminal_size_using_fd(pid) + } + fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16) { + set_terminal_size_using_fd(pid, cols, rows); + } + fn set_raw_mode(&mut self, pid: RawFd) { + into_raw_mode(pid); + } + fn unset_raw_mode(&mut self, pid: RawFd) { + let orig_termios = self.orig_termios.lock().unwrap(); + unset_raw_mode(pid, orig_termios.clone()); + } + fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { + let orig_termios = self.orig_termios.lock().unwrap(); + spawn_terminal(file_to_open, orig_termios.clone()) + } + fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> { + read(pid, buf) + } + fn write_to_tty_stdin(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> { + write(pid, buf) + } + fn tcdrain(&mut self, pid: RawFd) -> Result<(), nix::Error> { + tcdrain(pid) + } + fn box_clone(&self) -> Box<dyn OsApi> { + Box::new((*self).clone()) + } + fn read_from_stdin(&self) -> Vec<u8> { + let stdin = stdin(); + let mut stdin = stdin.lock(); + let buffer = stdin.fill_buf().unwrap(); + let length = buffer.len(); + let read_bytes = Vec::from(buffer); + stdin.consume(length); + read_bytes + } + fn get_stdout_writer(&self) -> Box<dyn Write> { + let stdout = ::std::io::stdout(); + Box::new(stdout) + } + fn kill(&mut self, fd: RawFd) -> Result<(), nix::Error> { + kill(Pid::from_raw(fd), Some(Signal::SIGINT)).unwrap(); + waitpid(Pid::from_raw(fd), None).unwrap(); + Ok(()) + } +} + +impl Clone for Box<dyn OsApi> { + fn clone(&self) -> Box<dyn OsApi> { + self.box_clone() + } +} + +pub fn get_os_input() -> OsInputOutput { + let current_termios = tcgetattr(0).unwrap(); + let orig_termios = Arc::new(Mutex::new(current_termios)); + OsInputOutput { orig_termios } +} diff --git a/src/common/pty_bus.rs b/src/common/pty_bus.rs new file mode 100644 index 00000000..9a00d1de --- /dev/null +++ b/src/common/pty_bus.rs @@ -0,0 +1,326 @@ +use ::async_std::stream::*; +use ::async_std::task; +use ::async_std::task::*; +use ::std::collections::HashMap; +use ::std::os::unix::io::RawFd; +use ::std::pin::*; +use ::std::sync::mpsc::Receiver; +use ::std::time::{Duration, Instant}; +use ::vte; +use std::path::PathBuf; + +use super::{ScreenInstruction, SenderWithContext, OPENCALLS}; +use crate::os_input_output::OsApi; +use crate::utils::logging::debug_to_file; +use crate::{ + errors::{ContextType, ErrorContext}, + panes::PaneId, +}; +use crate::{layout::Layout, wasm_vm::PluginInstruction}; + +pub struct ReadFromPid { + pid: RawFd, + os_input: Box<dyn OsApi>, +} + +impl ReadFromPid { + pub fn new(pid: &RawFd, os_input: Box<dyn OsApi>) -> ReadFromPid { + ReadFromPid { + pid: *pid, + os_input, + } + } +} + +impl Stream for ReadFromPid { + type Item = Vec<u8>; + fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { + let mut read_buffer = [0; 65535]; + let pid = self.pid; + let read_result = &self.os_input.read_from_tty_stdout(pid, &mut read_buffer); + match read_result { + Ok(res) => { + if *res == 0 { + // indicates end of file + Poll::Ready(None) + } else { + let res = Some(read_buffer[..=*res].to_vec()); + Poll::Ready(res) + } + } + Err(e) => { + match e { + nix::Error::Sys(errno) => { + if *errno == nix::errno::Errno::EAGAIN { + Poll::Ready(Some(vec![])) // TODO: better with timeout waker somehow + } else { + Poll::Ready(None) + } + } + _ => Poll::Ready(None), + } + } + } + } +} + +#[derive(Debug, Clone)] +pub enum VteEvent { + // TODO: try not to allocate Vecs + Print(char), + Execute(u8), // byte + Hook(Vec<i64>, Vec<u8>, bool, char), // params, intermediates, ignore, char + Put(u8), // byte + Unhook, + OscDispatch(Vec<Vec<u8>>, bool), // params, bell_terminated + CsiDispatch(Vec<i64>, Vec<u8>, bool, char), // params, intermediates, ignore, char + EscDispatch(Vec<u8>, bool, u8), // intermediates, ignore, byte +} + +struct VteEventSender { + id: RawFd, + sender: SenderWithContext<ScreenInstruction>, +} + +impl VteEventSender { + pub fn new(id: RawFd, sender: SenderWithContext<ScreenInstruction>) -> Self { + VteEventSender { id, sender } + } +} + +impl vte::Perform for VteEventSender { + fn print(&mut self, c: char) { + let _ = self + .sender + .send(ScreenInstruction::Pty(self.id, VteEvent::Print(c))); + } + fn execute(&mut self, byte: u8) { + let _ = self + .sender + .send(ScreenInstruction::Pty(self.id, VteEvent::Execute(byte))); + } + + fn hook(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, c: char) { + let params = params.iter().copied().collect(); + let intermediates = intermediates.iter().copied().collect(); + let instruction = + ScreenInstruction::Pty(self.id, VteEvent::Hook(params, intermediates, ignore, c)); + let _ = self.sender.send(instruction); + } + + fn put(&mut self, byte: u8) { + let _ = self + .sender + .send(ScreenInstruction::Pty(self.id, VteEvent::Put(byte))); + } + + fn unhook(&mut self) { + let _ = self + .sender + .send(ScreenInstruction::Pty(self.id, VteEvent::Unhook)); + } + + fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { + let params = params.iter().map(|p| p.to_vec()).collect(); + let instruction = + ScreenInstruction::Pty(self.id, VteEvent::OscDispatch(params, bell_terminated)); + let _ = self.sender.send(instruction); + } + + fn csi_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, c: char) { + let params = params.iter().copied().collect(); + let intermediates = intermediates.iter().copied().collect(); + let instruction = ScreenInstruction::Pty( + self.id, + VteEvent::CsiDispatch(params, intermediates, ignore, c), + ); + let _ = self.sender.send(instruction); + } + + fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { + let intermediates = intermediates.iter().copied().collect(); + let instruction = + ScreenInstruction::Pty(self.id, VteEvent::EscDispatch(intermediates, ignore, byte)); + let _ = self.sender.send(instruction); + } +} + +#[derive(Clone, Debug)] +pub enum PtyInstruction { + SpawnTerminal(Option<PathBuf>), + SpawnTerminalVertically(Option<PathBuf>), + SpawnTerminalHorizontally(Option<PathBuf>), + NewTab, + ClosePane(PaneId), + CloseTab(Vec<PaneId>), + Quit, +} + +pub struct PtyBus { + pub send_screen_instructions: SenderWithContext<ScreenInstruction>, + pub send_plugin_instructions: SenderWithContext<PluginInstruction>, + pub receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, + pub id_to_child_pid: HashMap<RawFd, RawFd>, + os_input: Box<dyn OsApi>, + debug_to_file: bool, + task_handles: HashMap<RawFd, JoinHandle<()>>, +} + +fn stream_terminal_bytes( + pid: RawFd, + mut send_screen_instructions: SenderWithContext<ScreenInstruction>, + os_input: Box<dyn OsApi>, + debug: bool, +) -> JoinHandle<()> { + let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow()); + task::spawn({ + async move { + err_ctx.add_call(ContextType::AsyncTask); + send_screen_instructions.update(err_ctx); + let mut vte_parser = vte::Parser::new(); + let mut vte_event_sender = VteEventSender::new(pid, send_screen_instructions.clone()); + let mut terminal_bytes = ReadFromPid::new(&pid, os_input); + + let mut last_byte_receive_time: Option<Instant> = None; + let mut pending_render = false; + let max_render_pause = Duration::from_millis(30); + + while let Some(bytes) = terminal_bytes.next().await { + let bytes_is_empty = bytes.is_empty(); + for byte in bytes { + if debug { + debug_to_file(byte, pid).unwrap(); + } + vte_parser.advance(&mut vte_event_sender, byte); + } + if !bytes_is_empty { + // for UX reasons, if we got something on the wire, we only send the render notice if: + // 1. there aren't any more bytes on the wire afterwards + // 2. a certain period (currently 30ms) has elapsed since the last render + // (otherwise if we get a large amount of data, the display would hang + // until it's done) + // 3. the stream has ended, and so we render 1 last time + match last_byte_receive_time.as_mut() { + Some(receive_time) => { + if receive_time.elapsed() > max_render_pause { + pending_render = false; + let _ = send_screen_instructions.send(ScreenInstruction::Render); + last_byte_receive_time = Some(Instant::now()); + } else { + pending_render = true; + } + } + None => { + last_byte_receive_time = Some(Instant::now()); + pending_render = true; + } + }; + } else { + if pending_render { + pending_render = false; + let _ = send_screen_instructions.send(ScreenInstruction::Render); + } + last_byte_receive_time = None; + task::sleep(::std::time::Duration::from_millis(10)).await; + } + } + send_screen_instructions + .send(ScreenInstruction::Render) + .unwrap(); + #[cfg(not(test))] + // this is a little hacky, and is because the tests end the file as soon as + // we read everything, rather than hanging until there is new data + // a better solution would be to fix the test fakes, but this will do for now + send_screen_instructions + .send(ScreenInstruction::ClosePane(PaneId::Terminal(pid))) + .unwrap(); + } + }) +} + +impl PtyBus { + pub fn new( + receive_pty_instructions: Receiver<(PtyInstruction, ErrorContext)>, + send_screen_instructions: SenderWithContext<ScreenInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + os_input: Box<dyn OsApi>, + debug_to_file: bool, + ) -> Self { + PtyBus { + send_screen_instructions, + send_plugin_instructions, + receive_pty_instructions, + os_input, + id_to_child_pid: HashMap::new(), + debug_to_file, + task_handles: HashMap::new(), + } + } + pub fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> RawFd { + let (pid_primary, pid_secondary): (RawFd, RawFd) = + self.os_input.spawn_terminal(file_to_open); + let task_handle = stream_terminal_bytes( + pid_primary, + self.send_screen_instructions.clone(), + self.os_input.clone(), + self.debug_to_file, + ); + self.task_handles.insert(pid_primary, task_handle); + self.id_to_child_pid.insert(pid_primary, pid_secondary); + pid_primary + } + pub fn spawn_terminals_for_layout(&mut self, layout: Layout) { + let total_panes = layout.total_terminal_panes(); + let mut new_pane_pids = vec![]; + for _ in 0..total_panes { + let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(None); + self.id_to_child_pid.insert(pid_primary, pid_secondary); + new_pane_pids.push(pid_primary); + } + self.send_screen_instructions + .send(ScreenInstruction::ApplyLayout(( + layout, + new_pane_pids.clone(), + ))) + .unwrap(); + for id in new_pane_pids { + let task_handle = stream_terminal_bytes( + id, + self.send_screen_instructions.clone(), + self.os_input.clone(), + self.debug_to_file, + ); + self.task_handles.insert(id, task_handle); + } + } + pub fn close_pane(&mut self, id: PaneId) { + match id { + PaneId::Terminal(id) => { + let child_pid = self.id_to_child_pid.remove(&id).unwrap(); + let handle = self.task_handles.remove(&id).unwrap(); + self.os_input.kill(child_pid).unwrap(); + task::block_on(async { + handle.cancel().await; + }); + } + PaneId::Plugin(pid) => drop( + self.send_plugin_instructions + .send(PluginInstruction::Unload(pid)), + ), + } + } + pub fn close_tab(&mut self, ids: Vec<PaneId>) { + ids.iter().for_each(|&id| { + self.close_pane(id); + }); + } +} + +impl Drop for PtyBus { + fn drop(&mut self) { + let child_ids: Vec<RawFd> = self.id_to_child_pid.keys().copied().collect(); + for id in child_ids { + self.close_pane(PaneId::Terminal(id)); + } + } +} diff --git a/src/common/screen.rs b/src/common/screen.rs new file mode 100644 index 00000000..6ae89ddc --- /dev/null +++ b/src/common/screen.rs @@ -0,0 +1,201 @@ +use std::collections::BTreeMap; +use std::os::unix::io::RawFd; +use std::sync::mpsc::Receiver; + +use super::{AppInstruction, SenderWithContext}; +use crate::os_input_output::OsApi; +use crate::panes::PositionAndSize; +use crate::pty_bus::{PtyInstruction, VteEvent}; +use crate::tab::Tab; +use crate::{errors::ErrorContext, wasm_vm::PluginInstruction}; +use crate::{layout::Layout, panes::PaneId}; + +/* + * Screen + * + * this holds multiple tabs, each one holding multiple panes + * it tracks the active tab and controls tab switching, all the rest + * is performed in Tab + * + */ + +#[derive(Debug, Clone)] +pub enum ScreenInstruction { + Pty(RawFd, VteEvent), + Render, + NewPane(PaneId), + HorizontalSplit(PaneId), + VerticalSplit(PaneId), + WriteCharacter(Vec<u8>), + ResizeLeft, + ResizeRight, + ResizeDown, + ResizeUp, + MoveFocus, + MoveFocusLeft, + MoveFocusDown, + MoveFocusUp, + MoveFocusRight, + Quit, + ScrollUp, + ScrollDown, + ClearScroll, + CloseFocusedPane, + ToggleActiveTerminalFullscreen, + SetSelectable(PaneId, bool), + SetMaxHeight(PaneId, usize), + SetInvisibleBorders(PaneId, bool), + ClosePane(PaneId), + ApplyLayout((Layout, Vec<RawFd>)), + NewTab(RawFd), + SwitchTabNext, + SwitchTabPrev, + CloseTab, +} + +pub struct Screen { + pub receiver: Receiver<(ScreenInstruction, ErrorContext)>, + max_panes: Option<usize>, + tabs: BTreeMap<usize, Tab>, + pub send_pty_instructions: SenderWithContext<PtyInstruction>, + pub send_plugin_instructions: SenderWithContext<PluginInstruction>, + pub send_app_instructions: SenderWithContext<AppInstruction>, + full_screen_ws: PositionAndSize, + active_tab_index: Option<usize>, + os_api: Box<dyn OsApi>, +} + +impl Screen { + pub fn new( + receive_screen_instructions: Receiver<(ScreenInstruction, ErrorContext)>, + send_pty_instructions: SenderWithContext<PtyInstruction>, + send_plugin_instructions: SenderWithContext<PluginInstruction>, + send_app_instructions: SenderWithContext<AppInstruction>, + full_screen_ws: &PositionAndSize, + os_api: Box<dyn OsApi>, + max_panes: Option<usize>, + ) -> Self { + Screen { + receiver: receive_screen_instructions, + max_panes, + send_pty_instructions, + send_plugin_instructions, + send_app_instructions, + full_screen_ws: *full_screen_ws, + active_tab_index: None, + tabs: BTreeMap::new(), + os_api, + } + } + pub fn new_tab(&mut self, pane_id: RawFd) { + let tab_index = self.get_next_tab_index(); + let tab = Tab::new( + tab_index, + &self.full_screen_ws, + self.os_api.clone(), + self.send_pty_instructions.clone(), + self.send_plugin_instructions.clone(), + self.send_app_instructions.clone(), + self.max_panes, + Some(PaneId::Terminal(pane_id)), + ); + self.active_tab_index = Some(tab_index); + self.tabs.insert(tab_index, tab); + self.render(); + } + fn get_next_tab_index(&self) -> usize { + if let Some(index) = self.tabs.keys().last() { + *index + 1 + } else { + 0 + } + } + pub fn switch_tab_next(&mut self) { + let active_tab_id = self.get_active_tab().unwrap().index; + let tab_ids: Vec<usize> = self.tabs.keys().copied().collect(); + let first_tab = tab_ids.get(0).unwrap(); + let active_tab_id_position = tab_ids.iter().position(|id| id == &active_tab_id).unwrap(); + if let Some(next_tab) = tab_ids.get(active_tab_id_position + 1) { + self.active_tab_index = Some(*next_tab); + } else { + self.active_tab_index = Some(*first_tab); + } + self.render(); + } + pub fn switch_tab_prev(&mut self) { + let active_tab_id = self.get_active_tab().unwrap().index; + let tab_ids: Vec<usize> = self.tabs.keys().copied().collect(); + let first_tab = tab_ids.get(0).unwrap(); + let last_tab = tab_ids.last().unwrap(); + + let active_tab_id_position = tab_ids.iter().position(|id| id == &active_tab_id).unwrap(); + if active_tab_id == *first_tab { + self.active_tab_index = Some(*last_tab) + } else if let Some(prev_tab) = tab_ids.get(active_tab_id_position - 1) { + self.active_tab_index = Some(*prev_tab) + } + self.render(); + } + pub fn close_tab(&mut self) { + let active_tab_index = self.active_tab_index.unwrap(); + if self.tabs.len() > 1 { + self.switch_tab_prev(); + } + let active_tab = self.tabs.remove(&active_tab_index).unwrap(); + let pane_ids = active_tab.get_pane_ids(); + // below we don't check the result of sending the CloseTab instruction to the pty thread + // because this might be happening when the app is closing, at which point the pty thread + // has already closed and this would result in an error + let _ = self + .send_pty_instructions + .send(PtyInstruction::CloseTab(pane_ids)); + if self.tabs.is_empty() { + self.active_tab_index = None; + self.send_app_instructions + .send(AppInstruction::Exit) + .unwrap(); + } + } + pub fn render(&mut self) { + if let Some(active_tab) = self.get_active_tab_mut() { + if active_tab.get_active_pane().is_some() { + active_tab.render(); + } else { + self.close_tab(); + } + }; + } + + pub fn get_active_tab(&self) -> Option<&Tab> { + match self.active_tab_index { + Some(tab) => self.tabs.get(&tab), + None => None, + } + } + pub fn get_tabs_mut(&mut self) -> &mut BTreeMap<usize, Tab> { + &mut self.tabs + } + pub fn get_active_tab_mut(&mut self) -> Option<&mut Tab> { + let tab = match self.active_tab_index { + Some(tab) => self.get_tabs_mut().get_mut(&tab), + None => None, + }; + tab + } + pub fn apply_layout(&mut self, layout: Layout, new_pids: Vec<RawFd>) { + let tab_index = self.get_next_tab_index(); + let mut tab = Tab::new( + tab_index, + &self.full_screen_ws, + self.os_api.clone(), + self.send_pty_instructions.clone(), + self.send_plugin_instructions.clone(), + self.send_app_instructions.clone(), + self.max_panes, + None, + ); + tab.apply_layout(layout, new_pids); + self.active_tab_index = Some(tab_index); + self.tabs.insert(tab_index, tab); + } +} diff --git a/src/common/utils/consts.rs b/src/common/utils/consts.rs new file mode 100644 index 00000000..7a0c9ddf --- /dev/null +++ b/src/common/utils/consts.rs @@ -0,0 +1,6 @@ +pub const MOSAIC_TMP_DIR: &str = "/tmp/mosaic"; +pub const MOSAIC_TMP_LOG_DIR: &str = "/tmp/mosaic/mosaic-log"; +pub const MOSAIC_TMP_LOG_FILE: &str = "/tmp/mosaic/mosaic-log/log.txt"; +pub const MOSAIC_IPC_PIPE: &str = "/tmp/mosaic/ipc"; +pub const MOSAIC_ROOT_PLUGIN_DIR: &str = "/usr/share/mosaic/plugins"; +pub const MOSAIC_ROOT_LAYOUT_DIR: &str = "/usr/share/mosaic/layouts"; diff --git a/src/common/utils/logging.rs b/src/common/utils/logging.rs new file mode 100644 index 00000000..05af455c --- /dev/null +++ b/src/common/utils/logging.rs @@ -0,0 +1,76 @@ +use std::{ + fs, + io::{self, prelude::*}, + os::unix::io::RawFd, + path::PathBuf, +}; + +use crate::utils::consts::{MOSAIC_TMP_LOG_DIR, MOSAIC_TMP_LOG_FILE}; + +pub fn atomic_create_file(file_name: &str) { + let _ = fs::OpenOptions::new().create(true).open(file_name); +} + +pub fn atomic_create_dir(dir_name: &str) -> io::Result<()> { + if let Err(e) = fs::create_dir(dir_name) { + if e.kind() == std::io::ErrorKind::AlreadyExists { + Ok(()) + } else { + Err(e) + } + } else { + Ok(()) + } +} + +pub fn debug_log_to_file(mut message: String) -> io::Result<()> { + message.push('\n'); + debug_log_to_file_without_newline(message) +} + +pub fn debug_log_to_file_without_newline(message: String) -> io::Result<()> { + atomic_create_file(MOSAIC_TMP_LOG_FILE); + let mut file = fs::OpenOptions::new() + .append(true) + .create(true) + .open(MOSAIC_TMP_LOG_FILE)?; + file.write_all(message.as_bytes()) +} + +pub fn _debug_log_to_file_pid_3(message: String, pid: RawFd) -> io::Result<()> { + if pid == 3 { + debug_log_to_file(message) + } else { + Ok(()) + } +} + +#[allow(dead_code)] +pub fn delete_log_file() -> io::Result<()> { + if fs::metadata(MOSAIC_TMP_LOG_FILE).is_ok() { + fs::remove_file(MOSAIC_TMP_LOG_FILE) + } else { + Ok(()) + } +} + +#[allow(dead_code)] +pub fn delete_log_dir() -> io::Result<()> { + if fs::metadata(MOSAIC_TMP_LOG_DIR).is_ok() { + fs::remove_dir_all(MOSAIC_TMP_LOG_DIR) + } else { + Ok(()) + } +} + +pub fn debug_to_file(message: u8, pid: RawFd) -> io::Result<()> { + let mut path = PathBuf::new(); + path.push(MOSAIC_TMP_LOG_DIR); + path.push(format!("mosaic-{}.log", pid.to_string())); + + let mut file = fs::OpenOptions::new() + .append(true) + .create(true) + .open(path)?; + file.write_all(&[message]) +} diff --git a/src/common/utils/mod.rs b/src/common/utils/mod.rs new file mode 100644 index 00000000..0ea4c76f --- /dev/null +++ b/src/common/utils/mod.rs @@ -0,0 +1,3 @@ +pub mod consts; +pub mod logging; +pub mod shared; diff --git a/src/common/utils/shared.rs b/src/common/utils/shared.rs new file mode 100644 index 00000000..1d8ca5c3 --- /dev/null +++ b/src/common/utils/shared.rs @@ -0,0 +1,19 @@ +use std::{iter, str::from_utf8}; + +use strip_ansi_escapes::strip; + +pub fn ansi_len(s: &str) -> usize { + from_utf8(&strip(s.as_bytes()).unwrap()) + .unwrap() + .chars() + .count() +} + +pub fn pad_to_size(s: &str, rows: usize, columns: usize) -> String { + s.lines() + .map(|l| [l, &str::repeat(" ", columns - ansi_len(l))].concat()) + .chain(iter::repeat(str::repeat(" ", columns))) + .take(rows) + .collect::<Vec<_>>() + .join("\n\r") +} diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs new file mode 100644 index 00000000..c9a236e3 --- /dev/null +++ b/src/common/wasm_vm.rs @@ -0,0 +1,121 @@ +use std::{ + path::PathBuf, + sync::mpsc::{channel, Sender}, +}; +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, +}; + +#[derive(Clone, Debug)] +pub enum PluginInstruction { + Load(Sender<u32>, PathBuf), + Draw(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols + Input(u32, Vec<u8>), // plugin id, input bytes + GlobalInput(Vec<u8>), // input bytes + Unload(u32), + Quit, +} + +#[derive(WasmerEnv, Clone)] +pub struct PluginEnv { + pub plugin_id: u32, + pub send_screen_instructions: SenderWithContext<ScreenInstruction>, + pub send_app_instructions: SenderWithContext<AppInstruction>, + pub send_pty_instructions: SenderWithContext<PtyInstruction>, // FIXME: This should be a big bundle of all of the channels + pub wasi_env: WasiEnv, +} + +// Plugin API --------------------------------------------------------------------------------------------------------- + +pub fn mosaic_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject { + imports! { + "zellij" => { + "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), + } + } +} + +// FIXME: Bundle up all of the channels! Pair that with WasiEnv? +fn host_open_file(plugin_env: &PluginEnv) { + let path = PathBuf::from(wasi_stdout(&plugin_env.wasi_env).lines().next().unwrap()); + plugin_env + .send_pty_instructions + .send(PtyInstruction::SpawnTerminal(Some(path))) + .unwrap(); +} + +// FIXME: Think about these naming conventions – should everything be prefixed by 'host'? +fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { + let selectable = selectable != 0; + plugin_env + .send_screen_instructions + .send(ScreenInstruction::SetSelectable( + PaneId::Plugin(plugin_env.plugin_id), + selectable, + )) + .unwrap() +} + +fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) { + let max_height = max_height as usize; + plugin_env + .send_screen_instructions + .send(ScreenInstruction::SetMaxHeight( + PaneId::Plugin(plugin_env.plugin_id), + max_height, + )) + .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 + // signal and joined one at a time, there would be an order to shutdown, so I + // could get rid of this .is_ok() check and the .try_send() + if plugin_env + .send_app_instructions + .try_send(AppInstruction::GetState(state_tx)) + .is_ok() + { + let help = get_help(&state_rx.recv().unwrap().input_state); + wasi_write_string(&plugin_env.wasi_env, &serde_json::to_string(&help).unwrap()); + } +} + +// Helper Functions --------------------------------------------------------------------------------------------------- + +// FIXME: Unwrap city +pub fn wasi_stdout(wasi_env: &WasiEnv) -> String { + let mut state = wasi_env.state(); + let wasi_file = state.fs.stdout_mut().unwrap().as_mut().unwrap(); + let mut buf = String::new(); + wasi_file.read_to_string(&mut buf).unwrap(); + buf +} + +pub fn wasi_write_string(wasi_env: &WasiEnv, buf: &str) { + let mut state = wasi_env.state(); + let wasi_file = state.fs.stdin_mut().unwrap().as_mut().unwrap(); + writeln!(wasi_file, "{}\r", buf).unwrap(); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..aea289fb --- /dev/null +++ b/src/main.rs @@ -0,0 +1,59 @@ +#[cfg(test)] +mod tests; + +mod cli; +mod common; +// TODO mod server; +mod client; + +use client::{boundaries, layout, panes, tab}; +use common::{ + command_is_executing, errors, ipc, os_input_output, pty_bus, screen, start, utils, wasm_vm, + ApiCommand, +}; + +use std::io::Write; +use std::os::unix::net::UnixStream; + +use structopt::StructOpt; + +use crate::cli::CliArgs; +use crate::command_is_executing::CommandIsExecuting; +use crate::os_input_output::get_os_input; +use crate::pty_bus::VteEvent; +use crate::utils::{ + consts::{MOSAIC_IPC_PIPE, MOSAIC_TMP_DIR, MOSAIC_TMP_LOG_DIR}, + logging::*, +}; + +pub fn main() { + let opts = CliArgs::from_args(); + if let Some(split_dir) = opts.split { + match split_dir { + 'h' => { + let mut stream = UnixStream::connect(MOSAIC_IPC_PIPE).unwrap(); + let api_command = bincode::serialize(&ApiCommand::SplitHorizontally).unwrap(); + stream.write_all(&api_command).unwrap(); + } + 'v' => { + let mut stream = UnixStream::connect(MOSAIC_IPC_PIPE).unwrap(); + let api_command = bincode::serialize(&ApiCommand::SplitVertically).unwrap(); + stream.write_all(&api_command).unwrap(); + } + _ => {} + }; + } else if opts.move_focus { + let mut stream = UnixStream::connect(MOSAIC_IPC_PIPE).unwrap(); + let api_command = bincode::serialize(&ApiCommand::MoveFocus).unwrap(); + stream.write_all(&api_command).unwrap(); + } else if let Some(file_to_open) = opts.open_file { + let mut stream = UnixStream::connect(MOSAIC_IPC_PIPE).unwrap(); + let api_command = bincode::serialize(&ApiCommand::OpenFile(file_to_open)).unwrap(); + stream.write_all(&api_command).unwrap(); + } else { + let os_input = get_os_input(); + atomic_create_dir(MOSAIC_TMP_DIR).unwrap(); + atomic_create_dir(MOSAIC_TMP_LOG_DIR).unwrap(); + start(Box::new(os_input), opts); + } +} diff --git a/src/server/mod.rs b/src/server/mod.rs new file mode 100644 index 00000000..626b4e6b --- /dev/null +++ b/src/server/mod.rs @@ -0,0 +1,5 @@ +use super::super::common::{screen}; + +pub fn start_server() { + // TODO +}
\ No newline at end of file diff --git a/src/tests/fakes.rs b/src/tests/fakes.rs new file mode 100644 index 00000000..fa9c6f0e --- /dev/null +++ b/src/tests/fakes.rs @@ -0,0 +1,205 @@ +use crate::panes::PositionAndSize; +use std::collections::{HashMap, VecDeque}; +use std::io::Write; +use std::os::unix::io::RawFd; +use std::path::PathBuf; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; + +use crate::os_input_output::OsApi; +use crate::tests::possible_tty_inputs::{get_possible_tty_inputs, Bytes}; + +const MIN_TIME_BETWEEN_SNAPSHOTS: Duration = Duration::from_millis(50); + +#[derive(Clone)] +pub enum IoEvent { + Kill(RawFd), + SetTerminalSizeUsingFd(RawFd, u16, u16), + IntoRawMode(RawFd), + UnsetRawMode(RawFd), + TcDrain(RawFd), +} + +#[derive(Clone)] +pub struct FakeStdoutWriter { + output_buffer: Arc<Mutex<Vec<u8>>>, + pub output_frames: Arc<Mutex<Vec<Vec<u8>>>>, + last_snapshot_time: Arc<Mutex<Instant>>, +} + +impl FakeStdoutWriter { + pub fn new(last_snapshot_time: Arc<Mutex<Instant>>) -> Self { + FakeStdoutWriter { + output_buffer: Arc::new(Mutex::new(Vec::new())), + output_frames: Arc::new(Mutex::new(Vec::new())), + last_snapshot_time, + } + } +} + +impl Write for FakeStdoutWriter { + fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> { + let mut bytes_written = 0; + let mut output_buffer = self.output_buffer.lock().unwrap(); + for byte in buf { + bytes_written += 1; + output_buffer.push(*byte); + } + Ok(bytes_written) + } + fn flush(&mut self) -> Result<(), std::io::Error> { + let mut output_buffer = self.output_buffer.lock().unwrap(); + let mut output_frames = self.output_frames.lock().unwrap(); + let new_frame = output_buffer.drain(..).collect(); + output_frames.push(new_frame); + let mut last_snapshot_time = self.last_snapshot_time.lock().unwrap(); + *last_snapshot_time = Instant::now(); + Ok(()) + } +} + +#[derive(Clone)] +pub struct FakeInputOutput { + read_buffers: Arc<Mutex<HashMap<RawFd, Bytes>>>, + input_to_add: Arc<Mutex<Option<Vec<[u8; 10]>>>>, + stdin_commands: Arc<Mutex<VecDeque<Vec<u8>>>>, + stdin_writes: Arc<Mutex<HashMap<RawFd, Vec<u8>>>>, + pub stdout_writer: FakeStdoutWriter, // stdout_writer.output is already an arc/mutex + io_events: Arc<Mutex<Vec<IoEvent>>>, + win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>, + possible_tty_inputs: HashMap<u16, Bytes>, + last_snapshot_time: Arc<Mutex<Instant>>, + started_reading_from_pty: Arc<AtomicBool>, +} + +impl FakeInputOutput { + pub fn new(winsize: PositionAndSize) -> Self { + let mut win_sizes = HashMap::new(); + let last_snapshot_time = Arc::new(Mutex::new(Instant::now())); + let stdout_writer = FakeStdoutWriter::new(last_snapshot_time.clone()); + win_sizes.insert(0, winsize); // 0 is the current terminal + FakeInputOutput { + read_buffers: Arc::new(Mutex::new(HashMap::new())), + stdin_writes: Arc::new(Mutex::new(HashMap::new())), + input_to_add: Arc::new(Mutex::new(None)), + stdin_commands: Arc::new(Mutex::new(VecDeque::new())), + stdout_writer, + last_snapshot_time, + io_events: Arc::new(Mutex::new(vec![])), + win_sizes: Arc::new(Mutex::new(win_sizes)), + possible_tty_inputs: get_possible_tty_inputs(), + started_reading_from_pty: Arc::new(AtomicBool::new(false)), + } + } + pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self { + self.possible_tty_inputs = tty_inputs; + self + } + pub fn add_terminal_input(&mut self, input: &[&[u8]]) { + let mut stdin_commands: VecDeque<Vec<u8>> = VecDeque::new(); + for command in input.iter() { + stdin_commands.push_back(command.iter().copied().collect()) + } + self.stdin_commands = Arc::new(Mutex::new(stdin_commands)); + } + pub fn add_terminal(&mut self, fd: RawFd) { + self.stdin_writes.lock().unwrap().insert(fd, vec![]); + } +} + +impl OsApi for FakeInputOutput { + fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize { + let win_sizes = self.win_sizes.lock().unwrap(); + let winsize = win_sizes.get(&pid).unwrap(); + *winsize + } + fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16) { + let terminal_input = self + .possible_tty_inputs + .get(&cols) + .expect(&format!("could not find input for size {:?}", cols)); + self.read_buffers + .lock() + .unwrap() + .insert(pid, terminal_input.clone()); + self.io_events + .lock() + .unwrap() + .push(IoEvent::SetTerminalSizeUsingFd(pid, cols, rows)); + } + fn set_raw_mode(&mut self, pid: RawFd) { + self.io_events + .lock() + .unwrap() + .push(IoEvent::IntoRawMode(pid)); + } + fn unset_raw_mode(&mut self, pid: RawFd) { + self.io_events + .lock() + .unwrap() + .push(IoEvent::UnsetRawMode(pid)); + } + fn spawn_terminal(&mut self, _file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { + let next_terminal_id = self.stdin_writes.lock().unwrap().keys().len() as RawFd + 1; + self.add_terminal(next_terminal_id); + (next_terminal_id as i32, next_terminal_id + 1000) // secondary number is arbitrary here + } + fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> { + let mut read_buffers = self.read_buffers.lock().unwrap(); + let mut bytes_read = 0; + match read_buffers.get_mut(&pid) { + Some(bytes) => { + for i in bytes.read_position..bytes.content.len() { + bytes_read += 1; + buf[i] = bytes.content[i]; + } + if bytes_read > bytes.read_position { + bytes.set_read_position(bytes_read); + } + self.started_reading_from_pty.store(true, Ordering::Release); + return Ok(bytes_read); + } + None => Err(nix::Error::Sys(nix::errno::Errno::EAGAIN)), + } + } + fn write_to_tty_stdin(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> { + let mut stdin_writes = self.stdin_writes.lock().unwrap(); + let write_buffer = stdin_writes.get_mut(&pid).unwrap(); + let mut bytes_written = 0; + for byte in buf { + bytes_written += 1; + write_buffer.push(*byte); + } + Ok(bytes_written) + } + fn tcdrain(&mut self, pid: RawFd) -> Result<(), nix::Error> { + self.io_events.lock().unwrap().push(IoEvent::TcDrain(pid)); + Ok(()) + } + fn box_clone(&self) -> Box<dyn OsApi> { + Box::new((*self).clone()) + } + fn read_from_stdin(&self) -> Vec<u8> { + loop { + let last_snapshot_time = { *self.last_snapshot_time.lock().unwrap() }; + if last_snapshot_time.elapsed() > MIN_TIME_BETWEEN_SNAPSHOTS { + break; + } else { + ::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS - last_snapshot_time.elapsed()); + } + } + self.stdin_commands + .lock() + .unwrap() + .pop_front() + .unwrap_or(vec![]) + } + fn get_stdout_writer(&self) -> Box<dyn Write> { + Box::new(self.stdout_writer.clone()) + } + fn kill(&mut self, fd: RawFd) -> Result<(), nix::Error> { + self.io_events.lock().unwrap().push(IoEvent::Kill(fd)); + Ok(()) + } +} diff --git a/src/tests/fixtures/bash_cursor_linewrap b/src/tests/fixtures/bash_cursor_linewrap Binary files differnew file mode 100644 index 00000000..2e183a1f --- /dev/null +++ b/src/tests/fixtures/bash_cursor_linewrap diff --git a/src/tests/fixtures/clear_scroll_region b/src/tests/fixtures/clear_scroll_region Binary files differnew file mode 100644 index 00000000..d4741364 --- /dev/null +++ b/src/tests/fixtures/clear_scroll_region diff --git a/src/tests/fixtures/emacs_longbuf_tutorial b/src/tests/fixtures/emacs_longbuf_tutorial Binary files differnew file mode 100644 index 00000000..f383e6d1 --- /dev/null +++ b/src/tests/fixtures/emacs_longbuf_tutorial diff --git a/src/tests/fixtures/fish_and_bandwhich b/src/tests/fixtures/fish_and_bandwhich Binary files differnew file mode 100644 index 00000000..a94dc7ba --- /dev/null +++ b/src/tests/fixtures/fish_and_bandwhich diff --git a/src/tests/fixtures/fish_paste_multiline b/src/tests/fixtures/fish_paste_multiline Binary files differnew file mode 100644 index 00000000..f41187f6 --- /dev/null +++ b/src/tests/fixtures/fish_paste_multiline diff --git a/src/tests/fixtures/fish_select_tab_completion_options b/src/tests/fixtures/fish_select_tab_completion_options Binary files differnew file mode 100644 index 00000000..bab8c6d4 --- /dev/null +++ b/src/tests/fixtures/fish_select_tab_completion_options diff --git a/src/tests/fixtures/fish_tab_completion_options b/src/tests/fixtures/fish_tab_completion_options Binary files differnew file mode 100644 index 00000000..f4ad186b --- /dev/null +++ b/src/tests/fixtures/fish_tab_completion_options diff --git a/src/tests/fixtures/git_diff_scrollup b/src/tests/fixtures/git_diff_scrollup Binary files differnew file mode 100644 index 00000000..98d06baa --- /dev/null +++ b/src/tests/fixtures/git_diff_scrollup diff --git a/src/tests/fixtures/git_log b/src/tests/fixtures/git_log Binary files differnew file mode 100644 index 00000000..9b5bca62 --- /dev/null +++ b/src/tests/fixtures/git_log diff --git a/src/tests/fixtures/htop b/src/tests/fixtures/htop Binary files differnew file mode 100644 index 00000000..37ee0777 --- /dev/null +++ b/src/tests/fixtures/htop diff --git a/src/tests/fixtures/htop_right_scrolling b/src/tests/fixtures/htop_right_scrolling Binary files differnew file mode 100644 index 00000000..f0bcfa5b --- /dev/null +++ b/src/tests/fixtures/htop_right_scrolling diff --git a/src/tests/fixtures/htop_scrolling b/src/tests/fixtures/htop_scrolling Binary files differnew file mode 100644 index 00000000..4e0df629 --- /dev/null +++ b/src/tests/fixtures/htop_scrolling diff --git a/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml b/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml new file mode 100644 index 00000000..e1a1a607 --- /dev/null +++ b/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml @@ -0,0 +1,16 @@ +--- + direction: Horizontal + parts: + - direction: Vertical + parts: + - direction: Horizontal + split_size: + Percent: 20 + - direction: Horizontal + split_size: + Percent: 50 + split_size: + Percent: 80 + - direction: Vertical + split_size: + Percent: 20 diff --git a/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml b/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml new file mode 100644 index 00000000..33d94225 --- /dev/null +++ b/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml @@ -0,0 +1,16 @@ +--- + direction: Horizontal + parts: + - direction: Vertical + parts: + - direction: Horizontal + split_size: + Percent: 20 + - direction: Horizontal + split_size: + Percent: 90 + split_size: + Percent: 80 + - direction: Vertical + split_size: + Percent: 20 diff --git a/src/tests/fixtures/layouts/three-panes-with-nesting.yaml b/src/tests/fixtures/layouts/three-panes-with-nesting.yaml new file mode 100644 index 00000000..f1e0dd7e --- /dev/null +++ b/src/tests/fixtures/layouts/three-panes-with-nesting.yaml @@ -0,0 +1,16 @@ +--- +direction: Horizontal +parts: + - direction: Vertical + parts: + - direction: Horizontal + split_size: + Percent: 20 + - direction: Horizontal + split_size: + Percent: 80 + split_size: + Percent: 80 + - direction: Vertical + split_size: + Percent: 20 diff --git a/src/tests/fixtures/nvim_insert b/src/tests/fixtures/nvim_insert Binary files differnew file mode 100644 index 00000000..4d476275 --- /dev/null +++ b/src/tests/fixtures/nvim_insert diff --git a/src/tests/fixtures/tab_characters b/src/tests/fixtures/tab_characters Binary files differnew file mode 100644 index 00000000..cf40aac5 --- /dev/null +++ b/src/tests/fixtures/tab_characters diff --git a/src/tests/fixtures/vim_ctrl_d b/src/tests/fixtures/vim_ctrl_d Binary files differnew file mode 100644 index 00000000..1f4929b8 --- /dev/null +++ b/src/tests/fixtures/vim_ctrl_d diff --git a/src/tests/fixtures/vim_ctrl_u b/src/tests/fixtures/vim_ctrl_u Binary files differnew file mode 100644 index 00000000..063eb231 --- /dev/null +++ b/src/tests/fixtures/vim_ctrl_u diff --git a/src/tests/fixtures/vim_overwrite b/src/tests/fixtures/vim_overwrite Binary files differnew file mode 100644 index 00000000..3a804d64 --- /dev/null +++ b/src/tests/fixtures/vim_overwrite diff --git a/src/tests/fixtures/vim_scroll_region_down b/src/tests/fixtures/vim_scroll_region_down Binary files differnew file mode 100644 index 00000000..cd2061d2 --- /dev/null +++ b/src/tests/fixtures/vim_scroll_region_down diff --git a/src/tests/integration/basic.rs b/src/tests/integration/basic.rs new file mode 100644 index 00000000..226b08f3 --- /dev/null +++ b/src/tests/integration/basic.rs @@ -0,0 +1,348 @@ +use crate::panes::PositionAndSize; +use ::insta::assert_snapshot; + +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::commands::{ + 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}; + +fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { + FakeInputOutput::new(fake_win_size.clone()) +} + +#[test] +pub fn starts_with_one_terminal() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn split_terminals_vertically() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn split_terminals_horizontally() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn split_largest_terminal() { + // this finds the largest pane and splits along its longest edge (vertically or horizontally) + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() { + let fake_win_size = PositionAndSize { + columns: 8, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 4, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_split_largest_terminal_when_there_is_no_room() { + let fake_win_size = PositionAndSize { + columns: 8, + rows: 4, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPAWN_TERMINAL_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn scrolling_up_inside_a_pane() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn scrolling_down_inside_a_pane() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn max_panes() { + // with the --max-panes option, we only allow a certain amount of panes on screen + // simultaneously, new panes beyond this limit will close older panes on screen + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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(); + opts.max_panes = Some(4); + start(Box::new(fake_input_output.clone()), opts); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn toggle_focused_pane_fullscreen() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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(); + opts.max_panes = Some(4); + start(Box::new(fake_input_output.clone()), opts); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs new file mode 100644 index 00000000..be60fd7c --- /dev/null +++ b/src/tests/integration/close_pane.rs @@ -0,0 +1,647 @@ +use crate::panes::PositionAndSize; +use ::insta::assert_snapshot; + +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(fake_win_size.clone()) +} + +#[test] +pub fn close_pane_with_another_pane_above_it() { + // ┌───────────┐ ┌───────────┐ + // │xxxxxxxxxxx│ │xxxxxxxxxxx│ + // │xxxxxxxxxxx│ │xxxxxxxxxxx│ + // ├───────────┤ ==close==> │xxxxxxxxxxx│ + // │███████████│ │xxxxxxxxxxx│ + // │███████████│ │xxxxxxxxxxx│ + // └───────────┘ └───────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_another_pane_below_it() { + // ┌───────────┐ ┌───────────┐ + // │███████████│ │xxxxxxxxxxx│ + // │███████████│ │xxxxxxxxxxx│ + // ├───────────┤ ==close==> │xxxxxxxxxxx│ + // │xxxxxxxxxxx│ │xxxxxxxxxxx│ + // │xxxxxxxxxxx│ │xxxxxxxxxxx│ + // └───────────┘ └───────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_another_pane_to_the_left() { + // ┌─────┬─────┐ ┌──────────┐ + // │xxxxx│█████│ │xxxxxxxxxx│ + // │xxxxx│█████│ ==close==> │xxxxxxxxxx│ + // │xxxxx│█████│ │xxxxxxxxxx│ + // └─────┴─────┘ └──────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &CLOSE_PANE_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_another_pane_to_the_right() { + // ┌─────┬─────┐ ┌──────────┐ + // │█████│xxxxx│ │xxxxxxxxxx│ + // │█████│xxxxx│ ==close==> │xxxxxxxxxx│ + // │█████│xxxxx│ │xxxxxxxxxx│ + // └─────┴─────┘ └──────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_above_it() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │xxxxx│xxxxx│ │xxxxx│xxxxx│ + // │xxxxx│xxxxx│ │xxxxx│xxxxx│ + // ├─────┴─────┤ ==close==> │xxxxx│xxxxx│ + // │███████████│ │xxxxx│xxxxx│ + // │███████████│ │xxxxx│xxxxx│ + // └───────────┘ └─────┴─────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_below_it() { + // ┌───────────┐ ┌─────┬─────┐ + // │███████████│ │xxxxx│xxxxx│ + // │███████████│ │xxxxx│xxxxx│ + // ├─────┬─────┤ ==close==> │xxxxx│xxxxx│ + // │xxxxx│xxxxx│ │xxxxx│xxxxx│ + // │xxxxx│xxxxx│ │xxxxx│xxxxx│ + // └─────┴─────┘ └─────┴─────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_to_the_left() { + // ┌─────┬─────┐ ┌──────────┐ + // │xxxxx│█████│ │xxxxxxxxxx│ + // │xxxxx│█████│ │xxxxxxxxxx│ + // ├─────┤█████│ ==close==> ├──────────┤ + // │xxxxx│█████│ │xxxxxxxxxx│ + // │xxxxx│█████│ │xxxxxxxxxx│ + // └─────┴─────┘ └──────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_to_the_right() { + // ┌─────┬─────┐ ┌──────────┐ + // │█████│xxxxx│ │xxxxxxxxxx│ + // │█████│xxxxx│ │xxxxxxxxxx│ + // │█████├─────┤ ==close==> ├──────────┤ + // │█████│xxxxx│ │xxxxxxxxxx│ + // │█████│xxxxx│ │xxxxxxxxxx│ + // └─────┴─────┘ └──────────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() { + // ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ + // │xxx│xxx│xxx│xxx│ │xxx│xxx│xxx│xxx│ + // ├───┤xxx│xxx├───┤ ├───┤xxx│xxx├───┤ + // │xxx├───┴───┤xxx│ ==close==> │xxx│xxx│xxx│xxx│ + // │xxx│███████│xxx│ │xxx│xxx│xxx│xxx│ + // │xxx│███████│xxx│ │xxx│xxx│xxx│xxx│ + // └───┴───────┴───┘ └───┴───┴───┴───┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() { + // ┌───┬───────┬───┐ ┌───┬───┬───┬───┐ + // │xxx│███████│xxx│ │xxx│xxx│xxx│xxx│ + // │xxx│███████│xxx│ │xxx│xxx│xxx│xxx│ + // │xxx├───┬───┤xxx│ ==close==> │xxx│xxx│xxx│xxx│ + // ├───┤xxx│xxx├───┤ ├───┤xxx│xxx├───┤ + // │xxx│xxx│xxx│xxx│ │xxx│xxx│xxx│xxx│ + // └───┴───┴───┴───┘ └───┴───┴───┴───┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() { + // ┌────┬──────┐ ┌────┬──────┐ + // │xxxx│xxxxxx│ │xxxx│xxxxxx│ + // ├────┴┬─────┤ ├────┴──────┤ + // │xxxxx│█████│ │xxxxxxxxxxx│ + // ├─────┤█████│ ==close==> ├───────────┤ + // │xxxxx│█████│ │xxxxxxxxxxx│ + // ├────┬┴─────┤ ├────┬──────┤ + // │xxxx│xxxxxx│ │xxxx│xxxxxx│ + // └────┴──────┘ └────┴──────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 30, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() { + // ┌────┬──────┐ ┌────┬──────┐ + // │xxxx│xxxxxx│ │xxxx│xxxxxx│ + // ├────┴┬─────┤ ├────┴──────┤ + // │█████│xxxxx│ │xxxxxxxxxxx│ + // │█████├─────┤ ==close==> ├───────────┤ + // │█████│xxxxx│ │xxxxxxxxxxx│ + // ├────┬┴─────┤ ├────┬──────┤ + // │xxxx│xxxxxx│ │xxxx│xxxxxx│ + // └────┴──────┘ └────┴──────┘ + // █ == pane being closed + let fake_win_size = PositionAndSize { + columns: 121, + rows: 30, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn closing_last_pane_exits_app() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs new file mode 100644 index 00000000..84deea5e --- /dev/null +++ b/src/tests/integration/compatibility.rs @@ -0,0 +1,486 @@ +use ::insta::assert_snapshot; +use ::std::collections::HashMap; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::possible_tty_inputs::Bytes; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{COMMAND_TOGGLE, QUIT}; + +/* + * These tests are general compatibility tests for non-trivial scenarios running in the terminal. + * They use fake TTY input replicated from these scenarios (and so don't actually interact with the + * OS). + * + * They work like this: + * - receive fake TTY input containing various VTE instructions. + * - run that output through mosaic so it interprets it and creates its state based on it + * - read that state into a Human-readable snapshot and compare it to the expected snapshot for + * this scenario. + * + */ + +fn get_fake_os_input(fake_win_size: &PositionAndSize, fixture_name: &str) -> FakeInputOutput { + let mut tty_inputs = HashMap::new(); + let fixture_bytes = Bytes::from_file_in_fixtures(&fixture_name); + tty_inputs.insert(fake_win_size.columns as u16, fixture_bytes); + FakeInputOutput::new(fake_win_size.clone()).with_tty_inputs(tty_inputs) +} + +#[test] +pub fn run_bandwhich_from_fish_shell() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "fish_and_bandwhich"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn fish_tab_completion_options() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "fish_tab_completion_options"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn fish_select_tab_completion_options() { + // the difference between this and the previous test is that here we press <TAB> + // twice, meaning the selection moves between the options and the command line + // changes. + // this is not clearly seen in the snapshot because it does not include styles, + // but we can see the command line change and the cursor staying in place + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "fish_select_tab_completion_options"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn vim_scroll_region_down() { + // here we test a case where vim defines the scroll region as lesser than the screen row count + // and then scrolls down + // the region is defined here by vim as 1-26 (there are 28 rows) + // then the cursor is moved to line 26 and a new line is added + // what should happen is that the first line in the scroll region (1) is deleted + // and an empty line is inserted in the last scroll region line (26) + // this tests also has other steps afterwards that fills the line with the next line in the + // file + // experience appear to the user + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "vim_scroll_region_down"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); // quit (ctrl-q) + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn vim_ctrl_d() { + // in vim ctrl-d moves down half a page + // in this case, it sends the terminal the csi 'M' directive, which tells it to delete X (13 in + // this case) lines inside the scroll region and push the other lines up + // what happens here is that 13 lines are deleted and instead 13 empty lines are added at the + // end of the scroll region + // vim makes sure to fill these empty lines with the rest of the file + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "vim_ctrl_d"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn vim_ctrl_u() { + // in vim ctrl-u moves up half a page + // in this case, it sends the terminal the csi 'L' directive, which tells it to insert X (13 in + // this case) lines at the cursor, pushing away (deleting) the last line in the scroll region + // this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the + // file above the current content) + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "vim_ctrl_u"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn htop() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "htop"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn htop_scrolling() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "htop_scrolling"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn htop_right_scrolling() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "htop_right_scrolling"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn vim_overwrite() { + // this tests the vim overwrite message + // to recreate: + // * open a file in vim + // * open the same file in another window + // * change the file in the other window and save + // * change the file in the original vim window and save + // * confirm you would like to change the file by pressing 'y' and then ENTER + // * if everything looks fine, this test passed :) + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "vim_overwrite"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn clear_scroll_region() { + // this tests the scroll region used by eg. vim is cleared properly + // this means that when vim exits, we get back the previous scroll + // buffer + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "clear_scroll_region"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn display_tab_characters_properly() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "tab_characters"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn neovim_insert_mode() { + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "nvim_insert"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn bash_cursor_linewrap() { + // this test makes sure that when we enter a command that is beyond the screen border, that it + // immediately goes down one line + let fake_win_size = PositionAndSize { + columns: 116, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "bash_cursor_linewrap"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn fish_paste_multiline() { + // here we paste a multiline command in fish shell, making sure we support it + // going up and changing the colors of our line-wrapped pasted text + let fake_win_size = PositionAndSize { + columns: 149, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "fish_paste_multiline"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn git_log() { + let fake_win_size = PositionAndSize { + columns: 149, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "git_log"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn git_diff_scrollup() { + // this tests makes sure that when we have a git diff that exceeds the screen size + // we are able to scroll up + let fake_win_size = PositionAndSize { + columns: 149, + rows: 28, + x: 0, + y: 0, + }; + let fixture_name = "git_diff_scrollup"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn emacs_longbuf() { + let fake_win_size = PositionAndSize { + columns: 284, + rows: 60, + x: 0, + y: 0, + }; + let fixture_name = "emacs_longbuf_tutorial"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/layouts.rs b/src/tests/integration/layouts.rs new file mode 100644 index 00000000..2086ac72 --- /dev/null +++ b/src/tests/integration/layouts.rs @@ -0,0 +1,52 @@ +use insta::assert_snapshot; +use std::path::PathBuf; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::commands::{COMMAND_TOGGLE, QUIT}; +use crate::tests::utils::get_output_frame_snapshots; +use crate::{start, CliArgs}; + +fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput { + FakeInputOutput::new(fake_win_size.clone()) +} + +#[test] +pub fn accepts_basic_layout() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &COMMAND_TOGGLE, &QUIT]); + let mut opts = CliArgs::default(); + opts.layout = Some(PathBuf::from( + "src/tests/fixtures/layouts/three-panes-with-nesting.yaml", + )); + + start(Box::new(fake_input_output.clone()), opts); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + + let snapshot_count = snapshots.len(); + let first_snapshot = snapshots.get(0).unwrap(); + let next_to_last_snapshot = snapshots.get(snapshot_count - 2).unwrap(); + let last_snapshot = snapshots.last().unwrap(); + // here we only test the first, next to last and last snapshot because there's a race condition + // with the other snapshots. Namely all the terminals are created asynchronously and read in an + // async task, so we have no way to guarantee the order in which their bytes will be read, and + // it doesn't really matter in this context. We just want to see that the layout is initially + // created properly and that in the end it's populated properly with its content + // + // we read the next to last as well as the last, because the last includes the "Bye from + // Mosaic" message, and we also want to make sure things are fine before that + assert_snapshot!(first_snapshot); + assert_snapshot!(next_to_last_snapshot); + assert_snapshot!(last_snapshot); +} diff --git a/src/tests/integration/mod.rs b/src/tests/integration/mod.rs new file mode 100644 index 00000000..512db9d0 --- /dev/null +++ b/src/tests/integration/mod.rs @@ -0,0 +1,14 @@ +pub mod basic; +pub mod close_pane; +pub mod compatibility; +pub mod layouts; +pub mod move_focus_down; +pub mod move_focus_left; +pub mod move_focus_right; +pub mod move_focus_up; +pub mod resize_down; +pub mod resize_left; +pub mod resize_right; +pub mod resize_up; +pub mod tabs; +pub mod toggle_fullscreen; diff --git a/src/tests/integration/move_focus_down.rs b/src/tests/integration/move_focus_down.rs new file mode 100644 index 00000000..639078d8 --- /dev/null +++ b/src/tests/integration/move_focus_down.rs @@ -0,0 +1,79 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +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_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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn move_focus_down() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn move_focus_down_to_the_largest_overlap() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/move_focus_left.rs b/src/tests/integration/move_focus_left.rs new file mode 100644 index 00000000..a8e073b9 --- /dev/null +++ b/src/tests/integration/move_focus_left.rs @@ -0,0 +1,79 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +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_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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn move_focus_left() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_RIGHT_IN_PANE_MODE, + &MOVE_FOCUS_LEFT_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn move_focus_left_to_the_largest_overlap() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/move_focus_right.rs b/src/tests/integration/move_focus_right.rs new file mode 100644 index 00000000..72c24a9b --- /dev/null +++ b/src/tests/integration/move_focus_right.rs @@ -0,0 +1,79 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +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_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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn move_focus_right() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn move_focus_right_to_the_largest_overlap() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/move_focus_up.rs b/src/tests/integration/move_focus_up.rs new file mode 100644 index 00000000..fcfedb18 --- /dev/null +++ b/src/tests/integration/move_focus_up.rs @@ -0,0 +1,79 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +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_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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn move_focus_up() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &PANE_MODE, + &SPLIT_DOWN_IN_PANE_MODE, + &MOVE_FOCUS_UP_IN_PANE_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn move_focus_up_to_the_largest_overlap() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/resize_down.rs b/src/tests/integration/resize_down.rs new file mode 100644 index 00000000..ec0221cb --- /dev/null +++ b/src/tests/integration/resize_down.rs @@ -0,0 +1,689 @@ +use insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn resize_down_with_pane_above() { + // ┌───────────┐ ┌───────────┐ + // │ │ │ │ + // │ │ │ │ + // ├───────────┤ ==resize=down==> │ │ + // │███████████│ ├───────────┤ + // │███████████│ │███████████│ + // │███████████│ │███████████│ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_pane_below() { + // ┌───────────┐ ┌───────────┐ + // │███████████│ │███████████│ + // │███████████│ │███████████│ + // ├───────────┤ ==resize=down==> │███████████│ + // │ │ ├───────────┤ + // │ │ │ │ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_above_and_below() { + // ┌───────────┐ ┌───────────┐ + // │ │ │ │ + // │ │ │ │ + // ├───────────┤ │ │ + // │███████████│ ==resize=down==> ├───────────┤ + // │███████████│ │███████████│ + // ├───────────┤ ├───────────┤ + // │ │ │ │ + // │ │ │ │ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_multiple_panes_above() { + // + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┴─────┤ ==resize=down==> │ │ │ + // │███████████│ ├─────┴─────┤ + // │███████████│ │███████████│ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_above_aligned_left_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=down==> ├─────┤ │ + // │ │█████│ │ ├─────┤ + // │ │█████│ │ │█████│ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_below_aligned_left_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │█████│ │ │█████│ + // │ │█████│ │ │█████│ + // ├─────┼─────┤ ==resize=down==> ├─────┤█████│ + // │ │ │ │ ├─────┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_above_aligned_right_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=down==> │ ├─────┤ + // │█████│ │ ├─────┤ │ + // │█████│ │ │█████│ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_below_aligned_right_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │█████│ │ │█████│ │ + // │█████│ │ │█████│ │ + // ├─────┼─────┤ ==resize=down==> │█████├─────┤ + // │ │ │ ├─────┤ │ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() { + // ┌───┬───┬───┐ ┌───┬───┬───┐ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ │ │ │ + // ├───┼───┼───┤ ==resize=down==> ├───┤ ├───┤ + // │ │███│ │ │ ├───┤ │ + // │ │███│ │ │ │███│ │ + // └───┴───┴───┘ └───┴───┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() { + // ┌───┬───┬───┐ ┌───┬───┬───┐ + // │ │███│ │ │ │███│ │ + // │ │███│ │ │ │███│ │ + // ├───┼───┼───┤ ==resize=down==> ├───┤███├───┤ + // │ │ │ │ │ ├───┤ │ + // │ │ │ │ │ │ │ │ + // └───┴───┴───┘ └───┴───┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right() { + // ┌─┬───────┬─┐ ┌─┬───────┬─┐ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ │ │ │ + // ├─┼─┬───┬─┼─┤ ==resize=down==> ├─┤ ├─┤ + // │ │ │███│ │ │ │ ├─┬───┬─┤ │ + // │ │ │███│ │ │ │ │ │███│ │ │ + // └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_right() { + // ┌─┬─┬───┬─┬─┐ ┌─┬─┬───┬─┬─┐ + // │ │ │███│ │ │ │ │ │███│ │ │ + // │ │ │███│ │ │ │ │ │███│ │ │ + // ├─┼─┴───┴─┼─┤ ==resize=down==> ├─┤ │███│ ├─┤ + // │ │ │ │ │ ├─┴───┴─┤ │ + // │ │ │ │ │ │ │ │ + // └─┴───────┴─┘ └─┴───────┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() { + // ┌───────────┐ ┌───────────┐ + // │███████████│ │███████████│ + // ├───────────┤ ==resize=down==> ├───────────┤ + // │ │ │ │ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 5, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/resize_left.rs b/src/tests/integration/resize_left.rs new file mode 100644 index 00000000..9645a4ec --- /dev/null +++ b/src/tests/integration/resize_left.rs @@ -0,0 +1,670 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn resize_left_with_pane_to_the_left() { + // ┌─────┬─────┐ ┌───┬───────┐ + // │ │█████│ │ │███████│ + // │ │█████│ ==resize=left==> │ │███████│ + // │ │█████│ │ │███████│ + // └─────┴─────┘ └───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_pane_to_the_right() { + // ┌─────┬─────┐ ┌───┬───────┐ + // │█████│ │ │███│ │ + // │█████│ │ ==resize=left==> │███│ │ + // │█████│ │ │███│ │ + // └─────┴─────┘ └───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_left_and_right() { + // ┌─────┬─────┬─────┐ ┌─────┬───┬───────┐ + // │ │█████│ │ │ │███│ │ + // │ │█████│ │ ==resize=left==> │ │███│ │ + // │ │█████│ │ │ │███│ │ + // └─────┴─────┴─────┘ └─────┴───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_multiple_panes_to_the_left() { + // ┌─────┬─────┐ ┌───┬───────┐ + // │ │█████│ │ │███████│ + // ├─────┤█████│ ==resize=left==> ├───┤███████│ + // │ │█████│ │ │███████│ + // └─────┴─────┘ └───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=left==> ├───┬─┴─────┤ + // │ │█████│ │ │███████│ + // └─────┴─────┘ └───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=left==> ├───┬─┴─────┤ + // │█████│ │ │███│ │ + // └─────┴─────┘ └───┴───────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌───┬───────┐ + // │ │█████│ │ │███████│ + // ├─────┼─────┤ ==resize=left==> ├───┴─┬─────┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌───┬───────┐ + // │█████│ │ │███│ │ + // ├─────┼─────┤ ==resize=left==> ├───┴─┬─────┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ├───┬─┴─────┤ + // │ │█████│ ==resize=left==> │ │███████│ + // ├─────┼─────┤ ├───┴─┬─────┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ├───┬─┴─────┤ + // │█████│ │ ==resize=left==> │███│ │ + // ├─────┼─────┤ ├───┴─┬─────┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // ├─────┼─────┤ ├───┬─┴─────┤ + // │ ├─────┤ │ ├───────┤ + // │ │█████│ ==resize=left==> │ │███████│ + // │ ├─────┤ │ ├───────┤ + // ├─────┼─────┤ ├───┴─┬─────┤ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // ├─────┼─────┤ ├───┬─┴─────┤ + // ├─────┤ │ ├───┤ │ + // │█████│ │ ==resize=left==> │███│ │ + // ├─────┤ │ ├───┤ │ + // ├─────┼─────┤ ├───┴─┬─────┤ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + // TODO: combine with above + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() { + // ┌─┬─┐ ┌─┬─┐ + // │ │█│ │ │█│ + // │ │█│ ==resize=left==> │ │█│ + // │ │█│ │ │█│ + // └─┴─┘ └─┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 9, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/resize_right.rs b/src/tests/integration/resize_right.rs new file mode 100644 index 00000000..cea8ecda --- /dev/null +++ b/src/tests/integration/resize_right.rs @@ -0,0 +1,670 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn resize_right_with_pane_to_the_left() { + // ┌─────┬─────┐ ┌───────┬───┐ + // │ │█████│ │ │███│ + // │ │█████│ ==resize=right==> │ │███│ + // │ │█████│ │ │███│ + // └─────┴─────┘ └───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_pane_to_the_right() { + // ┌─────┬─────┐ ┌───────┬───┐ + // │█████│ │ │███████│ │ + // │█████│ │ ==resize=right==> │███████│ │ + // │█████│ │ │███████│ │ + // └─────┴─────┘ └───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_left_and_right() { + // ┌─────┬─────┬─────┐ ┌─────┬───────┬───┐ + // │ │█████│ │ │ │███████│ │ + // │ │█████│ │ ==resize=right==> │ │███████│ │ + // │ │█████│ │ │ │███████│ │ + // └─────┴─────┴─────┘ └─────┴───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_multiple_panes_to_the_left() { + // ┌─────┬─────┐ ┌───────┬───┐ + // │ │█████│ │ │███│ + // ├─────┤█████│ ==resize=right==> ├───────┤███│ + // │ │█████│ │ │███│ + // └─────┴─────┘ └───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=right==> ├─────┴─┬───┤ + // │ │█████│ │ │███│ + // └─────┴─────┘ └───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ==resize=right==> ├─────┴─┬───┤ + // │█████│ │ │███████│ │ + // └─────┴─────┘ └───────┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌───────┬───┐ + // │ │█████│ │ │███│ + // ├─────┼─────┤ ==resize=right==> ├─────┬─┴───┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌───────┬───┐ + // │█████│ │ │███████│ │ + // ├─────┼─────┤ ==resize=right==> ├─────┬─┴───┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ├─────┴─┬───┤ + // │ │█████│ ==resize=right==> │ │███│ + // ├─────┼─────┤ ├─────┬─┴───┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // ├─────┼─────┤ ├─────┴─┬───┤ + // │█████│ │ ==resize=right==> │███████│ │ + // ├─────┼─────┤ ├─────┬─┴───┤ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // ├─────┼─────┤ ├─────┴─┬───┤ + // │ ├─────┤ │ ├───┤ + // │ │█████│ ==resize=right==> │ │███│ + // │ ├─────┤ │ ├───┤ + // ├─────┼─────┤ ├─────┬─┴───┤ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // ├─────┼─────┤ ├─────┴─┬───┤ + // ├─────┤ │ ├───────┤ │ + // │█████│ │ ==resize=right==> │███████│ │ + // ├─────┤ │ ├───────┤ │ + // ├─────┼─────┤ ├─────┬─┴───┤ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() { + // ┌─┬─┐ ┌─┬─┐ + // │ │█│ │ │█│ + // │ │█│ ==resize=right==> │ │█│ + // │ │█│ │ │█│ + // └─┴─┘ └─┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 9, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/resize_up.rs b/src/tests/integration/resize_up.rs new file mode 100644 index 00000000..6e9f7813 --- /dev/null +++ b/src/tests/integration/resize_up.rs @@ -0,0 +1,685 @@ +use ::insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn resize_up_with_pane_above() { + // ┌───────────┐ ┌───────────┐ + // │ │ │ │ + // │ │ ├───────────┤ + // ├───────────┤ ==resize=up==> │███████████│ + // │███████████│ │███████████│ + // │███████████│ │███████████│ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_pane_below() { + // ┌───────────┐ ┌───────────┐ + // │███████████│ │███████████│ + // │███████████│ ├───────────┤ + // ├───────────┤ ==resize=up==> │ │ + // │ │ │ │ + // │ │ │ │ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_above_and_below() { + // ┌───────────┐ ┌───────────┐ + // │ │ │ │ + // │ │ ├───────────┤ + // ├───────────┤ │███████████│ + // │███████████│ ==resize=up==> │███████████│ + // │███████████│ │███████████│ + // ├───────────┤ ├───────────┤ + // │ │ │ │ + // │ │ │ │ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_multiple_panes_above() { + // + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ ├─────┴─────┤ + // ├─────┴─────┤ ==resize=up==> │███████████│ + // │███████████│ │███████████│ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_above_aligned_left_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ ├─────┤ + // ├─────┼─────┤ ==resize=up==> ├─────┤█████│ + // │ │█████│ │ │█████│ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_below_aligned_left_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │█████│ │ │█████│ + // │ │█████│ │ ├─────┤ + // ├─────┼─────┤ ==resize=up==> ├─────┤ │ + // │ │ │ │ │ │ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_above_aligned_right_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │ │ │ │ │ │ + // │ │ │ ├─────┤ │ + // ├─────┼─────┤ ==resize=up==> │█████├─────┤ + // │█████│ │ │█████│ │ + // │█████│ │ │█████│ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_below_aligned_right_with_current_pane() { + // ┌─────┬─────┐ ┌─────┬─────┐ + // │█████│ │ │█████│ │ + // │█████│ │ ├─────┤ │ + // ├─────┼─────┤ ==resize=up==> │ ├─────┤ + // │ │ │ │ │ │ + // │ │ │ │ │ │ + // └─────┴─────┘ └─────┴─────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() { + // ┌───┬───┬───┐ ┌───┬───┬───┐ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ ├───┤ │ + // ├───┼───┼───┤ ==resize=up==> ├───┤███├───┤ + // │ │███│ │ │ │███│ │ + // │ │███│ │ │ │███│ │ + // └───┴───┴───┘ └───┴───┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() { + // ┌───┬───┬───┐ ┌───┬───┬───┐ + // │ │███│ │ │ │███│ │ + // │ │███│ │ │ ├───┤ │ + // ├───┼───┼───┤ ==resize=up==> ├───┤ ├───┤ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ │ │ │ + // └───┴───┴───┘ └───┴───┴───┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right() { + // ┌─┬───────┬─┐ ┌─┬───────┬─┐ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ ├─┬───┬─┤ │ + // ├─┼─┬───┬─┼─┤ ==resize=up==> ├─┤ │███│ ├─┤ + // │ │ │███│ │ │ │ │ │███│ │ │ + // │ │ │███│ │ │ │ │ │███│ │ │ + // └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_right() { + // ┌─┬─┬───┬─┬─┐ ┌─┬─┬───┬─┬─┐ + // │ │ │███│ │ │ │ │ │███│ │ │ + // │ │ │███│ │ │ │ ├─┴───┴─┤ │ + // ├─┼─┴───┴─┼─┤ ==resize=up==> ├─┤ ├─┤ + // │ │ │ │ │ │ │ │ + // │ │ │ │ │ │ │ │ + // └─┴───────┴─┘ └─┴───────┴─┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 40, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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, + ]); + + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() { + // ┌───────────┐ ┌───────────┐ + // │ │ │ │ + // ├───────────┤ ==resize=up==> ├───────────┤ + // │███████████│ │███████████│ + // └───────────┘ └───────────┘ + // █ == focused pane + let fake_win_size = PositionAndSize { + columns: 121, + rows: 5, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_largest_terminal_when_there_is_no_room.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_largest_terminal_when_there_is_no_room.snap new file mode 100644 index 00000000..d6b74e46 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_largest_terminal_when_there_is_no_room.snap @@ -0,0 +1,9 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line18-b +line19-b +prompt $ + █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_horizontally_when_active_terminal_is_too_small.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_horizontally_when_active_terminal_is_too_small.snap new file mode 100644 index 00000000..7eaac7a0 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_horizontally_when_active_terminal_is_too_small.snap @@ -0,0 +1,9 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_vertically_when_active_terminal_is_too_small.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_vertically_when_active_terminal_is_too_small.snap new file mode 100644 index 00000000..c9f9eb10 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__cannot_split_terminals_vertically_when_active_terminal_is_too_small.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line2-bb +line3-bb +line4-bb +line5-bb +line6-bb +line7-bb +line8-bb +line9-bb +line10-b +line11-b +line12-b +line13-b +line14-b +line15-b +line16-b +line17-b +line18-b +line19-b +prompt $ + █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__max_panes.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__max_panes.snap new file mode 100644 index 00000000..2f2d2faf --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__max_panes.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_down_inside_a_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_down_inside_a_pane.snap new file mode 100644 index 00000000..8f4ec6e2 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_down_inside_a_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_up_inside_a_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_up_inside_a_pane.snap new file mode 100644 index 00000000..485bde1e --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__scrolling_up_inside_a_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line18-bb█bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__split_largest_terminal.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_largest_terminal.snap new file mode 100644 index 00000000..2f2d2faf --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_largest_terminal.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__split_terminals_horizontally.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_terminals_horizontally.snap new file mode 100644 index 00000000..fab0ca8f --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_terminals_horizontally.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__basic__split_terminals_vertically.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_terminals_vertically.snap new file mode 100644 index 00000000..aaae6b5a --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__split_terminals_vertically.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__starts_with_one_terminal.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__starts_with_one_terminal.snap new file mode 100644 index 00000000..1eec02f4 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__starts_with_one_terminal.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__basic__toggle_focused_pane_fullscreen.snap b/src/tests/integration/snapshots/zellij__tests__integration__basic__toggle_focused_pane_fullscreen.snap new file mode 100644 index 00000000..868e5a95 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__basic__toggle_focused_pane_fullscreen.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/basic.rs +expression: snapshot_before_quit + +--- +line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_above_it.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_above_it.snap new file mode 100644 index 00000000..8ba40bc7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_above_it.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_below_it.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_below_it.snap new file mode 100644 index 00000000..8ba40bc7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_below_it.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_left.snap new file mode 100644 index 00000000..8ba40bc7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_right.snap new file mode 100644 index 00000000..cf7bacf6 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_another_pane_to_the_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it.snap new file mode 100644 index 00000000..05bbb477 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it_away_from_screen_edges.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it_away_from_screen_edges.snap new file mode 100644 index 00000000..ffc59eb5 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_above_it_away_from_screen_edges.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +a │bbbbbbbbbbbbbbb│line1-bbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line2-bbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line3-bbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbb│line4-bbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line5-bbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line6-bbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line7-bbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line17-bbbbbbbb│line8-bbbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤bbbbbbbbbbbbbbb│line9-bbbbbbbb├───────────────────────────── +a │bbbbbbbbbbbbbbb│line10-bbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line11-bbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbb│line12-bbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line13-bbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line14-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line15-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbb│line16-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line17-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line18-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line19-bbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it.snap new file mode 100644 index 00000000..05bbb477 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it_away_from_screen_edges.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it_away_from_screen_edges.snap new file mode 100644 index 00000000..6f546abf --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_below_it_away_from_screen_edges.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line1-bbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line2-bbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line3-bbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbb│line4-bbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line5-bbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line6-bbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line7-bbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbb│line8-bbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line9-bbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line10-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line11-bbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line18-bbbbbbbb│line12-bbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤bbbbbbbbbbbbbbb│line13-bbbbbbb├───────────────────────────── +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line14-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line15-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbb│line16-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line17-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbb│line18-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbb│line19-bbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left.snap new file mode 100644 index 00000000..abd742bc --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left_away_from_screen_edges.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left_away_from_screen_edges.snap new file mode 100644 index 00000000..eb3d6039 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_left_away_from_screen_edges.snap @@ -0,0 +1,35 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────── +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ +──────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────── +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right.snap new file mode 100644 index 00000000..448a074c --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right_away_from_screen_edges.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right_away_from_screen_edges.snap new file mode 100644 index 00000000..eb3d6039 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__close_pane_with_multiple_panes_to_the_right_away_from_screen_edges.snap @@ -0,0 +1,35 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────── +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ +──────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────── +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__close_pane__closing_last_pane_exits_app.snap b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__closing_last_pane_exits_app.snap new file mode 100644 index 00000000..cf7bacf6 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__close_pane__closing_last_pane_exits_app.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/close_pane.rs +expression: snapshot_before_quit + +--- +line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__bash_cursor_linewrap.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__bash_cursor_linewrap.snap new file mode 100644 index 00000000..d657b3e3 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__bash_cursor_linewrap.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +Welcome to fish, the friendly interactive shell +⋊> ~/c/mosaic on main ⨯ bash 16:00:06 +[aram@green mosaic]$ 12345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345 +█ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__clear_scroll_region.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__clear_scroll_region.snap new file mode 100644 index 00000000..2932c549 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__clear_scroll_region.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +Welcome to fish, the friendly interactive shell +⋊> ~/c/mosaic on main ⨯ vim some-file 15:07:22 +⋊> ~/c/mosaic on main ⨯ █ 15:07:29 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap new file mode 100644 index 00000000..ff52b200 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + + OS: 5.9.13-arch1-1 GNU/Linux + Uptime: 10 hours, 42 minutes + Hostname: kingdom + Disk usage: + +df: /run/user/1000/doc: Operation not permitted + / 321G / 514G 66% + /efi 27M / 96M 28% + + Network: + + wlp2s0 192.168.0.3 + +[I] [20:07] kingdom:mosaic (main) | █ + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__emacs_longbuf.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__emacs_longbuf.snap new file mode 100644 index 00000000..4f7e5515 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__emacs_longbuf.snap @@ -0,0 +1,65 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +➜ mosaic git:(mosaic#130) emacs +➜ mosaic git:(mosaic#130) emacs -nw +➜ mosaic git:(mosaic#130) exit +█ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap new file mode 100644 index 00000000..08f59e5a --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + + OS: 5.9.14-arch1-1 GNU/Linux + Uptime: 12 hours, 21 minutes + Hostname: kingdom + Disk usage: + +df: /run/user/1000/doc: Operation not permitted + / 295G / 514G 61% + /efi 27M / 96M 28% + + Network: + + wlp2s0 192.168.0.3 + +[I] [21:58] kingdom:mosaic (main) | echo -ne (\ + df -l -h | grep -E 'dev/(xvda|sd|mapper)' | \ + awk '{printf "\\\\t%s\\\\t%4s / %4s %s\\\\n\n", $6, $3, $2, $5}' | \ + sed -e 's/^\(.*\([8][5-9]\|[9][0-9]\)%.*\)$/\\\\e[0;31m\1\\\\e[0m/' -e 's/^\(.*\([7][5-9]\|[8][0-4]\)%.*\ +)$/\\\\e[0;33m\1\\\\e[0m/' | \ + paste -sd ''\ + )█ + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_select_tab_completion_options.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_select_tab_completion_options.snap new file mode 100644 index 00000000..9a29d950 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_select_tab_completion_options.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +Welcome to fish, the friendly interactive shell +⋊> ~/c/mosaic on main ⨯ sudo badblocks █ 11:32:23 +badblocks (Executable, 33kB) base64 (Executable, 42kB) bash (Executable, 906kB) +bandwhich (Executable, 3.0MB) basename (Executable, 38kB) bashbug (Executable, 6.8kB) +base32 (Executable, 42kB) basenc (Executable, 50kB) bass + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_tab_completion_options.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_tab_completion_options.snap new file mode 100644 index 00000000..006cd485 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_tab_completion_options.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +Welcome to fish, the friendly interactive shell +⋊> ~/c/mosaic on main ⨯ sudo ba█dwhich 11:18:26 +badblocks (Executable, 33kB) base64 (Executable, 42kB) bash (Executable, 906kB) +bandwhich (Executable, 3.0MB) basename (Executable, 38kB) bashbug (Executable, 6.8kB) +base32 (Executable, 42kB) basenc (Executable, 50kB) bass + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_diff_scrollup.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_diff_scrollup.snap new file mode 100644 index 00000000..63123585 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_diff_scrollup.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + +src/terminal_pane/scroll.rs +─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +────────────────────────────────────────────────┐ +use crate::terminal_pane::terminal_character::{ │ +────────────────────────────────────────────────┘ +5 + CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, +}; + +use crate::utils::logging::debug_log_to_file; + +/* + * Scroll + * + +──────────────┐ +impl Scroll { │ +──────────────┘ +663 + pub fn move_current_buffer_to_alternative_buffer(&mut self) { + self.alternative_buffer = Some(self.canonical_lines.drain(..).collect()); + self.alternative_cursor_position = Some(self.cursor_position); + self.cursor_position.reset(); + self.clear_all(); + } +:█ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_log.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_log.snap new file mode 100644 index 00000000..74978bda --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__git_log.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + + * wip: doesn't render when new tab is created? + + * wip: doesnt re-render when a new tab is spawned for now + + * wip: tabs now are a BTreeMap and we can switch between them in both directions + + * wip: I think that should also be here + + * wip: cleanup + + * Spawn a new terminal simultaneously with a new tab + + * Ensure proper Opening and Closing of tabs + + * cleanup + + * more cleanup + + * tests(snapshots): add 'loading' snapshot to each scenario + + * fix(tests): update snapshots + + * Add tests for tabs implementation + + * wip: added tests, moved tab related stuff to a separate file + +:█ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop.snap new file mode 100644 index 00000000..5f37e9ae --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + + 1 [||||| 10.1%] Tasks: 73, 413 thr; 1 running + 2 [||||||| 13.5%] Load average: 1.03 1.07 1.30 + 3 [|||||| 10.8%] Uptime: 22:41:15 + 4 [|||||| 10.6%] + Mem[|||||||||||||||||||||||||||||||||||||3.28G/15.3G] + Swp[ 0K/16.0G] + + PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command + 1352 aram 20 0 3776M 581M 238M S 8.7 3.7 2h01:10 /usr/lib/firefox/firefox + 98777 aram 20 0 537M 6184 4240 S 8.1 0.0 0:00.80 target/debug/mosaic --debug + 1669 aram 20 0 2944M 318M 130M S 8.1 2.0 1h01:33 /usr/lib/firefox/firefox -contentproc -childID 6 -i + 826 aram 9 -11 1581M 15092 11244 S 6.1 0.1 42:21.83 /usr/bin/pulseaudio --daemonize=no + 9419 aram 20 0 533M 7392 3344 S 4.7 0.0 22:01.92 /usr/local/bin/mosaic --max-panes 4 + 98913 aram 20 0 537M 6184 4240 S 3.4 0.0 0:00.31 target/debug/mosaic --debug + 1505 aram 20 0 3187M 329M 206M S 3.4 2.1 23:35.90 /usr/lib/firefox/firefox -contentproc -childID 2 -i + 98912 aram 20 0 537M 6184 4240 S 2.7 0.0 0:00.22 target/debug/mosaic --debug + 1164 aram -6 0 1581M 15092 11244 S 2.7 0.1 21:39.80 /usr/bin/pulseaudio --daemonize=no + 1247 aram 20 0 1184M 292M 84828 S 2.7 1.9 38:01.54 /usr/lib/Xorg -nolisten tcp :0 vt1 -keeptty -auth / + 1475 aram -11 0 3776M 581M 238M S 2.0 3.7 14:27.94 /usr/lib/firefox/firefox + 8574 aram 20 0 2944M 318M 130M S 2.0 2.0 14:36.50 /usr/lib/firefox/firefox -contentproc -childID 6 -i + 1364 aram 20 0 3776M 581M 238M S 2.0 3.7 18:01.89 /usr/lib/firefox/firefox + 1870 aram 20 0 3776M 581M 238M S 2.0 3.7 13:27.06 /usr/lib/firefox/firefox + 9427 aram 20 0 533M 7392 3344 S 2.0 0.0 6:53.47 /usr/local/bin/mosaic --max-panes 4 + 98905 aram 20 0 537M 6184 4240 S 2.0 0.0 0:00.17 target/debug/mosaic --debug + 99272 aram 20 0 8456 4348 3320 R 1.3 0.0 0:00.13 htop + 8611 aram 20 0 2944M 318M 130M S 1.3 2.0 8:17.90 /usr/lib/firefox/firefox -contentproc -childID 6 -i +F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_right_scrolling.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_right_scrolling.snap new file mode 100644 index 00000000..d14a411a --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_right_scrolling.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + + 1 [|||||||||| 16.9%] Tasks: 110, 512 thr; 1 running + 2 [|||||||||| 17.1%] Load average: 1.04 1.30 1.29 + 3 [||||||| 13.9%] Uptime: 6 days, 07:01:39 + 4 [||||||||| 14.9%] + Mem[|||||||||||||||||||||||||||||||||||||8.80G/15.3G] + Swp[| 2.82M/16.0G] + + PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command + 20 0 8576 4508 3356 R 1.3 0.0 0:00.11 htop + 20 0 171M 10868 7804 S 0.0 0.1 2:08.38 /sbin/init + 20 0 107M 29364 28092 S 0.0 0.2 0:03.42 /usr/lib/systemd/systemd-journald + 20 0 32648 9568 6616 S 0.0 0.1 0:01.87 /usr/lib/systemd/systemd-udevd + 20 0 78060 992 856 S 0.0 0.0 0:00.00 /usr/bin/lvmetad -f + 20 0 6952 4356 3492 S 0.0 0.0 0:57.67 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidf + 20 0 14824 7552 5984 S 0.0 0.0 0:12.93 /usr/bin/connmand -n --nodnsproxy + 20 0 17696 7940 6696 S 0.0 0.0 0:01.25 /usr/lib/systemd/systemd-logind + 20 0 1635M 56148 20460 S 0.0 0.3 1:27.24 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 0:38.37 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 0:00.01 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 0:00.00 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 1:47.55 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 1:26.19 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 1:40.77 /usr/bin/dockerd -H fd:// + 20 0 1635M 56148 20460 S 0.0 0.3 1:47.26 /usr/bin/dockerd -H fd:// +F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_scrolling.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_scrolling.snap new file mode 100644 index 00000000..6e34a969 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__htop_scrolling.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +█ + 1 [||||||||||||||||||||||||||||||||||||||||||100.0%] Tasks: 79, 382 thr; 1 running + 2 [ 0.0%] Load average: 1.40 1.43 1.38 + 3 [ 0.0%] Uptime: 2 days, 07:33:50 + 4 [ 0.0%] + Mem[|||||||||||||||||||||||||||||||||||||3.64G/15.3G] + Swp[ 0K/16.0G] + + PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command + 123934 aram 20 0 8444 4384 3364 R 66.7 0.0 0:00.05 htop --delay=100000000000 + 1 root 20 0 171M 11616 8608 S 0.0 0.1 0:56.91 /sbin/init + 268 root 20 0 93324 34340 33072 S 0.0 0.2 0:01.05 /usr/lib/systemd/systemd-journald + 276 root 20 0 32648 10192 7240 S 0.0 0.1 0:01.13 /usr/lib/systemd/systemd-udevd + 286 root 20 0 78060 1132 996 S 0.0 0.0 0:00.00 /usr/bin/lvmetad -f + 343 dbus 20 0 6952 4384 3520 S 0.0 0.0 0:13.85 /usr/bin/dbus-daemon --system --address=systemd: -- + 344 root 20 0 14588 7512 6176 S 0.0 0.0 0:03.21 /usr/bin/connmand -n --nodnsproxy + 345 root 20 0 17696 8372 7128 S 0.0 0.1 0:00.67 /usr/lib/systemd/systemd-logind + 395 root 20 0 1635M 83324 44976 S 0.0 0.5 0:32.43 /usr/bin/dockerd -H fd:// + 396 root 20 0 1635M 83324 44976 S 0.0 0.5 0:00.01 /usr/bin/dockerd -H fd:// + 397 root 20 0 1635M 83324 44976 S 0.0 0.5 0:00.01 /usr/bin/dockerd -H fd:// + 398 root 20 0 1635M 83324 44976 S 0.0 0.5 0:00.00 /usr/bin/dockerd -H fd:// + 399 root 20 0 1635M 83324 44976 S 0.0 0.5 0:00.00 /usr/bin/dockerd -H fd:// + 412 root 20 0 1635M 83324 44976 S 0.0 0.5 0:00.00 /usr/bin/dockerd -H fd:// + 441 root 20 0 1635M 83324 44976 S 0.0 0.5 0:41.35 /usr/bin/dockerd -H fd:// + 442 root 20 0 1635M 83324 44976 S 0.0 0.5 0:33.61 /usr/bin/dockerd -H fd:// + 444 root 20 0 1635M 83324 44976 S 0.0 0.5 0:33.13 /usr/bin/dockerd -H fd:// + 449 root 20 0 1635M 83324 44976 S 0.0 0.5 0:41.39 /usr/bin/dockerd -H fd:// +F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__neovim_insert_mode.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__neovim_insert_mode.snap new file mode 100644 index 00000000..159bfcac --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__neovim_insert_mode.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +line 1 +line 2 +line 3 +line 4 +line 5 +line 6 +line 7 +line 8 +line 9 +█ine 10 +line 11 +line 12 +line 13 +line 14 +line 15 +line 16 +line 17 +line 18 +line 19 +line 20 +line 21 +line 22 +line 23 +line 24 +line 25 +line 26 +some-file 10,1 Top +-- INSERT -- diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__run_bandwhich_from_fish_shell.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__run_bandwhich_from_fish_shell.snap new file mode 100644 index 00000000..e250ba86 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__run_bandwhich_from_fish_shell.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + Total Up / Down: 46Bps / 57Bps +┌Utilization by process name───────────────────────────────────────────────────────────────────────────────────────┐ +│Process Connections Up / Down │ +│ │ +│firefox 3 46Bps / 57Bps │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + Press <SPACE> to pause. Use <TAB> to rearrange tables. (DNS queries hidden). diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_d.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_d.snap new file mode 100644 index 00000000..5f922afd --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_d.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + 3 line14 + 2 line15 + 1 line16 +17 █ine17 + 1 line18 + 2 line19 + 3 line20 + 4 line21 + 5 line22 + 6 line23 + 7 line24 + 8 line25 + 9 line26 + 10 line27 + 11 line28 + 12 line29 + 13 line30 + 14 line31 + 15 line32 + 16 line33 + 17 line34 + 18 line35 + 19 line36 + 20 line37 + 21 line38 + 22 line39 + NORMAL testfile.rs unix | utf-8 | rust 40% 17:1 + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_u.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_u.snap new file mode 100644 index 00000000..f0b76512 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_ctrl_u.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + 22 line4 + 21 line5 + 20 line6 + 19 line7 + 18 line8 + 17 line9 + 16 line10 + 15 line11 + 14 line12 + 13 line13 + 12 line14 + 11 line15 + 10 line16 + 9 line17 + 8 line18 + 7 line19 + 6 line20 + 5 line21 + 4 line22 + 3 line23 + 2 line24 + 1 line25 +26 █ine26 + 1 line27 + 2 line28 + 3 line29 + NORMAL testfile.rs unix | utf-8 | rust 61% 26:1 + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_overwrite.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_overwrite.snap new file mode 100644 index 00000000..8dee61ab --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_overwrite.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +1 █ + 1 line 1 + 2 line 2 + 3 line 3 + 4 line 4 + 5 line 5 + 6 line 6 + 7 line 7 + 8 line 8 + 9 line 9 + 10 line 10 + 11 line 11 + 12 line 12 + 13 line 13 + 14 line 14 + 15 line 15 + 16 line 16 + 17 line 17 + 18 line 18 + 19 line 19 + 20 line 20 + 21 line 21 + 22 line 22 + 23 line 23 + 24 line 24 + 25 line 25 + NORMAL some-file unix | utf-8 | no ft 1% 1:1 + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_scroll_region_down.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_scroll_region_down.snap new file mode 100644 index 00000000..b4a455e3 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__vim_scroll_region_down.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- + 22 line2 + 21 line3 + 20 line4 + 19 line5 + 18 line6 + 17 line7 + 16 line8 + 15 line9 + 14 line10 + 13 line11 + 12 line12 + 11 line13 + 10 line14 + 9 line15 + 8 line16 + 7 line17 + 6 line18 + 5 line19 + 4 line20 + 3 line21 + 2 line22 + 1 line23 +24 █ine24 + 1 line25 + 2 line26 + 3 line27 + NORMAL testfile.rs unix | utf-8 | rust 57% 24:1 + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__layouts__accepts_basic_layout.snap b/src/tests/integration/snapshots/zellij__tests__integration__layouts__accepts_basic_layout.snap new file mode 100644 index 00000000..2f814621 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__layouts__accepts_basic_layout.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/layouts.rs +expression: first_snapshot + +--- +█ │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ +────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────── + + + + diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_down__move_focus_down.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_down__move_focus_down.snap new file mode 100644 index 00000000..3a89bb92 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_down__move_focus_down.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_down.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__move_focus_down__move_focus_down_to_the_largest_overlap.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_down__move_focus_down_to_the_largest_overlap.snap new file mode 100644 index 00000000..24cdf0f5 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_down__move_focus_down_to_the_largest_overlap.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_down.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +────────────────────────────────────────────────────────────┬──────────────────────────────┬───────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left.snap new file mode 100644 index 00000000..ad879d6c --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_left.rs +expression: snapshot_before_quit + +--- +a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left_to_the_largest_overlap.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left_to_the_largest_overlap.snap new file mode 100644 index 00000000..8e35b971 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_left__move_focus_left_to_the_largest_overlap.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right.snap new file mode 100644 index 00000000..fdd7c3d5 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_right.rs +expression: snapshot_before_quit + +--- +a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right_to_the_largest_overlap.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right_to_the_largest_overlap.snap new file mode 100644 index 00000000..0b745b04 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_right__move_focus_right_to_the_largest_overlap.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_right.rs +expression: snapshot_before_quit + +--- +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │prompt $ █ +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +a ├──────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__move_focus_up__move_focus_up.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_up__move_focus_up.snap new file mode 100644 index 00000000..cf6fc8c8 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_up__move_focus_up.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_up.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__move_focus_up__move_focus_up_to_the_largest_overlap.snap b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_up__move_focus_up_to_the_largest_overlap.snap new file mode 100644 index 00000000..f09d8fa6 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__move_focus_up__move_focus_up_to_the_largest_overlap.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/move_focus_up.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ │prompt $ +────────────────────────────────────────────────────────────┴──────────────────────────────┴───────────────────────────── +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__cannot_resize_down_when_pane_below_is_at_minimum_height.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__cannot_resize_down_when_pane_below_is_at_minimum_height.snap new file mode 100644 index 00000000..523612a9 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__cannot_resize_down_when_pane_below_is_at_minimum_height.snap @@ -0,0 +1,10 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_multiple_panes_above.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_multiple_panes_above.snap new file mode 100644 index 00000000..b69d1c29 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_multiple_panes_above.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────── +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_above.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_above.snap new file mode 100644 index 00000000..69a35e27 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_above.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_below.snap new file mode 100644 index 00000000..831b1c52 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_pane_below.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_current_pane.snap new file mode 100644 index 00000000..6a5197f7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line19-bbbbbbbbbbbbbbbbbbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├───────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ │line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────┤line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap new file mode 100644 index 00000000..0cd41085 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +a │line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaa│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ +──────────────────────────────┤ ├───────────────────────────── +line2-bbbbbbbbbbbbbbbbbbbbbbbb│ │line2-bbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbb├──────────┬──────────────────────────────────┬──────────────┤line3-bbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb │line4-bbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb │line5-bbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb │line6-bbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb │line7-bbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbb│line18-bbb│line8-bbbbbbbbbbbbbbbbbbbbbbb │line8-bbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb │line9-bbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb │line10-bbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb │line11-bbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb │line12-bbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb │line13-bbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbb│line14-bbbbbbbbbbbbbbbbbbbbbb │line14-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb │line15-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ █ │prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_with_current_pane.snap new file mode 100644 index 00000000..a6002f87 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_left_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────────────────────────────────── +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_right_with_current_pane.snap new file mode 100644 index 00000000..7a460b4e --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_aligned_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +a ├──────────────────────────────────────────────────────────── +prompt $ │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_and_below.snap new file mode 100644 index 00000000..0d404ed1 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_above_and_below.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_current_pane.snap new file mode 100644 index 00000000..e86d3efe --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line19-bbbbbbbbbbbbbbbbbbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├───────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ █ │line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────┤line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap new file mode 100644 index 00000000..14d9e507 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb │line1-bbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb │line2-bbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb │line3-bbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbb│line4-bbbbbbbbbbbbbbbbbbbbbbb │line4-bbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb │line5-bbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb │line6-bbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb │line7-bbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb │line8-bbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb │line9-bbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaa│line18-bbb│line10-bbbbbbbbbbbbbbbbbbbbbb │line10-bbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb │line11-bbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb │line12-bbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb │line13-bbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb │line14-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb │line15-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbb│line16-bbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │bbbbbbbbbb│prompt $ █ │prompt $ │prompt $ +──────────────────────────────┤bbbbbbbbbb│ │ ├───────────────────────────── +line2-bbbbbbbbbbbbbbbbbbbbbbbb│prompt $ │ │ │line2-bbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbb├──────────┴──────────────────────────────────┴──────────────┤line3-bbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_with_current_pane.snap new file mode 100644 index 00000000..8e8a9688 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_left_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ █ +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────────────────────────────────── +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_right_with_current_pane.snap new file mode 100644 index 00000000..1a90fef7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_down__resize_down_with_panes_below_aligned_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_down.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +a ├──────────────────────────────────────────────────────────── +prompt $ █ │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__cannot_resize_left_when_pane_to_the_left_is_at_minimum_width.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__cannot_resize_left_when_pane_to_the_left_is_at_minimum_width.snap new file mode 100644 index 00000000..214bc8c3 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__cannot_resize_left_when_pane_to_the_left_is_at_minimum_width.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +14-b│lin3 +b │lin4 +line│lin5 +15-b│lin6 +b │lin7 +line│lin8 +16-b│lin9 +b │ln10 +line│ln11 +17-b│ln12 +b │ln13 +line│ln14 +18-b│ln15 +b │ln16 +line│ln17 +19-b│ln18 +b │ln19 +prom│prom +pt $│pt $ + │ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_multiple_panes_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_multiple_panes_to_the_left.snap new file mode 100644 index 00000000..7cc426f7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_multiple_panes_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_left.snap new file mode 100644 index 00000000..7dc8c588 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaa │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_right.snap new file mode 100644 index 00000000..16597014 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_pane_to_the_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaa │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane.snap new file mode 100644 index 00000000..fbf57dd7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap new file mode 100644 index 00000000..6eb2cd18 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap new file mode 100644 index 00000000..02516734 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├────────────────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaa │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │prompt $ █ +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├────────────────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_with_current_pane.snap new file mode 100644 index 00000000..58edf926 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_aligned_top_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_and_right.snap new file mode 100644 index 00000000..4431134f --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_left_and_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbbbbbbbbbbbb │line1-bbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line3-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line5-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbbbbbbbbbbbb │line7-bbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line9-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbbbbbbbbbbbb │line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbbbbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane.snap new file mode 100644 index 00000000..549b15e5 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap new file mode 100644 index 00000000..bdee0bd7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap new file mode 100644 index 00000000..62a92718 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaa │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────┤line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────┤line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┴─────────┬──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_with_current_pane.snap new file mode 100644 index 00000000..654b16d0 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_left__resize_left_with_panes_to_the_right_aligned_top_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_left.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +──────────────────────────────────────────────────┬─────────┴──────────────────────────────────────────────────────────── +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +bbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__cannot_resize_right_when_pane_to_the_left_is_at_minimum_width.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__cannot_resize_right_when_pane_to_the_left_is_at_minimum_width.snap new file mode 100644 index 00000000..9d366dad --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__cannot_resize_right_when_pane_to_the_left_is_at_minimum_width.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +14-b│lin3 +b │lin4 +line│lin5 +15-b│lin6 +b │lin7 +line│lin8 +16-b│lin9 +b │ln10 +line│ln11 +17-b│ln12 +b │ln13 +line│ln14 +18-b│ln15 +b │ln16 +line│ln17 +19-b│ln18 +b │ln19 +prom│prom +pt $│pt $ + │ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_multiple_panes_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_multiple_panes_to_the_left.snap new file mode 100644 index 00000000..56b58e28 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_multiple_panes_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────────────────────────┤bbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_left.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_left.snap new file mode 100644 index 00000000..2e3ea9f7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_left.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_right.snap new file mode 100644 index 00000000..87eb82c7 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_pane_to_the_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane.snap new file mode 100644 index 00000000..9fafc30a --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │prompt $ █ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap new file mode 100644 index 00000000..21cbb652 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │prompt $ █ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap new file mode 100644 index 00000000..87714cef --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_above_and_below.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ├────────────────────────────────────────────────── +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ █ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ├────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_with_current_pane.snap new file mode 100644 index 00000000..1113bb73 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_aligned_top_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_and_right.snap new file mode 100644 index 00000000..fa310617 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_left_and_right.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +a │bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +a │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +a │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane.snap new file mode 100644 index 00000000..7bb38a1a --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ █ │prompt $ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap new file mode 100644 index 00000000..3c65a787 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ █ │prompt $ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap new file mode 100644 index 00000000..2c2a64e0 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_above_and_below.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa │bbbbbbbbbb +prompt $ │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────────────────────────┤bbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ █ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +──────────────────────────────────────────────────────────────────────┤bbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┬─────────┴────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_with_current_pane.snap new file mode 100644 index 00000000..24411c3e --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_right__resize_right_with_panes_to_the_right_aligned_top_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_right.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴─────────┬────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │bbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__cannot_resize_up_when_pane_above_is_at_minimum_height.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__cannot_resize_up_when_pane_above_is_at_minimum_height.snap new file mode 100644 index 00000000..e1f6bee0 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__cannot_resize_up_when_pane_above_is_at_minimum_height.snap @@ -0,0 +1,10 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_multiple_panes_above.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_multiple_panes_above.snap new file mode 100644 index 00000000..cf184ecf --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_multiple_panes_above.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ +────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────── +line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_above.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_above.snap new file mode 100644 index 00000000..877beb41 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_above.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_below.snap new file mode 100644 index 00000000..676082c1 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_pane_below.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_current_pane.snap new file mode 100644 index 00000000..24d805db --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbb +a ├──────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbb├───────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap new file mode 100644 index 00000000..aa571254 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_and_right.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +a │line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbb +a ├──────────┬──────────────────────────────────┬──────────────┤line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │bbbbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb │line1-bbbbbbbb│prompt $ +──────────────────────────────┤bbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb │line2-bbbbbbbb├───────────────────────────── +line2-bbbbbbbbbbbbbbbbbbbbbbbb│line17-bbb│line3-bbbbbbbbbbbbbbbbbbbbbbb │line3-bbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb │line4-bbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb │line5-bbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb │line6-bbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb │line7-bbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb │line8-bbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbb│line18-bbb│line9-bbbbbbbbbbbbbbbbbbbbbbb │line9-bbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb │line10-bbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb │line11-bbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb │line12-bbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb │line13-bbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb │line14-bbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbb│line15-bbbbbbbbbbbbbbbbbbbbbb │line15-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbb│bbbbbbbbbb│prompt $ █ │prompt $ │line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │ │ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_with_current_pane.snap new file mode 100644 index 00000000..463b225f --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_left_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ +a ├──────────────────────────────────────────────────────────── +prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_right_with_current_pane.snap new file mode 100644 index 00000000..dfe97594 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_aligned_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_and_below.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_and_below.snap new file mode 100644 index 00000000..471fe924 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_above_and_below.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_current_pane.snap new file mode 100644 index 00000000..d2ba58b3 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ █ │line18-bbbbbbbbbbbbbbbbbbbbbb +a ├──────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbb│prompt $ +────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbb├───────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap new file mode 100644 index 00000000..dfa9283b --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_right.snap @@ -0,0 +1,45 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb │line3-bbbbbbbb│line1-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb │line4-bbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb │line5-bbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb │line6-bbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line17-aaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb │line7-bbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbb│line8-bbbbbbbbbbbbbbbbbbbbbbb │line8-bbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb │line9-bbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb │line10-bbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb │line11-bbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb │line12-bbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb │line13-bbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbb│line14-bbbbbbbbbbbbbbbbbbbbbb │line14-bbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb │line15-bbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +a │bbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb │line16-bbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb │line17-bbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb │line18-bbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│bbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbb │line19-bbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ │prompt $ █ │prompt $ │line18-bbbbbbbbbbbbbbbbbbbbbb +a ├──────────┴──────────────────────────────────┴──────────────┤line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ +──────────────────────────────┤line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├───────────────────────────── +line2-bbbbbbbbbbbbbbbbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line2-bbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line3-bbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line4-bbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line5-bbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line6-bbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line7-bbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line8-bbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line9-bbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line10-bbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbb│prompt $ │line19-bbbbbbbbbbbbbbbbbbbbbb +prompt $ │ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_with_current_pane.snap new file mode 100644 index 00000000..3e41290c --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_left_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│prompt $ █ +a ├──────────────────────────────────────────────────────────── +prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_right_with_current_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_right_with_current_pane.snap new file mode 100644 index 00000000..fb31ae4b --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__resize_up__resize_up_with_panes_below_aligned_right_with_current_pane.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/resize_up.rs +expression: snapshot_before_quit + +--- +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +────────────────────────────────────────────────────────────┤line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│prompt $ +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb├──────────────────────────────────────────────────────────── +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_last_pane_in_a_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_last_pane_in_a_tab.snap new file mode 100644 index 00000000..5196e5ca --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_last_pane_in_a_tab.snap @@ -0,0 +1,25 @@ +--- +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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_tab.snap new file mode 100644 index 00000000..24ba5565 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_tab.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/tabs.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__tabs__close_the_middle_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_the_middle_tab.snap new file mode 100644 index 00000000..5196e5ca --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_the_middle_tab.snap @@ -0,0 +1,25 @@ +--- +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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap new file mode 100644 index 00000000..24ba5565 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__close_the_tab_that_has_a_pane_in_fullscreen.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/tabs.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__tabs__closing_last_tab_exits_the_app.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__closing_last_tab_exits_the_app.snap new file mode 100644 index 00000000..24ba5565 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__closing_last_tab_exits_the_app.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/tabs.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__tabs__open_new_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__open_new_tab.snap new file mode 100644 index 00000000..5196e5ca --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__open_new_tab.snap @@ -0,0 +1,25 @@ +--- +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 +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__tabs__switch_to_next_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__switch_to_next_tab.snap new file mode 100644 index 00000000..24ba5565 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__switch_to_next_tab.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/tabs.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__tabs__switch_to_prev_tab.snap b/src/tests/integration/snapshots/zellij__tests__integration__tabs__switch_to_prev_tab.snap new file mode 100644 index 00000000..24ba5565 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__tabs__switch_to_prev_tab.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/tabs.rs +expression: snapshot_before_quit + +--- +line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +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/snapshots/zellij__tests__integration__toggle_fullscreen__adding_new_terminal_in_fullscreen.snap b/src/tests/integration/snapshots/zellij__tests__integration__toggle_fullscreen__adding_new_terminal_in_fullscreen.snap new file mode 100644 index 00000000..74cf9c82 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__toggle_fullscreen__adding_new_terminal_in_fullscreen.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/toggle_fullscreen.rs +expression: snapshot_before_quit + +--- +a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │prompt $ +line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├──────────────────────────────────────────────────────────── +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ │prompt $ █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__toggle_fullscreen__move_focus_is_disabled_in_fullscreen.snap b/src/tests/integration/snapshots/zellij__tests__integration__toggle_fullscreen__move_focus_is_disabled_in_fullscreen.snap new file mode 100644 index 00000000..be8af70c --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__toggle_fullscreen__move_focus_is_disabled_in_fullscreen.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/integration/toggle_fullscreen.rs +expression: snapshot_before_quit + +--- +line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +prompt $ █ diff --git a/src/tests/integration/tabs.rs b/src/tests/integration/tabs.rs new file mode 100644 index 00000000..a4a0f52a --- /dev/null +++ b/src/tests/integration/tabs.rs @@ -0,0 +1,322 @@ +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_PANE_IN_PANE_MODE}; +use crate::{start, CliArgs}; + +use crate::tests::utils::commands::{ + 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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn open_new_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn switch_to_prev_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &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, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn switch_to_next_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_last_pane_in_a_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_the_middle_tab() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &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, + &CLOSE_TAB_IN_TAB_MODE, + &QUIT, + ]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn close_the_tab_that_has_a_pane_in_fullscreen() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn closing_last_tab_exits_the_app() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/toggle_fullscreen.rs b/src/tests/integration/toggle_fullscreen.rs new file mode 100644 index 00000000..943e91a5 --- /dev/null +++ b/src/tests/integration/toggle_fullscreen.rs @@ -0,0 +1,77 @@ +use insta::assert_snapshot; + +use crate::panes::PositionAndSize; +use crate::tests::fakes::FakeInputOutput; +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_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 { + FakeInputOutput::new(*fake_win_size) +} + +#[test] +pub fn adding_new_terminal_in_fullscreen() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} + +#[test] +pub fn move_focus_is_disabled_in_fullscreen() { + let fake_win_size = PositionAndSize { + columns: 121, + rows: 20, + x: 0, + y: 0, + }; + let mut fake_input_output = get_fake_os_input(&fake_win_size); + fake_input_output.add_terminal_input(&[ + &COMMAND_TOGGLE, + &COMMAND_TOGGLE, + &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()); + + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 00000000..6e07c96d --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,5 @@ +pub mod fakes; +pub mod integration; +pub mod possible_tty_inputs; +pub mod tty_inputs; +pub mod utils; diff --git a/src/tests/possible_tty_inputs.rs b/src/tests/possible_tty_inputs.rs new file mode 100644 index 00000000..fb1cc5c6 --- /dev/null +++ b/src/tests/possible_tty_inputs.rs @@ -0,0 +1,94 @@ +use crate::tests::tty_inputs::{ + COL_10, COL_121, COL_14, COL_15, COL_19, COL_20, COL_24, COL_29, COL_30, COL_34, COL_39, COL_4, + COL_40, COL_50, COL_60, COL_70, COL_8, COL_9, COL_90, COL_96, +}; +use std::collections::HashMap; +use std::fs; +use std::path::PathBuf; + +#[derive(Clone, Debug)] +pub struct Bytes { + pub content: Vec<u8>, + pub read_position: usize, +} + +impl Bytes { + pub fn new() -> Self { + Bytes { + content: vec![], + read_position: 0, + } + } + pub fn from_file_in_fixtures(file_name: &str) -> Self { + let mut path_to_file = PathBuf::new(); + path_to_file.push("src"); + path_to_file.push("tests"); + path_to_file.push("fixtures"); + path_to_file.push(file_name); + let content = fs::read(path_to_file) + .unwrap_or_else(|_| panic!("could not read fixture {:?}", &file_name)); + Bytes { + content, + read_position: 0, + } + } + pub fn content_from_str(mut self, content: &[&'static str]) -> Self { + let mut content_as_bytes = vec![]; + for line in content { + for char in line.chars() { + content_as_bytes.push(char as u8); + } + } + self.content = content_as_bytes; + self + } + pub fn set_read_position(&mut self, read_position: usize) { + self.read_position = read_position; + } +} + +pub fn get_possible_tty_inputs() -> HashMap<u16, Bytes> { + // the key is the column count for this terminal input + let mut possible_inputs = HashMap::new(); + let col_4_bytes = Bytes::new().content_from_str(&COL_4); + let col_8_bytes = Bytes::new().content_from_str(&COL_8); + let col_9_bytes = Bytes::new().content_from_str(&COL_9); + let col_10_bytes = Bytes::new().content_from_str(&COL_10); + let col_14_bytes = Bytes::new().content_from_str(&COL_14); + let col_15_bytes = Bytes::new().content_from_str(&COL_15); + let col_19_bytes = Bytes::new().content_from_str(&COL_19); + let col_20_bytes = Bytes::new().content_from_str(&COL_20); + let col_24_bytes = Bytes::new().content_from_str(&COL_24); + let col_29_bytes = Bytes::new().content_from_str(&COL_29); + let col_30_bytes = Bytes::new().content_from_str(&COL_30); + let col_34_bytes = Bytes::new().content_from_str(&COL_34); + let col_39_bytes = Bytes::new().content_from_str(&COL_39); + let col_40_bytes = Bytes::new().content_from_str(&COL_40); + let col_50_bytes = Bytes::new().content_from_str(&COL_50); + let col_60_bytes = Bytes::new().content_from_str(&COL_60); + let col_70_bytes = Bytes::new().content_from_str(&COL_70); + let col_90_bytes = Bytes::new().content_from_str(&COL_90); + let col_96_bytes = Bytes::new().content_from_str(&COL_96); + let col_121_bytes = Bytes::new().content_from_str(&COL_121); + possible_inputs.insert(4, col_4_bytes); + possible_inputs.insert(8, col_8_bytes); + possible_inputs.insert(9, col_9_bytes); + possible_inputs.insert(10, col_10_bytes); + possible_inputs.insert(14, col_14_bytes); + possible_inputs.insert(15, col_15_bytes); + possible_inputs.insert(19, col_19_bytes); + possible_inputs.insert(20, col_20_bytes); + possible_inputs.insert(24, col_24_bytes); + possible_inputs.insert(29, col_29_bytes); + possible_inputs.insert(30, col_30_bytes); + possible_inputs.insert(34, col_34_bytes); + possible_inputs.insert(39, col_39_bytes); + possible_inputs.insert(40, col_40_bytes); + possible_inputs.insert(50, col_50_bytes); + possible_inputs.insert(60, col_60_bytes); + possible_inputs.insert(70, col_70_bytes); + possible_inputs.insert(90, col_90_bytes); + possible_inputs.insert(96, col_96_bytes); + possible_inputs.insert(121, col_121_bytes); + possible_inputs +} diff --git a/src/tests/tty_inputs.rs b/src/tests/tty_inputs.rs new file mode 100644 index 00000000..09f67abe --- /dev/null +++ b/src/tests/tty_inputs.rs @@ -0,0 +1,458 @@ +pub const COL_121: [&str; 20] = [ + "line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n", + "prompt $ ", +]; + +pub const COL_4: [&str; 20] = [ + "lin1\r\n", + "lin2\r\n", + "lin3\r\n", + "lin4\r\n", + "lin5\r\n", + "lin6\r\n", + "lin7\r\n", + "lin8\r\n", + "lin9\r\n", + "ln10\r\n", + "ln11\r\n", + "ln12\r\n", + "ln13\r\n", + "ln14\r\n", + "ln15\r\n", + "ln16\r\n", + "ln17\r\n", + "ln18\r\n", + "ln19\r\n", + "prompt $ ", +]; + +pub const COL_8: [&str; 20] = [ + "line1-bb\r\n", + "line2-bb\r\n", + "line3-bb\r\n", + "line4-bb\r\n", + "line5-bb\r\n", + "line6-bb\r\n", + "line7-bb\r\n", + "line8-bb\r\n", + "line9-bb\r\n", + "line10-b\r\n", + "line11-b\r\n", + "line12-b\r\n", + "line13-b\r\n", + "line14-b\r\n", + "line15-b\r\n", + "line16-b\r\n", + "line17-b\r\n", + "line18-b\r\n", + "line19-b\r\n", + "prompt $ ", +]; + +pub const COL_9: [&str; 20] = [ + "line1-bbb\r\n", + "line2-bbb\r\n", + "line3-bbb\r\n", + "line4-bbb\r\n", + "line5-bbb\r\n", + "line6-bbb\r\n", + "line7-bbb\r\n", + "line8-bbb\r\n", + "line9-bbb\r\n", + "line10-bb\r\n", + "line11-bb\r\n", + "line12-bb\r\n", + "line13-bb\r\n", + "line14-bb\r\n", + "line15-bb\r\n", + "line16-bb\r\n", + "line17-bb\r\n", + "line18-bb\r\n", + "line19-bb\r\n", + "prompt $ ", +]; + +pub const COL_10: [&str; 20] = [ + "line1-bbbb\r\n", + "line2-bbbb\r\n", + "line3-bbbb\r\n", + "line4-bbbb\r\n", + "line5-bbbb\r\n", + "line6-bbbb\r\n", + "line7-bbbb\r\n", + "line8-bbbb\r\n", + "line9-bbbb\r\n", + "line10-bbb\r\n", + "line11-bbb\r\n", + "line12-bbb\r\n", + "line13-bbb\r\n", + "line14-bbb\r\n", + "line15-bbb\r\n", + "line16-bbb\r\n", + "line17-bbb\r\n", + "line18-bbb\r\n", + "line19-bbb\r\n", + "prompt $ ", +]; + +pub const COL_14: [&str; 20] = [ + "line1-bbbbbbbb\r\n", + "line2-bbbbbbbb\r\n", + "line3-bbbbbbbb\r\n", + "line4-bbbbbbbb\r\n", + "line5-bbbbbbbb\r\n", + "line6-bbbbbbbb\r\n", + "line7-bbbbbbbb\r\n", + "line8-bbbbbbbb\r\n", + "line9-bbbbbbbb\r\n", + "line10-bbbbbbb\r\n", + "line11-bbbbbbb\r\n", + "line12-bbbbbbb\r\n", + "line13-bbbbbbb\r\n", + "line14-bbbbbbb\r\n", + "line15-bbbbbbb\r\n", + "line16-bbbbbbb\r\n", + "line17-bbbbbbb\r\n", + "line18-bbbbbbb\r\n", + "line19-bbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_15: [&str; 20] = [ + "line1-bbbbbbbbb\r\n", + "line2-bbbbbbbbb\r\n", + "line3-bbbbbbbbb\r\n", + "line4-bbbbbbbbb\r\n", + "line5-bbbbbbbbb\r\n", + "line6-bbbbbbbbb\r\n", + "line7-bbbbbbbbb\r\n", + "line8-bbbbbbbbb\r\n", + "line9-bbbbbbbbb\r\n", + "line10-bbbbbbbb\r\n", + "line11-bbbbbbbb\r\n", + "line12-bbbbbbbb\r\n", + "line13-bbbbbbbb\r\n", + "line14-bbbbbbbb\r\n", + "line15-bbbbbbbb\r\n", + "line16-bbbbbbbb\r\n", + "line17-bbbbbbbb\r\n", + "line18-bbbbbbbb\r\n", + "line19-bbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_19: [&str; 20] = [ + "line1-bbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_20: [&str; 20] = [ + "line1-bbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_24: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; +pub const COL_29: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_30: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_34: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_40: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_39: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_50: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_60: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_70: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_90: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; + +pub const COL_96: [&str; 20] = [ + "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n", + "prompt $ ", +]; diff --git a/src/tests/utils.rs b/src/tests/utils.rs new file mode 100644 index 00000000..587d36fd --- /dev/null +++ b/src/tests/utils.rs @@ -0,0 +1,79 @@ +use crate::panes::PositionAndSize; +use crate::panes::TerminalPane; + +pub fn get_output_frame_snapshots( + output_frames: &[Vec<u8>], + win_size: &PositionAndSize, +) -> Vec<String> { + let mut vte_parser = vte::Parser::new(); + let main_pid = 0; + let mut terminal_output = TerminalPane::new(main_pid, *win_size); + + let mut snapshots = vec![]; + for frame in output_frames.iter() { + for byte in frame.iter() { + vte_parser.advance(&mut terminal_output, *byte); + } + let output_lines = terminal_output.read_buffer_as_lines(); + let cursor_coordinates = terminal_output.cursor_coordinates(); + let mut snapshot = String::new(); + for (line_index, line) in output_lines.iter().enumerate() { + for (character_index, terminal_character) in line.iter().enumerate() { + if let Some((cursor_x, cursor_y)) = cursor_coordinates { + if line_index == cursor_y && character_index == cursor_x { + snapshot.push('█'); + continue; + } + } + snapshot.push(terminal_character.character); + } + if line_index != output_lines.len() - 1 { + snapshot.push('\n'); + } + } + snapshots.push(snapshot); + } + snapshots +} + +pub fn get_next_to_last_snapshot(mut snapshots: Vec<String>) -> Option<String> { + if snapshots.len() < 2 { + None + } else { + Some(snapshots.remove(snapshots.len() - 2)) + } +} + +pub mod commands { + 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 +} |
