fix(grid): various crashes (#2972)

* fix(grid): various crashes

* style(fmt): rustfmt
This commit is contained in:
Aram Drevekenin 2023-11-30 18:16:26 +01:00 committed by GitHub
parent 7c841251f6
commit 6c20ba9d03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1421,9 +1421,11 @@ impl Grid {
} }
} }
pub fn clear_cursor_line(&mut self) { pub fn clear_cursor_line(&mut self) {
self.viewport.get_mut(self.cursor.y).unwrap().truncate(0); if let Some(viewport_line) = self.viewport.get_mut(self.cursor.y) {
viewport_line.truncate(0);
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
}
pub fn clear_all(&mut self, replace_with: TerminalCharacter) { pub fn clear_all(&mut self, replace_with: TerminalCharacter) {
let replace_with_columns = VecDeque::from(vec![replace_with; self.width]); let replace_with_columns = VecDeque::from(vec![replace_with; self.width]);
self.replace_characters_in_line_after_cursor(replace_with); self.replace_characters_in_line_after_cursor(replace_with);
@ -1462,12 +1464,13 @@ impl Grid {
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, pad_character); self.pad_lines_until(self.cursor.y, pad_character);
} }
let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); if let Some(current_row) = self.viewport.get_mut(self.cursor.y) {
for _ in current_row.width()..position { for _ in current_row.width()..position {
current_row.push(pad_character); current_row.push(pad_character);
} }
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
}
fn pad_lines_until(&mut self, position: usize, pad_character: TerminalCharacter) { fn pad_lines_until(&mut self, position: usize, pad_character: TerminalCharacter) {
for _ in self.viewport.len()..=position { for _ in self.viewport.len()..=position {
let columns = VecDeque::from(vec![pad_character; self.width]); let columns = VecDeque::from(vec![pad_character; self.width]);
@ -1646,21 +1649,22 @@ impl Grid {
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, empty_character); self.pad_current_line_until(pad_until, empty_character);
let current_row = self.viewport.get_mut(self.cursor.y).unwrap(); if let Some(current_row) = self.viewport.get_mut(self.cursor.y) {
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);
} }
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
}
fn erase_characters(&mut self, count: usize, empty_char_style: CharacterStyles) { fn erase_characters(&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 current_row = self.viewport.get_mut(self.cursor.y).unwrap(); if let Some(current_row) = self.viewport.get_mut(self.cursor.y) {
// pad row if needed // pad row if needed
if current_row.width_cached() < self.width { if current_row.width_cached() < self.width {
let padding_count = self.width - current_row.width_cached(); let padding_count = self.width - current_row.width_cached();
let mut columns_padding = VecDeque::from(vec![EMPTY_TERMINAL_CHARACTER; padding_count]); let mut columns_padding =
VecDeque::from(vec![EMPTY_TERMINAL_CHARACTER; padding_count]);
current_row.columns.append(&mut columns_padding); current_row.columns.append(&mut columns_padding);
} }
for _ in 0..count { for _ in 0..count {
@ -1676,6 +1680,7 @@ impl Grid {
} }
self.output_buffer.update_line(self.cursor.y); self.output_buffer.update_line(self.cursor.y);
} }
}
fn add_newline(&mut self) { fn add_newline(&mut self) {
self.add_canonical_line(); self.add_canonical_line();
self.mark_for_rerender(); self.mark_for_rerender();
@ -3278,13 +3283,14 @@ impl Row {
if absolute_x_index < self.columns.len() { if absolute_x_index < self.columns.len() {
self.columns.push_back(terminal_character); self.columns.push_back(terminal_character);
// this is much more performant than remove/insert // this is much more performant than remove/insert
let character = self.columns.swap_remove_back(absolute_x_index).unwrap(); if let Some(character) = self.columns.swap_remove_back(absolute_x_index) {
let excess_width = character.width.saturating_sub(terminal_character.width); let excess_width = character.width.saturating_sub(terminal_character.width);
for _ in 0..excess_width { for _ in 0..excess_width {
self.columns self.columns
.insert(absolute_x_index, EMPTY_TERMINAL_CHARACTER); .insert(absolute_x_index, EMPTY_TERMINAL_CHARACTER);
} }
} }
}
self.width = None; self.width = None;
} }
pub fn replace_columns(&mut self, columns: VecDeque<TerminalCharacter>) { pub fn replace_columns(&mut self, columns: VecDeque<TerminalCharacter>) {
@ -3382,7 +3388,7 @@ impl Row {
let erase_position = self.absolute_character_index(x); let erase_position = self.absolute_character_index(x);
if erase_position < self.columns.len() { if erase_position < self.columns.len() {
self.width = None; self.width = None;
Some(self.columns.remove(erase_position).unwrap()) // TODO: just return the remove part? self.columns.remove(erase_position)
} else { } else {
None None
} }
@ -3404,7 +3410,9 @@ impl Row {
parts.push(Row::from_columns(current_part)) parts.push(Row::from_columns(current_part))
}; };
if !parts.is_empty() && self.is_canonical { if !parts.is_empty() && self.is_canonical {
parts.get_mut(0).unwrap().is_canonical = true; if let Some(part) = parts.get_mut(0) {
part.is_canonical = true;
}
} }
if parts.is_empty() { if parts.is_empty() {
parts.push(self.clone()); parts.push(self.clone());