Fix scrolling (#650)
* fix(grid): scroll up on empty line * fix(grid): line wrapping while scrolling * style(grid): fix names * docs(changelog): document fix
This commit is contained in:
parent
fde38dcb44
commit
e889891604
10 changed files with 348 additions and 79 deletions
|
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
* New pane UI: draw pane frames - can be disabled with ctrl-p + z, or through configuration (https://github.com/zellij-org/zellij/pull/643)
|
* New pane UI: draw pane frames - can be disabled with ctrl-p + z, or through configuration (https://github.com/zellij-org/zellij/pull/643)
|
||||||
* Terminal compatibility: support changing index colors through OSC 4 and similar (https://github.com/zellij-org/zellij/pull/646)
|
* Terminal compatibility: support changing index colors through OSC 4 and similar (https://github.com/zellij-org/zellij/pull/646)
|
||||||
* Fix various shells (eg. nushell) unexpectedly exiting when the user presses ctrl-c (https://github.com/zellij-org/zellij/pull/648)
|
* Fix various shells (eg. nushell) unexpectedly exiting when the user presses ctrl-c (https://github.com/zellij-org/zellij/pull/648)
|
||||||
|
* Fix line wrapping while scrolling (https://github.com/zellij-org/zellij/pull/650)
|
||||||
|
|
||||||
## [0.15.0] - 2021-07-19
|
## [0.15.0] - 2021-07-19
|
||||||
* Kill children properly (https://github.com/zellij-org/zellij/pull/601)
|
* Kill children properly (https://github.com/zellij-org/zellij/pull/601)
|
||||||
|
|
|
||||||
20
src/tests/fixtures/scrolling
vendored
Normal file
20
src/tests/fixtures/scrolling
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
line 1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 3aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 4aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 5aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 6aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 7aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 10aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 11aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 12aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 13aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 14aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 16aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 17aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 18aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 19aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
line 20aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
@ -42,7 +42,7 @@ fn get_top_non_canonical_rows(rows: &mut Vec<Row>) -> Vec<Row> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bottom_canonical_row_and_wraps(rows: &mut VecDeque<Row>) -> Vec<Row> {
|
fn get_lines_above_bottom_canonical_row_and_wraps(rows: &mut VecDeque<Row>) -> Vec<Row> {
|
||||||
let mut index_of_last_non_canonical_row = None;
|
let mut index_of_last_non_canonical_row = None;
|
||||||
for (i, row) in rows.iter().enumerate().rev() {
|
for (i, row) in rows.iter().enumerate().rev() {
|
||||||
index_of_last_non_canonical_row = Some(i);
|
index_of_last_non_canonical_row = Some(i);
|
||||||
|
|
@ -58,100 +58,157 @@ fn get_bottom_canonical_row_and_wraps(rows: &mut VecDeque<Row>) -> Vec<Row> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_rows_down(
|
fn get_viewport_bottom_canonical_row_and_wraps(viewport: &mut Vec<Row>) -> Vec<Row> {
|
||||||
source: &mut VecDeque<Row>,
|
let mut index_of_last_non_canonical_row = None;
|
||||||
destination: &mut Vec<Row>,
|
for (i, row) in viewport.iter().enumerate().rev() {
|
||||||
|
index_of_last_non_canonical_row = Some(i);
|
||||||
|
if row.is_canonical {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match index_of_last_non_canonical_row {
|
||||||
|
Some(index_of_last_non_canonical_row) => {
|
||||||
|
viewport.drain(index_of_last_non_canonical_row..).collect()
|
||||||
|
}
|
||||||
|
None => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_top_canonical_row_and_wraps(rows: &mut Vec<Row>) -> Vec<Row> {
|
||||||
|
let mut index_of_first_non_canonical_row = None;
|
||||||
|
let mut end_index_of_first_canonical_line = None;
|
||||||
|
for (i, row) in rows.iter().enumerate() {
|
||||||
|
if row.is_canonical && end_index_of_first_canonical_line.is_none() {
|
||||||
|
index_of_first_non_canonical_row = Some(i);
|
||||||
|
end_index_of_first_canonical_line = Some(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if row.is_canonical && end_index_of_first_canonical_line.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if index_of_first_non_canonical_row.is_some() {
|
||||||
|
end_index_of_first_canonical_line = Some(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match (
|
||||||
|
index_of_first_non_canonical_row,
|
||||||
|
end_index_of_first_canonical_line,
|
||||||
|
) {
|
||||||
|
(Some(first_index), Some(last_index)) => rows.drain(first_index..=last_index).collect(),
|
||||||
|
(Some(first_index), None) => rows.drain(first_index..).collect(),
|
||||||
|
_ => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transfer_rows_from_lines_above_to_viewport(
|
||||||
|
lines_above: &mut VecDeque<Row>,
|
||||||
|
viewport: &mut Vec<Row>,
|
||||||
count: usize,
|
count: usize,
|
||||||
max_src_width: Option<usize>,
|
max_viewport_width: usize,
|
||||||
max_dst_width: Option<usize>,
|
|
||||||
) {
|
) {
|
||||||
let mut next_lines: Vec<Row> = vec![];
|
let mut next_lines: Vec<Row> = vec![];
|
||||||
let mut lines_added_to_destination: isize = 0;
|
let mut lines_added_to_viewport: isize = 0;
|
||||||
loop {
|
loop {
|
||||||
if lines_added_to_destination as usize == count {
|
if lines_added_to_viewport as usize == count {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if next_lines.is_empty() {
|
if next_lines.is_empty() {
|
||||||
match source.pop_back() {
|
match lines_above.pop_back() {
|
||||||
Some(next_line) => {
|
Some(next_line) => {
|
||||||
let mut top_non_canonical_rows_in_dst = get_top_non_canonical_rows(destination);
|
let mut top_non_canonical_rows_in_dst = get_top_non_canonical_rows(viewport);
|
||||||
lines_added_to_destination -= top_non_canonical_rows_in_dst.len() as isize;
|
lines_added_to_viewport -= top_non_canonical_rows_in_dst.len() as isize;
|
||||||
next_lines.push(next_line);
|
next_lines.push(next_line);
|
||||||
next_lines.append(&mut top_non_canonical_rows_in_dst);
|
next_lines.append(&mut top_non_canonical_rows_in_dst);
|
||||||
next_lines = match max_dst_width {
|
next_lines = Row::from_rows(next_lines, max_viewport_width)
|
||||||
Some(max_row_width) => Row::from_rows(next_lines, max_row_width)
|
.split_to_rows_of_length(max_viewport_width);
|
||||||
.split_to_rows_of_length(max_row_width),
|
|
||||||
None => vec![Row::from_rows(next_lines, 0)],
|
|
||||||
};
|
|
||||||
if next_lines.is_empty() {
|
if next_lines.is_empty() {
|
||||||
// no more lines at source, the line we popped was probably empty
|
// no more lines at lines_above, the line we popped was probably empty
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => break, // no more rows
|
None => break, // no more rows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
destination.insert(0, next_lines.pop().unwrap());
|
viewport.insert(0, next_lines.pop().unwrap());
|
||||||
lines_added_to_destination += 1;
|
lines_added_to_viewport += 1;
|
||||||
}
|
}
|
||||||
if !next_lines.is_empty() {
|
if !next_lines.is_empty() {
|
||||||
match max_src_width {
|
|
||||||
Some(max_row_width) => {
|
|
||||||
let excess_rows = Row::from_rows(next_lines, max_row_width)
|
|
||||||
.split_to_rows_of_length(max_row_width);
|
|
||||||
source.extend(excess_rows);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let excess_row = Row::from_rows(next_lines, 0);
|
let excess_row = Row::from_rows(next_lines, 0);
|
||||||
bounded_push(source, excess_row);
|
bounded_push(lines_above, excess_row);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_rows_up(
|
fn transfer_rows_from_viewport_to_lines_above(
|
||||||
source: &mut Vec<Row>,
|
viewport: &mut Vec<Row>,
|
||||||
destination: &mut VecDeque<Row>,
|
lines_above: &mut VecDeque<Row>,
|
||||||
count: usize,
|
count: usize,
|
||||||
max_src_width: Option<usize>,
|
max_viewport_width: usize,
|
||||||
max_dst_width: Option<usize>,
|
|
||||||
) {
|
) {
|
||||||
let mut next_lines: Vec<Row> = vec![];
|
let mut next_lines: Vec<Row> = vec![];
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
if next_lines.is_empty() {
|
if next_lines.is_empty() {
|
||||||
if !source.is_empty() {
|
if !viewport.is_empty() {
|
||||||
let next_line = source.remove(0);
|
let next_line = viewport.remove(0);
|
||||||
if !next_line.is_canonical {
|
if !next_line.is_canonical {
|
||||||
let mut bottom_canonical_row_and_wraps_in_dst =
|
let mut bottom_canonical_row_and_wraps_in_dst =
|
||||||
get_bottom_canonical_row_and_wraps(destination);
|
get_lines_above_bottom_canonical_row_and_wraps(lines_above);
|
||||||
next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
|
next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
|
||||||
}
|
}
|
||||||
next_lines.push(next_line);
|
next_lines.push(next_line);
|
||||||
next_lines = match max_dst_width {
|
next_lines = vec![Row::from_rows(next_lines, 0)];
|
||||||
Some(max_row_width) => Row::from_rows(next_lines, max_row_width)
|
|
||||||
.split_to_rows_of_length(max_row_width),
|
|
||||||
None => vec![Row::from_rows(next_lines, 0)],
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
break; // no more rows
|
break; // no more rows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bounded_push(destination, next_lines.remove(0));
|
bounded_push(lines_above, next_lines.remove(0));
|
||||||
}
|
}
|
||||||
if !next_lines.is_empty() {
|
if !next_lines.is_empty() {
|
||||||
match max_src_width {
|
let excess_rows = Row::from_rows(next_lines, max_viewport_width)
|
||||||
Some(max_row_width) => {
|
.split_to_rows_of_length(max_viewport_width);
|
||||||
let excess_rows = Row::from_rows(next_lines, max_row_width)
|
|
||||||
.split_to_rows_of_length(max_row_width);
|
|
||||||
for row in excess_rows {
|
for row in excess_rows {
|
||||||
source.insert(0, row);
|
viewport.insert(0, row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
}
|
||||||
|
|
||||||
|
fn transfer_rows_from_lines_below_to_viewport(
|
||||||
|
lines_below: &mut Vec<Row>,
|
||||||
|
viewport: &mut Vec<Row>,
|
||||||
|
count: usize,
|
||||||
|
max_viewport_width: usize,
|
||||||
|
) {
|
||||||
|
let mut next_lines: Vec<Row> = vec![];
|
||||||
|
for _ in 0..count {
|
||||||
|
let mut lines_pulled_from_viewport = 0;
|
||||||
|
if next_lines.is_empty() {
|
||||||
|
if !lines_below.is_empty() {
|
||||||
|
let mut top_non_canonical_rows_in_lines_below =
|
||||||
|
get_top_non_canonical_rows(lines_below);
|
||||||
|
if !top_non_canonical_rows_in_lines_below.is_empty() {
|
||||||
|
let mut canonical_line = get_viewport_bottom_canonical_row_and_wraps(viewport);
|
||||||
|
lines_pulled_from_viewport += canonical_line.len();
|
||||||
|
canonical_line.append(&mut top_non_canonical_rows_in_lines_below);
|
||||||
|
next_lines = Row::from_rows(canonical_line, max_viewport_width)
|
||||||
|
.split_to_rows_of_length(max_viewport_width);
|
||||||
|
} else {
|
||||||
|
let canonical_row = get_top_canonical_row_and_wraps(lines_below);
|
||||||
|
next_lines = Row::from_rows(canonical_row, max_viewport_width)
|
||||||
|
.split_to_rows_of_length(max_viewport_width);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break; // no more rows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _ in 0..(lines_pulled_from_viewport + 1) {
|
||||||
|
if !next_lines.is_empty() {
|
||||||
|
viewport.push(next_lines.remove(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !next_lines.is_empty() {
|
||||||
let excess_row = Row::from_rows(next_lines, 0);
|
let excess_row = Row::from_rows(next_lines, 0);
|
||||||
source.insert(0, excess_row);
|
lines_below.insert(0, excess_row);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,12 +538,11 @@ impl Grid {
|
||||||
let line_to_push_down = self.viewport.pop().unwrap();
|
let line_to_push_down = self.viewport.pop().unwrap();
|
||||||
self.lines_below.insert(0, line_to_push_down);
|
self.lines_below.insert(0, line_to_push_down);
|
||||||
|
|
||||||
transfer_rows_down(
|
transfer_rows_from_lines_above_to_viewport(
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
1,
|
1,
|
||||||
None,
|
self.width,
|
||||||
Some(self.width),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
self.selection.move_down(1);
|
self.selection.move_down(1);
|
||||||
|
|
@ -503,8 +559,14 @@ impl Grid {
|
||||||
last_line_above.append(&mut line_to_push_up.columns);
|
last_line_above.append(&mut line_to_push_up.columns);
|
||||||
bounded_push(&mut self.lines_above, last_line_above);
|
bounded_push(&mut self.lines_above, last_line_above);
|
||||||
}
|
}
|
||||||
let line_to_insert_at_viewport_bottom = self.lines_below.remove(0);
|
|
||||||
self.viewport.push(line_to_insert_at_viewport_bottom);
|
transfer_rows_from_lines_below_to_viewport(
|
||||||
|
&mut self.lines_below,
|
||||||
|
&mut self.viewport,
|
||||||
|
1,
|
||||||
|
self.width,
|
||||||
|
);
|
||||||
|
|
||||||
self.selection.move_up(1);
|
self.selection.move_up(1);
|
||||||
self.output_buffer.update_all_lines();
|
self.output_buffer.update_all_lines();
|
||||||
}
|
}
|
||||||
|
|
@ -593,12 +655,12 @@ impl Grid {
|
||||||
match current_viewport_row_count.cmp(&self.height) {
|
match current_viewport_row_count.cmp(&self.height) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
let row_count_to_transfer = self.height - current_viewport_row_count;
|
let row_count_to_transfer = self.height - current_viewport_row_count;
|
||||||
transfer_rows_down(
|
|
||||||
|
transfer_rows_from_lines_above_to_viewport(
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
None,
|
new_columns,
|
||||||
Some(new_columns),
|
|
||||||
);
|
);
|
||||||
let rows_pulled = self.viewport.len() - current_viewport_row_count;
|
let rows_pulled = self.viewport.len() - current_viewport_row_count;
|
||||||
new_cursor_y += rows_pulled;
|
new_cursor_y += rows_pulled;
|
||||||
|
|
@ -610,12 +672,11 @@ impl Grid {
|
||||||
} else {
|
} else {
|
||||||
new_cursor_y -= row_count_to_transfer;
|
new_cursor_y -= row_count_to_transfer;
|
||||||
}
|
}
|
||||||
transfer_rows_up(
|
transfer_rows_from_viewport_to_lines_above(
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
Some(new_columns),
|
new_columns,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ordering::Equal => {}
|
Ordering::Equal => {}
|
||||||
|
|
@ -628,12 +689,11 @@ impl Grid {
|
||||||
match current_viewport_row_count.cmp(&new_rows) {
|
match current_viewport_row_count.cmp(&new_rows) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
let row_count_to_transfer = new_rows - current_viewport_row_count;
|
let row_count_to_transfer = new_rows - current_viewport_row_count;
|
||||||
transfer_rows_down(
|
transfer_rows_from_lines_above_to_viewport(
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
None,
|
new_columns,
|
||||||
Some(new_columns),
|
|
||||||
);
|
);
|
||||||
let rows_pulled = self.viewport.len() - current_viewport_row_count;
|
let rows_pulled = self.viewport.len() - current_viewport_row_count;
|
||||||
self.cursor.y += rows_pulled;
|
self.cursor.y += rows_pulled;
|
||||||
|
|
@ -645,12 +705,11 @@ impl Grid {
|
||||||
} else {
|
} else {
|
||||||
self.cursor.y -= row_count_to_transfer;
|
self.cursor.y -= row_count_to_transfer;
|
||||||
}
|
}
|
||||||
transfer_rows_up(
|
transfer_rows_from_viewport_to_lines_above(
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
Some(new_columns),
|
new_columns,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ordering::Equal => {}
|
Ordering::Equal => {}
|
||||||
|
|
@ -794,12 +853,11 @@ impl Grid {
|
||||||
}
|
}
|
||||||
if self.cursor.y == self.height - 1 {
|
if self.cursor.y == self.height - 1 {
|
||||||
let row_count_to_transfer = 1;
|
let row_count_to_transfer = 1;
|
||||||
transfer_rows_up(
|
transfer_rows_from_viewport_to_lines_above(
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
Some(self.width),
|
self.width,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
self.selection.move_up(1);
|
self.selection.move_up(1);
|
||||||
self.output_buffer.update_all_lines();
|
self.output_buffer.update_all_lines();
|
||||||
|
|
@ -869,12 +927,11 @@ impl Grid {
|
||||||
self.cursor.x = 0;
|
self.cursor.x = 0;
|
||||||
if self.cursor.y == self.height - 1 {
|
if self.cursor.y == self.height - 1 {
|
||||||
let row_count_to_transfer = 1;
|
let row_count_to_transfer = 1;
|
||||||
transfer_rows_up(
|
transfer_rows_from_viewport_to_lines_above(
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
row_count_to_transfer,
|
row_count_to_transfer,
|
||||||
Some(self.width),
|
self.width,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
let wrapped_row = Row::new(self.width);
|
let wrapped_row = Row::new(self.width);
|
||||||
self.viewport.push(wrapped_row);
|
self.viewport.push(wrapped_row);
|
||||||
|
|
@ -2165,6 +2222,9 @@ impl Row {
|
||||||
if !parts.is_empty() && self.is_canonical {
|
if !parts.is_empty() && self.is_canonical {
|
||||||
parts.get_mut(0).unwrap().is_canonical = true;
|
parts.get_mut(0).unwrap().is_canonical = true;
|
||||||
}
|
}
|
||||||
|
if parts.is_empty() {
|
||||||
|
parts.push(self.clone());
|
||||||
|
}
|
||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -608,9 +608,9 @@ fn copy_selected_text_from_lines_below() {
|
||||||
|
|
||||||
grid.move_viewport_up(40);
|
grid.move_viewport_up(40);
|
||||||
|
|
||||||
grid.start_selection(&Position::new(35, 6));
|
grid.start_selection(&Position::new(63, 6));
|
||||||
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
||||||
grid.end_selection(Some(&Position::new(37, 35)));
|
grid.end_selection(Some(&Position::new(65, 35)));
|
||||||
let text = grid.get_selected_text();
|
let text = grid.get_selected_text();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
text.unwrap(),
|
text.unwrap(),
|
||||||
|
|
@ -907,3 +907,95 @@ pub fn exa_plus_omf_theme() {
|
||||||
}
|
}
|
||||||
assert_snapshot!(format!("{:?}", grid));
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_up() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 50, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_down() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 50, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
grid.scroll_down_one_line();
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_up_with_line_wraps() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 25, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_down_with_line_wraps() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 25, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
grid.scroll_down_one_line();
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_up_decrease_width_and_scroll_down() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 50, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
for _ in 0..10 {
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
}
|
||||||
|
grid.change_size(10, 25);
|
||||||
|
for _ in 0..10 {
|
||||||
|
grid.scroll_down_one_line();
|
||||||
|
}
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn scroll_up_increase_width_and_scroll_down() {
|
||||||
|
let mut vte_parser = vte::Parser::new();
|
||||||
|
let mut grid = Grid::new(10, 25, Palette::default());
|
||||||
|
let fixture_name = "scrolling";
|
||||||
|
let content = read_fixture(fixture_name);
|
||||||
|
for byte in content {
|
||||||
|
vte_parser.advance(&mut grid, byte);
|
||||||
|
}
|
||||||
|
for _ in 0..10 {
|
||||||
|
grid.scroll_up_one_line();
|
||||||
|
}
|
||||||
|
grid.change_size(10, 50);
|
||||||
|
for _ in 0..10 {
|
||||||
|
grid.scroll_down_one_line();
|
||||||
|
}
|
||||||
|
assert_snapshot!(format!("{:?}", grid));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (C): line 11aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
01 (C): line 12aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
02 (C): line 13aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
03 (C): line 14aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
04 (C): line 15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
05 (C): line 16aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
06 (C): line 17aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
07 (C): line 18aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
08 (C): line 19aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
09 (C): line 20aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (C): line 16aaaaaaaaaaaaaaaaaa
|
||||||
|
01 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
02 (C): line 17aaaaaaaaaaaaaaaaaa
|
||||||
|
03 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
04 (C): line 18aaaaaaaaaaaaaaaaaa
|
||||||
|
05 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
06 (C): line 19aaaaaaaaaaaaaaaaaa
|
||||||
|
07 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
08 (C): line 20aaaaaaaaaaaaaaaaaa
|
||||||
|
09 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (C): line 10aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
01 (C): line 11aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
02 (C): line 12aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
03 (C): line 13aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
04 (C): line 14aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
05 (C): line 15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
06 (C): line 16aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
07 (C): line 17aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
08 (C): line 18aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
09 (C): line 19aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (C): line 11aaaaaaaaaaaaaaaaaa
|
||||||
|
01 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
02 (C): line 12aaaaaaaaaaaaaaaaaa
|
||||||
|
03 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
04 (C): line 13aaaaaaaaaaaaaaaaaa
|
||||||
|
05 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
06 (C): line 14aaaaaaaaaaaaaaaaaa
|
||||||
|
07 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
08 (C): line 15aaaaaaaaaaaaaaaaaa
|
||||||
|
09 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (C): line 11aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
01 (C): line 12aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
02 (C): line 13aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
03 (C): line 14aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
04 (C): line 15aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
05 (C): line 16aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
06 (C): line 17aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
07 (C): line 18aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
08 (C): line 19aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
09 (C): line 20aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||||
|
expression: "format!(\"{:?}\", grid)"
|
||||||
|
|
||||||
|
---
|
||||||
|
00 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
01 (C): line 16aaaaaaaaaaaaaaaaaa
|
||||||
|
02 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
03 (C): line 17aaaaaaaaaaaaaaaaaa
|
||||||
|
04 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
05 (C): line 18aaaaaaaaaaaaaaaaaa
|
||||||
|
06 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
07 (C): line 19aaaaaaaaaaaaaaaaaa
|
||||||
|
08 (W): aaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
09 (C): line 20aaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue