fix(compatibility): single line scroll and other edge cases (#1307)

This commit is contained in:
Aram Drevekenin 2022-04-09 13:34:32 +02:00 committed by GitHub
parent 8097ae3903
commit c08145ef5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -389,7 +389,7 @@ impl Grid {
} }
let mut empty_character = EMPTY_TERMINAL_CHARACTER; let mut empty_character = EMPTY_TERMINAL_CHARACTER;
empty_character.styles = styles; empty_character.styles = styles;
self.pad_current_line_until(self.cursor.x); self.pad_current_line_until(self.cursor.x, empty_character);
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
pub fn move_to_previous_tabstop(&mut self) { pub fn move_to_previous_tabstop(&mut self) {
@ -877,12 +877,16 @@ impl Grid {
self.viewport.remove(0); self.viewport.remove(0);
} }
let columns = VecDeque::from(vec![EMPTY_TERMINAL_CHARACTER; self.width]); let mut pad_character = EMPTY_TERMINAL_CHARACTER;
pad_character.styles = self.cursor.pending_styles;
let columns = VecDeque::from(vec![pad_character; self.width]);
self.viewport.push(Row::from_columns(columns).canonical()); self.viewport.push(Row::from_columns(columns).canonical());
self.selection.move_up(1); self.selection.move_up(1);
} else { } else {
self.viewport.remove(scroll_region_top); self.viewport.remove(scroll_region_top);
let columns = VecDeque::from(vec![EMPTY_TERMINAL_CHARACTER; self.width]); let mut pad_character = EMPTY_TERMINAL_CHARACTER;
pad_character.styles = self.cursor.pending_styles;
let columns = VecDeque::from(vec![pad_character; self.width]);
if self.viewport.len() >= scroll_region_bottom { if self.viewport.len() >= scroll_region_bottom {
self.viewport self.viewport
.insert(scroll_region_bottom, Row::from_columns(columns).canonical()); .insert(scroll_region_bottom, Row::from_columns(columns).canonical());
@ -1065,13 +1069,13 @@ impl Grid {
self.scrollback_buffer_lines = self.recalculate_scrollback_buffer_count(); self.scrollback_buffer_lines = self.recalculate_scrollback_buffer_count();
} }
fn pad_current_line_until(&mut self, position: usize) { fn pad_current_line_until(&mut self, position: usize, pad_character: TerminalCharacter) {
if self.viewport.get(self.cursor.y).is_none() { if self.viewport.get(self.cursor.y).is_none() {
self.pad_lines_until(self.cursor.y, EMPTY_TERMINAL_CHARACTER); self.pad_lines_until(self.cursor.y, pad_character);
} }
let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); let current_row = self.viewport.get_mut(self.cursor.y).unwrap();
for _ in current_row.width()..position { for _ in current_row.width()..position {
current_row.push(EMPTY_TERMINAL_CHARACTER); current_row.push(pad_character);
} }
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
@ -1097,13 +1101,13 @@ impl Grid {
self.cursor.y = std::cmp::min(self.height - 1, y + y_offset); self.cursor.y = std::cmp::min(self.height - 1, y + y_offset);
} }
self.pad_lines_until(self.cursor.y, pad_character); self.pad_lines_until(self.cursor.y, pad_character);
self.pad_current_line_until(self.cursor.x); self.pad_current_line_until(self.cursor.x, pad_character);
} }
None => { None => {
self.cursor.x = std::cmp::min(self.width - 1, x); self.cursor.x = std::cmp::min(self.width - 1, x);
self.cursor.y = std::cmp::min(self.height - 1, y); self.cursor.y = std::cmp::min(self.height - 1, y);
self.pad_lines_until(self.cursor.y, pad_character); self.pad_lines_until(self.cursor.y, pad_character);
self.pad_current_line_until(self.cursor.x); self.pad_current_line_until(self.cursor.x, pad_character);
} }
} }
} }
@ -1176,7 +1180,9 @@ impl Grid {
pub fn set_scroll_region(&mut self, top_line_index: usize, bottom_line_index: Option<usize>) { pub fn set_scroll_region(&mut self, top_line_index: usize, bottom_line_index: Option<usize>) {
let bottom_line_index = bottom_line_index.unwrap_or(self.height); let bottom_line_index = bottom_line_index.unwrap_or(self.height);
self.scroll_region = Some((top_line_index, bottom_line_index)); self.scroll_region = Some((top_line_index, bottom_line_index));
self.move_cursor_to(0, 0, EMPTY_TERMINAL_CHARACTER); // DECSTBM moves the cursor to column 1 line 1 of the page let mut pad_character = EMPTY_TERMINAL_CHARACTER;
pad_character.styles = self.cursor.pending_styles;
self.move_cursor_to(0, 0, pad_character); // DECSTBM moves the cursor to column 1 line 1 of the page
} }
pub fn clear_scroll_region(&mut self) { pub fn clear_scroll_region(&mut self) {
self.scroll_region = None; self.scroll_region = None;
@ -1238,18 +1244,20 @@ impl Grid {
} }
pub fn move_cursor_to_column(&mut self, column: usize) { pub fn move_cursor_to_column(&mut self, column: usize) {
self.cursor.x = column; self.cursor.x = column;
self.pad_current_line_until(self.cursor.x); let pad_character = EMPTY_TERMINAL_CHARACTER;
self.pad_current_line_until(self.cursor.x, pad_character);
} }
pub fn move_cursor_to_line(&mut self, line: usize, pad_character: TerminalCharacter) { pub fn move_cursor_to_line(&mut self, line: usize, pad_character: TerminalCharacter) {
self.cursor.y = std::cmp::min(self.height - 1, line); self.cursor.y = std::cmp::min(self.height - 1, line);
self.pad_lines_until(self.cursor.y, pad_character); self.pad_lines_until(self.cursor.y, pad_character);
self.pad_current_line_until(self.cursor.x); let pad_character = EMPTY_TERMINAL_CHARACTER;
self.pad_current_line_until(self.cursor.x, pad_character);
} }
pub fn replace_with_empty_chars(&mut self, count: usize, empty_char_style: CharacterStyles) { pub fn replace_with_empty_chars(&mut self, count: usize, empty_char_style: CharacterStyles) {
let mut empty_character = EMPTY_TERMINAL_CHARACTER; let mut empty_character = EMPTY_TERMINAL_CHARACTER;
empty_character.styles = empty_char_style; empty_character.styles = empty_char_style;
let pad_until = std::cmp::min(self.width, self.cursor.x + count); let pad_until = std::cmp::min(self.width, self.cursor.x + count);
self.pad_current_line_until(pad_until); self.pad_current_line_until(pad_until, empty_character);
let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); let current_row = self.viewport.get_mut(self.cursor.y).unwrap();
for i in 0..count { for i in 0..count {
current_row.replace_character_at(empty_character, self.cursor.x + i); current_row.replace_character_at(empty_character, self.cursor.x + i);
@ -1719,8 +1727,7 @@ impl Perform for Grid {
// we subtract 1 from the row/column because these are 1 indexed // we subtract 1 from the row/column because these are 1 indexed
let row = next_param_or(1).saturating_sub(1); let row = next_param_or(1).saturating_sub(1);
let col = next_param_or(1).saturating_sub(1); let col = next_param_or(1).saturating_sub(1);
let pad_character = EMPTY_TERMINAL_CHARACTER; self.move_cursor_to(col, row, EMPTY_TERMINAL_CHARACTER);
self.move_cursor_to(col, row, pad_character);
} else if c == 'A' { } else if c == 'A' {
// move cursor up until edge of screen // move cursor up until edge of screen
let move_up_count = next_param_or(1); let move_up_count = next_param_or(1);