Stability fixes (#273)

* fix(grid): various recoveries from a corrupted state

* style(fmt): rustfmt

* fix(grid): more stability fixes

* style(fmt): rustfmt
This commit is contained in:
Aram Drevekenin 2021-04-15 20:14:35 +02:00 committed by GitHub
parent 4fe100813c
commit 833381bca8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -476,6 +476,10 @@ impl Grid {
// then we add an empty line at its end which will be filled by the application // then we add an empty line at its end which will be filled by the application
// controlling the scroll region (presumably filled by whatever comes next in the // controlling the scroll region (presumably filled by whatever comes next in the
// scroll buffer, but that's not something we control) // scroll buffer, but that's not something we control)
if scroll_region_top >= self.viewport.len() {
// the state is corrupted
return;
}
self.viewport.remove(scroll_region_top); self.viewport.remove(scroll_region_top);
let columns = vec![EMPTY_TERMINAL_CHARACTER; self.width]; let columns = vec![EMPTY_TERMINAL_CHARACTER; self.width];
self.viewport self.viewport
@ -648,7 +652,9 @@ impl Grid {
if current_line_index == scroll_region_top { if current_line_index == scroll_region_top {
// if we're at the top line, we create a new line and remove the last line that // if we're at the top line, we create a new line and remove the last line that
// would otherwise overflow // would otherwise overflow
self.viewport.remove(scroll_region_bottom); if scroll_region_bottom < self.viewport.len() {
self.viewport.remove(scroll_region_bottom);
}
self.viewport.insert(current_line_index, Row::new()); // TODO: .canonical() ? self.viewport.insert(current_line_index, Row::new()); // TODO: .canonical() ?
} else if current_line_index > scroll_region_top } else if current_line_index > scroll_region_top
&& current_line_index <= scroll_region_bottom && current_line_index <= scroll_region_bottom
@ -711,8 +717,12 @@ impl Grid {
for _ in 0..count { for _ in 0..count {
self.viewport.remove(current_line_index); self.viewport.remove(current_line_index);
let columns = vec![pad_character; self.width]; let columns = vec![pad_character; self.width];
self.viewport if self.viewport.len() > scroll_region_bottom {
.insert(scroll_region_bottom, Row::from_columns(columns).canonical()); self.viewport
.insert(scroll_region_bottom, Row::from_columns(columns).canonical());
} else {
self.viewport.push(Row::from_columns(columns).canonical());
}
} }
} }
} }
@ -731,7 +741,9 @@ impl Grid {
// so we add an empty line where the cursor currently is, and delete the last line // so we add an empty line where the cursor currently is, and delete the last line
// of the scroll region // of the scroll region
for _ in 0..count { for _ in 0..count {
self.viewport.remove(scroll_region_bottom); if scroll_region_bottom < self.viewport.len() {
self.viewport.remove(scroll_region_bottom);
}
let columns = vec![pad_character; self.width]; let columns = vec![pad_character; self.width];
self.viewport self.viewport
.insert(current_line_index, Row::from_columns(columns).canonical()); .insert(current_line_index, Row::from_columns(columns).canonical());
@ -784,6 +796,7 @@ impl Grid {
self.viewport = vec![Row::new().canonical()]; self.viewport = vec![Row::new().canonical()];
self.alternative_lines_above_viewport_and_cursor = None; self.alternative_lines_above_viewport_and_cursor = None;
self.cursor_key_mode = false; self.cursor_key_mode = false;
self.scroll_region = None;
self.clear_viewport_before_rendering = true; self.clear_viewport_before_rendering = true;
self.cursor = Cursor::new(0, 0); self.cursor = Cursor::new(0, 0);
} }
@ -881,12 +894,15 @@ impl vte::Perform for Grid {
if params[0] == 0 { if params[0] == 0 {
(0, params[0] as usize) (0, params[0] as usize)
} else { } else {
(params[0] as usize - 1, params[0] as usize) ((params[0] as usize).saturating_sub(1), params[0] as usize)
} }
} else if params[0] == 0 { } else if params[0] == 0 {
(0, params[1] as usize - 1) (0, (params[1] as usize).saturating_sub(1))
} else { } else {
(params[0] as usize - 1, params[1] as usize - 1) (
(params[0] as usize).saturating_sub(1),
(params[1] as usize).saturating_sub(1),
)
}; };
let pad_character = EMPTY_TERMINAL_CHARACTER; let pad_character = EMPTY_TERMINAL_CHARACTER;
self.move_cursor_to(col, row, pad_character); self.move_cursor_to(col, row, pad_character);
@ -973,8 +989,8 @@ impl vte::Perform for Grid {
} else if c == 'r' { } else if c == 'r' {
if params.len() > 1 { if params.len() > 1 {
// minus 1 because these are 1 indexed // minus 1 because these are 1 indexed
let top_line_index = params[0] as usize - 1; let top_line_index = (params[0] as usize).saturating_sub(1);
let bottom_line_index = params[1] as usize - 1; let bottom_line_index = (params[1] as usize).saturating_sub(1);
self.set_scroll_region(top_line_index, bottom_line_index); self.set_scroll_region(top_line_index, bottom_line_index);
self.show_cursor(); self.show_cursor();
} else { } else {
@ -1160,8 +1176,10 @@ impl Row {
} }
pub fn replace_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) { pub fn replace_character_at(&mut self, terminal_character: TerminalCharacter, x: usize) {
// this is much more performant than remove/insert // this is much more performant than remove/insert
self.columns.push(terminal_character); if x < self.columns.len() {
self.columns.swap_remove(x); self.columns.push(terminal_character);
self.columns.swap_remove(x);
}
} }
pub fn replace_columns(&mut self, columns: Vec<TerminalCharacter>) { pub fn replace_columns(&mut self, columns: Vec<TerminalCharacter>) {
self.columns = columns; self.columns = columns;
@ -1176,7 +1194,11 @@ impl Row {
self.columns.append(to_append); self.columns.append(to_append);
} }
pub fn replace_beginning_with(&mut self, mut line_part: Vec<TerminalCharacter>) { pub fn replace_beginning_with(&mut self, mut line_part: Vec<TerminalCharacter>) {
drop(self.columns.drain(0..line_part.len())); if line_part.len() > self.columns.len() {
self.columns.clear();
} else {
drop(self.columns.drain(0..line_part.len()));
}
line_part.append(&mut self.columns); line_part.append(&mut self.columns);
self.columns = line_part; self.columns = line_part;
} }
@ -1184,7 +1206,9 @@ impl Row {
self.columns.len() self.columns.len()
} }
pub fn delete_character(&mut self, x: usize) { pub fn delete_character(&mut self, x: usize) {
self.columns.remove(x); if x < self.columns.len() {
self.columns.remove(x);
}
} }
pub fn split_to_rows_of_length(&mut self, max_row_length: usize) -> Vec<Row> { pub fn split_to_rows_of_length(&mut self, max_row_length: usize) -> Vec<Row> {
let mut parts: Vec<Row> = vec![]; let mut parts: Vec<Row> = vec![];