aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authora-kenji <aks.kenji@protonmail.com>2021-04-03 21:19:39 +0200
committera-kenji <aks.kenji@protonmail.com>2021-04-03 21:19:39 +0200
commit4f5f189373603d29fc8b042b72aae375efbd0a1c (patch)
treed63b769a0c218d4956316fd3128f96ed33c2d9cf /src
parentMerge branch 'main' of https://github.com/zellij-org/zellij into config-file (diff)
parentAdd Kyle to governance.md (diff)
downloadsl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.tar.gz
sl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.tar.xz
sl0ppij-4f5f189373603d29fc8b042b72aae375efbd0a1c.zip
Merge branch 'main' of https://github.com/zellij-org/zellij into config-file
Diffstat (limited to 'src')
-rw-r--r--src/client/mod.rs1
-rw-r--r--src/client/pane_resizer.rs508
-rw-r--r--src/client/panes/plugin_pane.rs12
-rw-r--r--src/client/panes/terminal_pane.rs12
-rw-r--r--src/client/tab.rs121
-rw-r--r--src/common/errors.rs8
-rw-r--r--src/common/input/handler.rs10
-rw-r--r--src/common/mod.rs24
-rw-r--r--src/common/os_input_output.rs32
-rw-r--r--src/common/screen.rs30
-rw-r--r--src/common/utils/shared.rs13
-rw-r--r--src/tests/fakes.rs38
-rw-r--r--src/tests/integration/close_pane.rs2
-rw-r--r--src/tests/integration/mod.rs1
-rw-r--r--src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_height_increase_with_one_pane.snap25
-rw-r--r--src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_and_height_decrease_with_one_pane.snap25
-rw-r--r--src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_decrease_with_one_pane.snap25
-rw-r--r--src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_increase_with_one_pane.snap25
-rw-r--r--src/tests/integration/terminal_window_resize.rs127
-rw-r--r--src/tests/possible_tty_inputs.rs9
-rw-r--r--src/tests/tty_inputs.rs46
-rw-r--r--src/tests/utils.rs1
22 files changed, 1033 insertions, 62 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 93f35e06..cba12a46 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -1,5 +1,6 @@
pub mod boundaries;
pub mod layout;
+pub mod pane_resizer;
pub mod panes;
pub mod tab;
diff --git a/src/client/pane_resizer.rs b/src/client/pane_resizer.rs
new file mode 100644
index 00000000..007dc33f
--- /dev/null
+++ b/src/client/pane_resizer.rs
@@ -0,0 +1,508 @@
+use crate::os_input_output::OsApi;
+use crate::panes::{PaneId, PositionAndSize};
+use crate::tab::Pane;
+use std::collections::{BTreeMap, HashSet};
+
+pub struct PaneResizer<'a> {
+ panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
+ os_api: &'a mut Box<dyn OsApi>,
+}
+
+// TODO: currently there are some functions here duplicated with Tab
+// the reason for this is that we need to get rid of the expansion_boundary
+// otherwise we'll have a big separation of concerns issue
+// once that is done, all resizing functions should move here
+
+impl<'a> PaneResizer<'a> {
+ pub fn new(
+ panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
+ os_api: &'a mut Box<dyn OsApi>,
+ ) -> Self {
+ PaneResizer { panes, os_api }
+ }
+ pub fn resize(
+ &mut self,
+ mut current_size: PositionAndSize,
+ new_size: PositionAndSize,
+ ) -> Option<(isize, isize)> {
+ // (column_difference, row_difference)
+ let mut successfully_resized = false;
+ let mut column_difference: isize = 0;
+ let mut row_difference: isize = 0;
+ if new_size.columns < current_size.columns {
+ let reduce_by = current_size.columns - new_size.columns;
+ find_reducible_vertical_chain(
+ &self.panes,
+ reduce_by,
+ current_size.columns,
+ current_size.rows,
+ )
+ .map(|panes_to_resize| {
+ self.reduce_panes_left_and_pull_adjacents_left(panes_to_resize, reduce_by);
+ column_difference = new_size.columns as isize - current_size.columns as isize;
+ current_size.columns = (current_size.columns as isize + column_difference) as usize;
+ successfully_resized = true;
+ });
+ } else if new_size.columns > current_size.columns {
+ let increase_by = new_size.columns - current_size.columns;
+ find_increasable_vertical_chain(
+ &self.panes,
+ increase_by,
+ current_size.columns,
+ current_size.rows,
+ )
+ .map(|panes_to_resize| {
+ self.increase_panes_right_and_push_adjacents_right(panes_to_resize, increase_by);
+ column_difference = new_size.columns as isize - current_size.columns as isize;
+ current_size.columns = (current_size.columns as isize + column_difference) as usize;
+ successfully_resized = true;
+ });
+ }
+ if new_size.rows < current_size.rows {
+ let reduce_by = current_size.rows - new_size.rows;
+ find_reducible_horizontal_chain(
+ &self.panes,
+ reduce_by,
+ current_size.columns,
+ current_size.rows,
+ )
+ .map(|panes_to_resize| {
+ self.reduce_panes_up_and_pull_adjacents_up(panes_to_resize, reduce_by);
+ row_difference = new_size.rows as isize - current_size.rows as isize;
+ current_size.rows = (current_size.rows as isize + row_difference) as usize;
+ successfully_resized = true;
+ });
+ } else if new_size.rows > current_size.rows {
+ let increase_by = new_size.rows - current_size.rows;
+ find_increasable_horizontal_chain(
+ &self.panes,
+ increase_by,
+ current_size.columns,
+ current_size.rows,
+ )
+ .map(|panes_to_resize| {
+ self.increase_panes_down_and_push_down_adjacents(panes_to_resize, increase_by);
+ row_difference = new_size.rows as isize - current_size.rows as isize;
+ current_size.rows = (current_size.rows as isize + row_difference) as usize;
+ successfully_resized = true;
+ });
+ }
+ if successfully_resized {
+ Some((column_difference, row_difference))
+ } else {
+ None
+ }
+ }
+ fn reduce_panes_left_and_pull_adjacents_left(
+ &mut self,
+ panes_to_reduce: Vec<PaneId>,
+ reduce_by: usize,
+ ) {
+ let mut pulled_panes: HashSet<PaneId> = HashSet::new();
+ for pane_id in panes_to_reduce {
+ let (pane_x, pane_y, pane_columns, pane_rows) = {
+ let pane = self.panes.get(&pane_id).unwrap();
+ (pane.x(), pane.y(), pane.columns(), pane.rows())
+ };
+ let panes_to_pull = self.panes.values_mut().filter(|p| {
+ p.x() > pane_x + pane_columns
+ && (p.y() <= pane_y && p.y() + p.rows() >= pane_y
+ || p.y() >= pane_y && p.y() + p.rows() <= pane_y + pane_rows)
+ });
+ for pane in panes_to_pull {
+ if !pulled_panes.contains(&pane.pid()) {
+ pane.pull_left(reduce_by);
+ pulled_panes.insert(pane.pid());
+ }
+ }
+ self.reduce_pane_width_left(&pane_id, reduce_by);
+ }
+ }
+ fn reduce_panes_up_and_pull_adjacents_up(
+ &mut self,
+ panes_to_reduce: Vec<PaneId>,
+ reduce_by: usize,
+ ) {
+ let mut pulled_panes: HashSet<PaneId> = HashSet::new();
+ for pane_id in panes_to_reduce {
+ let (pane_x, pane_y, pane_columns, pane_rows) = {
+ let pane = self.panes.get(&pane_id).unwrap();
+ (pane.x(), pane.y(), pane.columns(), pane.rows())
+ };
+ let panes_to_pull = self.panes.values_mut().filter(|p| {
+ p.y() > pane_y + pane_rows
+ && (p.x() <= pane_x && p.x() + p.columns() >= pane_x
+ || p.x() >= pane_x && p.x() + p.columns() <= pane_x + pane_columns)
+ });
+ for pane in panes_to_pull {
+ if !pulled_panes.contains(&pane.pid()) {
+ pane.pull_up(reduce_by);
+ pulled_panes.insert(pane.pid());
+ }
+ }
+ self.reduce_pane_height_up(&pane_id, reduce_by);
+ }
+ }
+ fn increase_panes_down_and_push_down_adjacents(
+ &mut self,
+ panes_to_increase: Vec<PaneId>,
+ increase_by: usize,
+ ) {
+ let mut pushed_panes: HashSet<PaneId> = HashSet::new();
+ for pane_id in panes_to_increase {
+ let (pane_x, pane_y, pane_columns, pane_rows) = {
+ let pane = self.panes.get(&pane_id).unwrap();
+ (pane.x(), pane.y(), pane.columns(), pane.rows())
+ };
+ let panes_to_push = self.panes.values_mut().filter(|p| {
+ p.y() > pane_y + pane_rows
+ && (p.x() <= pane_x && p.x() + p.columns() >= pane_x
+ || p.x() >= pane_x && p.x() + p.columns() <= pane_x + pane_columns)
+ });
+ for pane in panes_to_push {
+ if !pushed_panes.contains(&pane.pid()) {
+ pane.push_down(increase_by);
+ pushed_panes.insert(pane.pid());
+ }
+ }
+ self.increase_pane_height_down(&pane_id, increase_by);
+ }
+ }
+ fn increase_panes_right_and_push_adjacents_right(
+ &mut self,
+ panes_to_increase: Vec<PaneId>,
+ increase_by: usize,
+ ) {
+ let mut pushed_panes: HashSet<PaneId> = HashSet::new();
+ for pane_id in panes_to_increase {
+ let (pane_x, pane_y, pane_columns, pane_rows) = {
+ let pane = self.panes.get(&pane_id).unwrap();
+ (pane.x(), pane.y(), pane.columns(), pane.rows())
+ };
+ let panes_to_push = self.panes.values_mut().filter(|p| {
+ p.x() > pane_x + pane_columns
+ && (p.y() <= pane_y && p.y() + p.rows() >= pane_y
+ || p.y() >= pane_y && p.y() + p.rows() <= pane_y + pane_rows)
+ });
+ for pane in panes_to_push {
+ if !pushed_panes.contains(&pane.pid()) {
+ pane.push_right(increase_by);
+ pushed_panes.insert(pane.pid());
+ }
+ }
+ self.increase_pane_width_right(&pane_id, increase_by);
+ }
+ }
+ fn reduce_pane_height_up(&mut self, id: &PaneId, count: usize) {
+ let pane = self.panes.get_mut(id).unwrap();
+ pane.reduce_height_up(count);
+ if let PaneId::Terminal(pid) = id {
+ self.os_api
+ .set_terminal_size_using_fd(*pid, pane.columns() as u16, pane.rows() as u16);
+ }
+ }
+ fn increase_pane_height_down(&mut self, id: &PaneId, count: usize) {
+ let pane = self.panes.get_mut(id).unwrap();
+ pane.increase_height_down(count);
+ if let PaneId::Terminal(pid) = pane.pid() {
+ self.os_api
+ .set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
+ }
+ }
+ fn increase_pane_width_right(&mut self, id: &PaneId, count: usize) {
+ let pane = self.panes.get_mut(id).unwrap();
+ pane.increase_width_right(count);
+ if let PaneId::Terminal(pid) = pane.pid() {
+ self.os_api
+ .set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
+ }
+ }
+ fn reduce_pane_width_left(&mut self, id: &PaneId, count: usize) {
+ let pane = self.panes.get_mut(id).unwrap();
+ pane.reduce_width_left(count);
+ if let PaneId::Terminal(pid) = pane.pid() {
+ self.os_api
+ .set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
+ }
+ }
+}
+
+fn find_next_increasable_horizontal_pane(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ right_of: &Box<dyn Pane>,
+ increase_by: usize,
+) -> Option<PaneId> {
+ let next_pane_candidates = panes.values().filter(
+ |p| {
+ p.x() == right_of.x() + right_of.columns() + 1
+ && p.horizontally_overlaps_with(right_of.as_ref())
+ }, // TODO: the name here is wrong, it should be vertically_overlaps_with
+ );
+ let resizable_candidates =
+ next_pane_candidates.filter(|p| p.can_increase_height_by(increase_by));
+ resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
+ Some(next_pane) => {
+ let next_pane = panes.get(&next_pane).unwrap();
+ if next_pane.y() < p.y() {
+ next_pane_id
+ } else {
+ Some(p.pid())
+ }
+ }
+ None => Some(p.pid()),
+ })
+}
+
+fn find_next_increasable_vertical_pane(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ below: &Box<dyn Pane>,
+ increase_by: usize,
+) -> Option<PaneId> {
+ let next_pane_candidates = panes.values().filter(
+ |p| p.y() == below.y() + below.rows() + 1 && p.vertically_overlaps_with(below.as_ref()), // TODO: the name here is wrong, it should be horizontally_overlaps_with
+ );
+ let resizable_candidates =
+ next_pane_candidates.filter(|p| p.can_increase_width_by(increase_by));
+ resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
+ Some(next_pane) => {
+ let next_pane = panes.get(&next_pane).unwrap();
+ if next_pane.x() < p.x() {
+ next_pane_id
+ } else {
+ Some(p.pid())
+ }
+ }
+ None => Some(p.pid()),
+ })
+}
+
+fn find_next_reducible_vertical_pane(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ below: &Box<dyn Pane>,
+ reduce_by: usize,
+) -> Option<PaneId> {
+ let next_pane_candidates = panes.values().filter(
+ |p| p.y() == below.y() + below.rows() + 1 && p.vertically_overlaps_with(below.as_ref()), // TODO: the name here is wrong, it should be horizontally_overlaps_with
+ );
+ let resizable_candidates = next_pane_candidates.filter(|p| p.can_reduce_width_by(reduce_by));
+ resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
+ Some(next_pane) => {
+ let next_pane = panes.get(&next_pane).unwrap();
+ if next_pane.x() < p.x() {
+ next_pane_id
+ } else {
+ Some(p.pid())
+ }
+ }
+ None => Some(p.pid()),
+ })
+}
+
+fn find_next_reducible_horizontal_pane(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ right_of: &Box<dyn Pane>,
+ reduce_by: usize,
+) -> Option<PaneId> {
+ let next_pane_candidates = panes.values().filter(
+ |p| {
+ p.x() == right_of.x() + right_of.columns() + 1
+ && p.horizontally_overlaps_with(right_of.as_ref())
+ }, // TODO: the name here is wrong, it should be vertically_overlaps_with
+ );
+ let resizable_candidates = next_pane_candidates.filter(|p| p.can_reduce_height_by(reduce_by));
+ resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
+ Some(next_pane) => {
+ let next_pane = panes.get(&next_pane).unwrap();
+ if next_pane.y() < p.y() {
+ next_pane_id
+ } else {
+ Some(p.pid())
+ }
+ }
+ None => Some(p.pid()),
+ })
+}
+
+fn find_increasable_horizontal_chain(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ increase_by: usize,
+ screen_width: usize,
+ screen_height: usize, // TODO: this is the previous size (make this clearer)
+) -> Option<Vec<PaneId>> {
+ let mut horizontal_coordinate = 0;
+ loop {
+ if horizontal_coordinate == screen_height {
+ return None;
+ }
+
+ match panes
+ .values()
+ .find(|p| p.x() == 0 && p.y() == horizontal_coordinate)
+ {
+ Some(leftmost_pane) => {
+ if !leftmost_pane.can_increase_height_by(increase_by) {
+ horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
+ continue;
+ }
+ let mut panes_to_resize = vec![];
+ let mut current_pane = leftmost_pane;
+ loop {
+ panes_to_resize.push(current_pane.pid());
+ if current_pane.x() + current_pane.columns() == screen_width {
+ return Some(panes_to_resize);
+ }
+ match find_next_increasable_horizontal_pane(panes, &current_pane, increase_by) {
+ Some(next_pane_id) => {
+ current_pane = panes.get(&next_pane_id).unwrap();
+ }
+ None => {
+ horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
+ break;
+ }
+ };
+ }
+ }
+ None => {
+ return None;
+ }
+ }
+ }
+}
+
+fn find_increasable_vertical_chain(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ increase_by: usize,
+ screen_width: usize,
+ screen_height: usize, // TODO: this is the previous size (make this clearer)
+) -> Option<Vec<PaneId>> {
+ let mut vertical_coordinate = 0;
+ loop {
+ if vertical_coordinate == screen_width {
+ return None;
+ }
+
+ match panes
+ .values()
+ .find(|p| p.y() == 0 && p.x() == vertical_coordinate)
+ {
+ Some(topmost_pane) => {
+ if !topmost_pane.can_increase_width_by(increase_by) {
+ vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
+ continue;
+ }
+ let mut panes_to_resize = vec![];
+ let mut current_pane = topmost_pane;
+ loop {
+ panes_to_resize.push(current_pane.pid());
+ if current_pane.y() + current_pane.rows() == screen_height {
+ return Some(panes_to_resize);
+ }
+ match find_next_increasable_vertical_pane(panes, &current_pane, increase_by) {
+ Some(next_pane_id) => {
+ current_pane = panes.get(&next_pane_id).unwrap();
+ }
+ None => {
+ vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
+ break;
+ }
+ };
+ }
+ }
+ None => {
+ return None;
+ }
+ }
+ }
+}
+
+fn find_reducible_horizontal_chain(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ reduce_by: usize,
+ screen_width: usize,
+ screen_height: usize, // TODO: this is the previous size (make this clearer)
+) -> Option<Vec<PaneId>> {
+ let mut horizontal_coordinate = 0;
+ loop {
+ if horizontal_coordinate == screen_height {
+ return None;
+ }
+
+ match panes
+ .values()
+ .find(|p| p.x() == 0 && p.y() == horizontal_coordinate)
+ {
+ Some(leftmost_pane) => {
+ if !leftmost_pane.can_reduce_height_by(reduce_by) {
+ horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
+ continue;
+ }
+ let mut panes_to_resize = vec![];
+ let mut current_pane = leftmost_pane;
+ loop {
+ panes_to_resize.push(current_pane.pid());
+ if current_pane.x() + current_pane.columns() == screen_width {
+ return Some(panes_to_resize);
+ }
+ match find_next_reducible_horizontal_pane(panes, &current_pane, reduce_by) {
+ Some(next_pane_id) => {
+ current_pane = panes.get(&next_pane_id).unwrap();
+ }
+ None => {
+ horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
+ break;
+ }
+ };
+ }
+ }
+ None => {
+ return None;
+ }
+ }
+ }
+}
+
+fn find_reducible_vertical_chain(
+ panes: &BTreeMap<PaneId, Box<dyn Pane>>,
+ increase_by: usize,
+ screen_width: usize,
+ screen_height: usize, // TODO: this is the previous size (make this clearer)
+) -> Option<Vec<PaneId>> {
+ let mut vertical_coordinate = 0;
+ loop {
+ if vertical_coordinate == screen_width {
+ return None;
+ }
+
+ match panes
+ .values()
+ .find(|p| p.y() == 0 && p.x() == vertical_coordinate)
+ {
+ Some(topmost_pane) => {
+ if !topmost_pane.can_reduce_width_by(increase_by) {
+ vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
+ continue;
+ }
+ let mut panes_to_resize = vec![];
+ let mut current_pane = topmost_pane;
+ loop {
+ panes_to_resize.push(current_pane.pid());
+ if current_pane.y() + current_pane.rows() == screen_height {
+ return Some(panes_to_resize);
+ }
+ match find_next_reducible_vertical_pane(panes, &current_pane, increase_by) {
+ Some(next_pane_id) => {
+ current_pane = panes.get(&next_pane_id).unwrap();
+ }
+ None => {
+ vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
+ break;
+ }
+ };
+ }
+ }
+ None => {
+ return None;
+ }
+ }
+ }
+}
diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs
index 4cffff5f..caf49acc 100644
--- a/src/client/panes/plugin_pane.rs
+++ b/src/client/panes/plugin_pane.rs
@@ -173,6 +173,18 @@ impl Pane for PluginPane {
self.position_and_size.columns += count;
self.should_render = true;
}
+ fn push_down(&mut self, count: usize) {
+ self.position_and_size.y += count;
+ }
+ fn push_right(&mut self, count: usize) {
+ self.position_and_size.x += count;
+ }
+ fn pull_left(&mut self, count: usize) {
+ self.position_and_size.x -= count;
+ }
+ fn pull_up(&mut self, count: usize) {
+ self.position_and_size.y -= count;
+ }
fn scroll_up(&mut self, _count: usize) {
unimplemented!()
}
diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs
index f0b15e50..463a33e3 100644
--- a/src/client/panes/terminal_pane.rs
+++ b/src/client/panes/terminal_pane.rs
@@ -282,6 +282,18 @@ impl Pane for TerminalPane {
self.position_and_size.columns += count;
self.reflow_lines();
}
+ fn push_down(&mut self, count: usize) {
+ self.position_and_size.y += count;
+ }
+ fn push_right(&mut self, count: usize) {
+ self.position_and_size.x += count;
+ }
+ fn pull_left(&mut self, count: usize) {
+ self.position_and_size.x -= count;
+ }
+ fn pull_up(&mut self, count: usize) {
+ self.position_and_size.y -= count;
+ }
fn scroll_up(&mut self, count: usize) {
self.grid.move_viewport_up(count);
self.mark_for_rerender();
diff --git a/src/client/tab.rs b/src/client/tab.rs
index 1e56fd8b..695d42cb 100644
--- a/src/client/tab.rs
+++ b/src/client/tab.rs
@@ -2,20 +2,23 @@
//! as well as how they should be resized
use crate::boundaries::colors;
+use crate::client::pane_resizer::PaneResizer;
use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContext};
use crate::layout::Layout;
+use crate::os_input_output::OsApi;
use crate::panes::{PaneId, PositionAndSize, TerminalPane};
use crate::pty_bus::{PtyInstruction, VteEvent};
+use crate::utils::shared::adjust_to_size;
use crate::wasm_vm::PluginInstruction;
use crate::{boundaries::Boundaries, panes::PluginPane};
-use crate::{os_input_output::OsApi, utils::shared::pad_to_size};
+use serde::{Deserialize, Serialize};
use std::os::unix::io::RawFd;
use std::{
cmp::Reverse,
collections::{BTreeMap, HashSet},
};
use std::{io::Write, sync::mpsc::channel};
-use zellij_tile::data::{Event, InputMode};
+use zellij_tile::data::{Event, ModeInfo};
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;
@@ -66,7 +69,17 @@ pub struct Tab {
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
pub send_app_instructions: SenderWithContext<AppInstruction>,
expansion_boundary: Option<PositionAndSize>,
- pub input_mode: InputMode,
+ should_clear_display_before_rendering: bool,
+ pub mode_info: ModeInfo,
+}
+
+#[derive(Clone, Debug, Default, Serialize, Deserialize)]
+pub struct TabData {
+ /* subset of fields to publish to plugins */
+ pub position: usize,
+ pub name: String,
+ pub active: bool,
+ pub mode_info: ModeInfo,
}
// FIXME: Use a struct that has a pane_type enum, to reduce all of the duplication
@@ -99,6 +112,10 @@ pub trait Pane {
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 push_down(&mut self, count: usize);
+ fn push_right(&mut self, count: usize);
+ fn pull_left(&mut self, count: usize);
+ fn pull_up(&mut self, count: usize);
fn scroll_up(&mut self, count: usize);
fn scroll_down(&mut self, count: usize);
fn clear_scroll(&mut self);
@@ -153,6 +170,22 @@ pub trait Pane {
rows: self.rows(),
}
}
+ fn can_increase_height_by(&self, increase_by: usize) -> bool {
+ self.max_height()
+ .map(|max_height| self.rows() + increase_by <= max_height)
+ .unwrap_or(true)
+ }
+ fn can_increase_width_by(&self, increase_by: usize) -> bool {
+ self.max_width()
+ .map(|max_width| self.columns() + increase_by <= max_width)
+ .unwrap_or(true)
+ }
+ fn can_reduce_height_by(&self, reduce_by: usize) -> bool {
+ self.rows() > reduce_by && self.rows() - reduce_by >= self.min_height()
+ }
+ fn can_reduce_width_by(&self, reduce_by: usize) -> bool {
+ self.columns() > reduce_by && self.columns() - reduce_by >= self.min_width()
+ }
fn min_width(&self) -> usize {
MIN_TERMINAL_WIDTH
}
@@ -183,7 +216,7 @@ impl Tab {
send_app_instructions: SenderWithContext<AppInstruction>,
max_panes: Option<usize>,
pane_id: Option<PaneId>,
- input_mode: InputMode,
+ mode_info: ModeInfo,
) -> Self {
let panes = if let Some(PaneId::Terminal(pid)) = pane_id {
let new_terminal = TerminalPane::new(pid, *full_screen_ws);
@@ -213,7 +246,8 @@ impl Tab {
send_pty_instructions,
send_plugin_instructions,
expansion_boundary: None,
- input_mode,
+ should_clear_display_before_rendering: false,
+ mode_info,
}
}
@@ -267,6 +301,13 @@ impl Tab {
self.send_plugin_instructions.clone(),
);
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
+ // Send an initial mode update to the newly loaded plugin only!
+ self.send_plugin_instructions
+ .send(PluginInstruction::Update(
+ Some(pid),
+ Event::ModeUpdate(self.mode_info.clone()),
+ ))
+ .unwrap();
} 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
@@ -623,26 +664,33 @@ impl Tab {
stdout
.write_all(&hide_cursor.as_bytes())
.expect("cannot write to stdout");
- for (kind, terminal) in self.panes.iter_mut() {
- if !self.panes_to_hide.contains(&terminal.pid()) {
- match self.active_terminal.unwrap() == terminal.pid() {
+ if self.should_clear_display_before_rendering {
+ let clear_display = "\u{1b}[2J";
+ stdout
+ .write_all(&clear_display.as_bytes())
+ .expect("cannot write to stdout");
+ self.should_clear_display_before_rendering = false;
+ }
+ for (kind, pane) in self.panes.iter_mut() {
+ if !self.panes_to_hide.contains(&pane.pid()) {
+ match self.active_terminal.unwrap() == pane.pid() {
true => {
- boundaries.add_rect(terminal.as_ref(), self.input_mode, Some(colors::GREEN))
+ boundaries.add_rect(pane.as_ref(), self.mode_info.mode, Some(colors::GREEN))
}
- false => boundaries.add_rect(terminal.as_ref(), self.input_mode, None),
+ false => boundaries.add_rect(pane.as_ref(), self.mode_info.mode, None),
}
- if let Some(vte_output) = terminal.render() {
+ if let Some(vte_output) = pane.render() {
let vte_output = if let PaneId::Terminal(_) = kind {
vte_output
} else {
- pad_to_size(&vte_output, terminal.rows(), terminal.columns())
+ adjust_to_size(&vte_output, pane.rows(), pane.columns())
};
// FIXME: Use Termion for cursor and style clearing?
write!(
stdout,
"\u{1b}[{};{}H\u{1b}[m{}",
- terminal.y() + 1,
- terminal.x() + 1,
+ pane.y() + 1,
+ pane.x() + 1,
vte_output
)
.expect("cannot write to stdout");
@@ -1655,17 +1703,30 @@ impl Tab {
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);
- }
+ pub fn resize_whole_tab(&mut self, new_screen_size: PositionAndSize) {
+ if self.fullscreen_is_active {
+ // this is not ideal but until we get rid of expansion_boundary, it's a necessity
+ self.toggle_active_pane_fullscreen();
}
- self.render();
+ match PaneResizer::new(&mut self.panes, &mut self.os_api)
+ .resize(self.full_screen_ws, new_screen_size)
+ {
+ Some((column_difference, row_difference)) => {
+ self.should_clear_display_before_rendering = true;
+ self.expansion_boundary.as_mut().map(|expansion_boundary| {
+ // TODO: this is not always accurate
+ expansion_boundary.columns =
+ (expansion_boundary.columns as isize + column_difference) as usize;
+ expansion_boundary.rows =
+ (expansion_boundary.rows as isize + row_difference) as usize;
+ });
+ self.full_screen_ws.columns =
+ (self.full_screen_ws.columns as isize + column_difference) as usize;
+ self.full_screen_ws.rows =
+ (self.full_screen_ws.rows as isize + row_difference) as usize;
+ }
+ None => {}
+ };
}
pub fn resize_left(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
@@ -1679,6 +1740,18 @@ impl Tab {
}
self.render();
}
+ 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_down(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
let count = 2;
diff --git a/src/common/errors.rs b/src/common/errors.rs
index f5aeae85..00284cd4 100644
--- a/src/common/errors.rs
+++ b/src/common/errors.rs
@@ -42,7 +42,7 @@ pub fn handle_panic(
msg,
location.file(),
location.line(),
- backtrace
+ backtrace,
),
(Some(location), None) => format!(
"{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked: {}:{}\n\u{1b}[0;0m{:?}",
@@ -200,7 +200,8 @@ pub enum ScreenContext {
CloseTab,
GoToTab,
UpdateTabName,
- ChangeInputMode,
+ TerminalResize,
+ ChangeMode,
}
// FIXME: Just deriving EnumDiscriminants from strum will remove the need for any of this!!!
@@ -241,7 +242,8 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::CloseTab => ScreenContext::CloseTab,
ScreenInstruction::GoToTab(_) => ScreenContext::GoToTab,
ScreenInstruction::UpdateTabName(_) => ScreenContext::UpdateTabName,
- ScreenInstruction::ChangeInputMode(_) => ScreenContext::ChangeInputMode,
+ ScreenInstruction::TerminalResize => ScreenContext::TerminalResize,
+ ScreenInstruction::ChangeMode(_) => ScreenContext::ChangeMode,
}
}
}
diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs
index 0d30530a..7db14d64 100644
--- a/src/common/input/handler.rs
+++ b/src/common/input/handler.rs
@@ -82,9 +82,11 @@ impl InputHandler {
break 'input_loop;
}
}
- termion::event::Event::Mouse(_) | termion::event::Event::Unsupported(_) => {
- unimplemented!("Mouse and unsupported events aren't supported!");
- }
+ termion::event::Event::Mouse(_)
+ | termion::event::Event::Unsupported(_) => {
+ // Mouse and unsupported events aren't implemented yet,
+ // use a NoOp untill then.
+ }
},
Err(err) => panic!("Encountered read error: {:?}", err),
}
@@ -128,7 +130,7 @@ impl InputHandler {
))
.unwrap();
self.send_screen_instructions
- .send(ScreenInstruction::ChangeInputMode(mode))
+ .send(ScreenInstruction::ChangeMode(get_mode_info(mode)))
.unwrap();
self.send_screen_instructions
.send(ScreenInstruction::Render)
diff --git a/src/common/mod.rs b/src/common/mod.rs
index 57c21155..e9b74d58 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -38,7 +38,7 @@ use wasm_vm::PluginEnv;
use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, PluginInstruction};
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
use wasmer_wasi::{Pipe, WasiState};
-use zellij_tile::data::{EventType, InputMode};
+use zellij_tile::data::{EventType, ModeInfo};
#[derive(Serialize, Deserialize, Debug)]
pub enum ApiCommand {
@@ -264,7 +264,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
&full_screen_ws,
os_input,
max_panes,
- InputMode::Normal,
+ ModeInfo::default(),
);
loop {
let (event, mut err_ctx) = screen
@@ -397,8 +397,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
ScreenInstruction::UpdateTabName(c) => {
screen.update_active_tab_name(c);
}
- ScreenInstruction::ChangeInputMode(input_mode) => {
- screen.change_input_mode(input_mode);
+ ScreenInstruction::TerminalResize => {
+ screen.resize_to_screen();
+ }
+ ScreenInstruction::ChangeMode(mode_info) => {
+ screen.change_mode(mode_info);
}
ScreenInstruction::Quit => {
break;
@@ -514,6 +517,19 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
})
.unwrap();
+ let _signal_thread = thread::Builder::new()
+ .name("signal_listener".to_string())
+ .spawn({
+ let os_input = os_input.clone();
+ let send_screen_instructions = send_screen_instructions.clone();
+ move || {
+ os_input.receive_sigwinch(Box::new(move || {
+ let _ = send_screen_instructions.send(ScreenInstruction::TerminalResize);
+ }));
+ }
+ })
+ .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
diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs
index 043a9aea..de0c6a3b 100644
--- a/src/common/os_input_output.rs
+++ b/src/common/os_input_output.rs
@@ -13,6 +13,8 @@ use std::path::PathBuf;
use std::process::{Child, Command};
use std::sync::{Arc, Mutex};
+use signal_hook::{consts::signal::*, iterator::Signals};
+
use std::env;
fn into_raw_mode(pid: RawFd) {
@@ -65,7 +67,7 @@ pub fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) {
/// process exits.
fn handle_command_exit(mut child: Child) {
// register the SIGINT signal (TODO handle more signals)
- let signals = ::signal_hook::iterator::Signals::new(&[::signal_hook::SIGINT]).unwrap();
+ let mut signals = ::signal_hook::iterator::Signals::new(&[SIGINT]).unwrap();
'handle_exit: loop {
// test whether the child process has exited
match child.try_wait() {
@@ -82,10 +84,15 @@ fn handle_command_exit(mut child: Child) {
}
for signal in signals.pending() {
- if signal == signal_hook::SIGINT {
- child.kill().unwrap();
- child.wait().unwrap();
- break 'handle_exit;
+ // FIXME: We need to handle more signals here!
+ #[allow(clippy::single_match)]
+ match signal {
+ SIGINT => {
+ child.kill().unwrap();
+ child.wait().unwrap();
+ break 'handle_exit;
+ }
+ _ => {}
}
}
}
@@ -188,6 +195,7 @@ pub trait OsApi: Send + Sync {
fn get_stdout_writer(&self) -> Box<dyn io::Write>;
/// Returns a [`Box`] pointer to this [`OsApi`] struct.
fn box_clone(&self) -> Box<dyn OsApi>;
+ fn receive_sigwinch(&self, cb: Box<dyn Fn()>);
}
impl OsApi for OsInputOutput {
@@ -238,6 +246,20 @@ impl OsApi for OsInputOutput {
waitpid(Pid::from_raw(pid), None).unwrap();
Ok(())
}
+ fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
+ let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap();
+ for signal in signals.forever() {
+ match signal {
+ SIGWINCH => {
+ cb();
+ }
+ SIGTERM | SIGINT | SIGQUIT => {
+ break;
+ }
+ _ => unreachable!(),
+ }
+ }
+ }
}
impl Clone for Box<dyn OsApi> {
diff --git a/src/common/screen.rs b/src/common/screen.rs
index 5208834a..121f21bd 100644
--- a/src/common/screen.rs
+++ b/src/common/screen.rs
@@ -13,7 +13,7 @@ use crate::tab::Tab;
use crate::{errors::ErrorContext, wasm_vm::PluginInstruction};
use crate::{layout::Layout, panes::PaneId};
-use zellij_tile::data::{Event, InputMode, TabInfo};
+use zellij_tile::data::{Event, ModeInfo, TabInfo};
/// Instructions that can be sent to the [`Screen`].
#[derive(Debug, Clone)]
@@ -50,7 +50,8 @@ pub enum ScreenInstruction {
CloseTab,
GoToTab(u32),
UpdateTabName(Vec<u8>),
- ChangeInputMode(InputMode),
+ TerminalResize,
+ ChangeMode(ModeInfo),
}
/// A [`Screen`] holds multiple [`Tab`]s, each one holding multiple [`panes`](crate::client::panes).
@@ -74,7 +75,7 @@ pub struct Screen {
active_tab_index: Option<usize>,
/// The [`OsApi`] this [`Screen`] uses.
os_api: Box<dyn OsApi>,
- input_mode: InputMode,
+ mode_info: ModeInfo,
}
impl Screen {
@@ -87,7 +88,7 @@ impl Screen {
full_screen_ws: &PositionAndSize,
os_api: Box<dyn OsApi>,
max_panes: Option<usize>,
- input_mode: InputMode,
+ mode_info: ModeInfo,
) -> Self {
Screen {
receiver: receive_screen_instructions,
@@ -99,7 +100,7 @@ impl Screen {
active_tab_index: None,
tabs: BTreeMap::new(),
os_api,
- input_mode,
+ mode_info,
}
}
@@ -119,7 +120,7 @@ impl Screen {
self.send_app_instructions.clone(),
self.max_panes,
Some(PaneId::Terminal(pane_id)),
- self.input_mode,
+ self.mode_info.clone(),
);
self.active_tab_index = Some(tab_index);
self.tabs.insert(tab_index, tab);
@@ -213,6 +214,15 @@ impl Screen {
}
}
+ pub fn resize_to_screen(&mut self) {
+ let new_screen_size = self.os_api.get_terminal_size_using_fd(0);
+ self.full_screen_ws = new_screen_size;
+ for (_, tab) in self.tabs.iter_mut() {
+ tab.resize_whole_tab(new_screen_size);
+ }
+ self.render();
+ }
+
/// Renders this [`Screen`], which amounts to rendering its active [`Tab`].
pub fn render(&mut self) {
if let Some(active_tab) = self.get_active_tab_mut() {
@@ -261,7 +271,7 @@ impl Screen {
self.send_app_instructions.clone(),
self.max_panes,
None,
- self.input_mode,
+ self.mode_info.clone(),
);
tab.apply_layout(layout, new_pids);
self.active_tab_index = Some(tab_index);
@@ -301,10 +311,10 @@ impl Screen {
}
self.update_tabs();
}
- pub fn change_input_mode(&mut self, input_mode: InputMode) {
- self.input_mode = input_mode;
+ pub fn change_mode(&mut self, mode_info: ModeInfo) {
+ self.mode_info = mode_info;
for tab in self.tabs.values_mut() {
- tab.input_mode = self.input_mode;
+ tab.mode_info = self.mode_info.clone();
}
}
}
diff --git a/src/common/utils/shared.rs b/src/common/utils/shared.rs
index 9717837a..93892d4f 100644
--- a/src/common/utils/shared.rs
+++ b/src/common/utils/shared.rs
@@ -11,9 +11,18 @@ fn ansi_len(s: &str) -> usize {
.count()
}
-pub fn pad_to_size(s: &str, rows: usize, columns: usize) -> String {
+pub fn adjust_to_size(s: &str, rows: usize, columns: usize) -> String {
s.lines()
- .map(|l| [l, &str::repeat(" ", columns - ansi_len(l))].concat())
+ .map(|l| {
+ let actual_len = ansi_len(l);
+ if actual_len > columns {
+ let mut line = String::from(l);
+ line.truncate(columns);
+ return line;
+ } else {
+ return [l, &str::repeat(" ", columns - ansi_len(l))].concat();
+ }
+ })
.chain(iter::repeat(str::repeat(" ", columns)))
.take(rows)
.collect::<Vec<_>>()
diff --git a/src/tests/fakes.rs b/src/tests/fakes.rs
index c800de97..c9504a98 100644
--- a/src/tests/fakes.rs
+++ b/src/tests/fakes.rs
@@ -3,14 +3,13 @@ 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::sync::{Arc, Condvar, Mutex};
use std::time::{Duration, Instant};
use crate::os_input_output::OsApi;
use crate::tests::possible_tty_inputs::{get_possible_tty_inputs, Bytes};
-use crate::tests::utils::commands::SLEEP;
+use crate::tests::utils::commands::{QUIT, SLEEP};
const MIN_TIME_BETWEEN_SNAPSHOTS: Duration = Duration::from_millis(50);
@@ -72,7 +71,8 @@ pub struct FakeInputOutput {
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>,
+ should_trigger_sigwinch: Arc<(Mutex<bool>, Condvar)>,
+ sigwinch_event: Option<PositionAndSize>,
}
impl FakeInputOutput {
@@ -91,7 +91,8 @@ impl FakeInputOutput {
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)),
+ should_trigger_sigwinch: Arc::new((Mutex::new(false), Condvar::new())),
+ sigwinch_event: None,
}
}
pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self {
@@ -108,10 +109,20 @@ impl FakeInputOutput {
pub fn add_terminal(&mut self, fd: RawFd) {
self.stdin_writes.lock().unwrap().insert(fd, vec![]);
}
+ pub fn add_sigwinch_event(&mut self, new_position_and_size: PositionAndSize) {
+ self.sigwinch_event = Some(new_position_and_size);
+ }
}
impl OsApi for FakeInputOutput {
fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize {
+ if let Some(new_position_and_size) = self.sigwinch_event {
+ let (lock, _cvar) = &*self.should_trigger_sigwinch;
+ let should_trigger_sigwinch = lock.lock().unwrap();
+ if *should_trigger_sigwinch && pid == 0 {
+ return new_position_and_size;
+ }
+ }
let win_sizes = self.win_sizes.lock().unwrap();
let winsize = win_sizes.get(&pid).unwrap();
*winsize
@@ -159,7 +170,6 @@ impl OsApi for FakeInputOutput {
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)),
@@ -199,6 +209,12 @@ impl OsApi for FakeInputOutput {
.unwrap_or(vec![]);
if command == SLEEP {
std::thread::sleep(std::time::Duration::from_millis(200));
+ } else if command == QUIT && self.sigwinch_event.is_some() {
+ let (lock, cvar) = &*self.should_trigger_sigwinch;
+ let mut should_trigger_sigwinch = lock.lock().unwrap();
+ *should_trigger_sigwinch = true;
+ cvar.notify_one();
+ ::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS); // give some time for the app to resize before quitting
}
command
}
@@ -209,4 +225,14 @@ impl OsApi for FakeInputOutput {
self.io_events.lock().unwrap().push(IoEvent::Kill(fd));
Ok(())
}
+ fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
+ if self.sigwinch_event.is_some() {
+ let (lock, cvar) = &*self.should_trigger_sigwinch;
+ let mut should_trigger_sigwinch = lock.lock().unwrap();
+ while !*should_trigger_sigwinch {
+ should_trigger_sigwinch = cvar.wait(should_trigger_sigwinch).unwrap();
+ }
+ cb();
+ }
+ }
}
diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs
index 0a7aea48..7421ba37 100644
--- a/src/tests/integration/close_pane.rs
+++ b/src/tests/integration/close_pane.rs
@@ -6,7 +6,7 @@ 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,
+ CLOSE_PANE_IN_PANE_MODE, 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,
};
diff --git a/src/tests/integration/mod.rs b/src/tests/integration/mod.rs
index 9036ad6d..83cb7d22 100644
--- a/src/tests/integration/mod.rs
+++ b/src/tests/integration/mod.rs
@@ -12,4 +12,5 @@ pub mod resize_left;
pub mod resize_right;
pub mod resize_up;
pub mod tabs;
+pub mod terminal_window_resize;
pub mod toggle_fullscreen;
diff --git a/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_height_increase_with_one_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_height_increase_with_one_pane.snap
new file mode 100644
index 00000000..2b8efe26
--- /dev/null
+++ b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_height_increase_with_one_pane.snap
@@ -0,0 +1,25 @@
+---
+source: src/tests/integration/terminal_window_resize.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
+ █
diff --git a/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_and_height_decrease_with_one_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_and_height_decrease_with_one_pane.snap
new file mode 100644
index 00000000..55f32b5d
--- /dev/null
+++ b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_and_height_decrease_with_one_pane.snap
@@ -0,0 +1,25 @@
+---
+source: src/tests/integration/terminal_window_resize.rs
+expression: snapshot_before_quit
+
+---
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+prompt $ █
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_decrease_with_one_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_decrease_with_one_pane.snap
new file mode 100644
index 00000000..2f72d22a
--- /dev/null
+++ b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_decrease_with_one_pane.snap
@@ -0,0 +1,25 @@
+---
+source: src/tests/integration/terminal_window_resize.rs
+expression: snapshot_before_quit
+
+---
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+prompt $ █
diff --git a/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_increase_with_one_pane.snap b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_increase_with_one_pane.snap
new file mode 100644
index 00000000..95cc6c36
--- /dev/null
+++ b/src/tests/integration/snapshots/zellij__tests__integration__terminal_window_resize__window_width_increase_with_one_pane.snap
@@ -0,0 +1,25 @@
+---
+source: src/tests/integration/terminal_window_resize.rs
+expression: snapshot_before_quit
+
+---
+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/terminal_window_resize.rs b/src/tests/integration/terminal_window_resize.rs
new file mode 100644
index 00000000..ab73d24e
--- /dev/null
+++ b/src/tests/integration/terminal_window_resize.rs
@@ -0,0 +1,127 @@
+use crate::panes::PositionAndSize;
+use ::insta::assert_snapshot;
+
+use crate::tests::fakes::FakeInputOutput;
+use crate::tests::utils::commands::QUIT;
+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 window_width_decrease_with_one_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(&[&QUIT]);
+ fake_input_output.add_sigwinch_event(PositionAndSize {
+ columns: 90,
+ rows: 20,
+ x: 0,
+ y: 0,
+ });
+ let opts = CliArgs::default();
+ 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 window_width_increase_with_one_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(&[&QUIT]);
+ fake_input_output.add_sigwinch_event(PositionAndSize {
+ columns: 141,
+ rows: 20,
+ x: 0,
+ y: 0,
+ });
+ let opts = CliArgs::default();
+ 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 window_height_increase_with_one_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(&[&QUIT]);
+ fake_input_output.add_sigwinch_event(PositionAndSize {
+ columns: 121,
+ rows: 30,
+ x: 0,
+ y: 0,
+ });
+ let opts = CliArgs::default();
+ 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 window_width_and_height_decrease_with_one_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(&[&QUIT]);
+ fake_input_output.add_sigwinch_event(PositionAndSize {
+ columns: 90,
+ rows: 10,
+ x: 0,
+ y: 0,
+ });
+ let opts = CliArgs::default();
+ 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/possible_tty_inputs.rs b/src/tests/possible_tty_inputs.rs
index fa918be0..30668360 100644
--- a/src/tests/possible_tty_inputs.rs
+++ b/src/tests/possible_tty_inputs.rs
@@ -1,6 +1,7 @@
use crate::tests::tty_inputs::{
- COL_10, COL_121, COL_14, COL_15, COL_19, COL_20, COL_24, COL_25, COL_29, COL_30, COL_34,
- COL_39, COL_4, COL_40, COL_47, COL_50, COL_60, COL_70, COL_8, COL_9, COL_90, COL_96,
+ COL_10, COL_121, COL_14, COL_141, COL_15, COL_19, COL_20, COL_24, COL_25, COL_29, COL_30,
+ COL_34, COL_39, COL_4, COL_40, COL_47, COL_50, COL_60, COL_70, COL_8, COL_80, COL_9, COL_90,
+ COL_96,
};
use std::collections::HashMap;
use std::fs;
@@ -69,9 +70,11 @@ pub fn get_possible_tty_inputs() -> HashMap<u16, Bytes> {
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_80_bytes = Bytes::new().content_from_str(&COL_80);
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);
+ let col_141_bytes = Bytes::new().content_from_str(&COL_141);
possible_inputs.insert(4, col_4_bytes);
possible_inputs.insert(8, col_8_bytes);
possible_inputs.insert(9, col_9_bytes);
@@ -91,8 +94,10 @@ pub fn get_possible_tty_inputs() -> HashMap<u16, 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(80, col_80_bytes);
possible_inputs.insert(90, col_90_bytes);
possible_inputs.insert(96, col_96_bytes);
possible_inputs.insert(121, col_121_bytes);
+ possible_inputs.insert(141, col_141_bytes);
possible_inputs
}
diff --git a/src/tests/tty_inputs.rs b/src/tests/tty_inputs.rs
index cf49290e..43ac8abc 100644
--- a/src/tests/tty_inputs.rs
+++ b/src/tests/tty_inputs.rs
@@ -1,3 +1,26 @@
+pub const COL_141: [&str; 20] = [
+ "line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line17-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line18-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "line19-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
+ "prompt $ ",
+];
+
pub const COL_121: [&str; 20] = [
"line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
"line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
@@ -457,6 +480,29 @@ pub const COL_70: [&str; 20] = [
"prompt $ ",
];
+pub const COL_80: [&str; 20] = [
+ "line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
+ "prompt $ ",
+];
+
pub const COL_90: [&str; 20] = [
"line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
"line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
diff --git a/src/tests/utils.rs b/src/tests/utils.rs
index 14f4cfa0..915adfb0 100644
--- a/src/tests/utils.rs
+++ b/src/tests/utils.rs
@@ -45,7 +45,6 @@ pub fn get_next_to_last_snapshot(mut snapshots: Vec<String>) -> Option<String> {
}
pub mod commands {
- pub const COMMAND_TOGGLE: [u8; 1] = [7]; // ctrl-g
pub const QUIT: [u8; 1] = [17]; // ctrl-q
pub const ESC: [u8; 1] = [27];