diff --git a/src/client/panes/grid.rs b/src/client/panes/grid.rs index f2aa848c..a13fe204 100644 --- a/src/client/panes/grid.rs +++ b/src/client/panes/grid.rs @@ -431,7 +431,7 @@ impl Grid { pub fn rotate_scroll_region_down(&mut self, _count: usize) { // TBD } - pub fn add_canonical_line(&mut self) { + pub fn add_canonical_line(&mut self, pad_character: TerminalCharacter) { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { if self.cursor.y == scroll_region_bottom { // end of scroll region @@ -441,12 +441,16 @@ impl Grid { // controlling the scroll region (presumably filled by whatever comes next in the // scroll buffer, but that's not something we control) self.viewport.remove(scroll_region_top); + let columns = vec![pad_character; self.width]; self.viewport - .insert(scroll_region_bottom, Row::new().canonical()); + .insert(scroll_region_bottom, Row::from_columns(columns).canonical()); return; } } if self.viewport.len() <= self.cursor.y + 1 { + // FIXME: this should add an empty line with the pad_character + // but for some reason this breaks rendering in various situations + // it needs to be investigated and fixed let new_row = Row::new().canonical(); self.viewport.push(new_row); } @@ -565,15 +569,16 @@ impl Grid { current_row.push(EMPTY_TERMINAL_CHARACTER); } } - fn pad_lines_until(&mut self, position: usize) { + fn pad_lines_until(&mut self, position: usize, pad_character: TerminalCharacter) { for _ in self.viewport.len()..=position { - self.viewport.push(Row::new().canonical()); + let columns = vec![pad_character; self.width]; + self.viewport.push(Row::from_columns(columns).canonical()); } } - pub fn move_cursor_to(&mut self, x: usize, y: usize) { + pub fn move_cursor_to(&mut self, x: usize, y: usize, pad_character: TerminalCharacter) { self.cursor.x = std::cmp::min(self.width - 1, x); self.cursor.y = std::cmp::min(self.height - 1, y); - self.pad_lines_until(self.cursor.y); + self.pad_lines_until(self.cursor.y, pad_character); self.pad_current_line_until(self.cursor.x); } pub fn move_cursor_up(&mut self, count: usize) { @@ -600,7 +605,7 @@ impl Grid { } } } - pub fn move_cursor_down(&mut self, count: usize) { + pub fn move_cursor_down(&mut self, count: usize, pad_character: TerminalCharacter) { let lines_to_add = if self.cursor.y + count > self.height - 1 { (self.cursor.y + count) - (self.height - 1) } else { @@ -612,9 +617,9 @@ impl Grid { self.cursor.y + count }; for _ in 0..lines_to_add { - self.add_canonical_line(); + self.add_canonical_line(pad_character); } - self.pad_lines_until(self.cursor.y); + self.pad_lines_until(self.cursor.y, pad_character); } pub fn move_cursor_back(&mut self, count: usize) { if self.cursor.x < count { @@ -638,7 +643,11 @@ impl Grid { pub fn set_scroll_region_to_viewport_size(&mut self) { self.scroll_region = Some((0, self.height - 1)); } - pub fn delete_lines_in_scroll_region(&mut self, count: usize) { + pub fn delete_lines_in_scroll_region( + &mut self, + count: usize, + pad_character: TerminalCharacter, + ) { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { let current_line_index = self.cursor.y; if current_line_index >= scroll_region_top && current_line_index <= scroll_region_bottom @@ -649,13 +658,18 @@ impl Grid { // region for _ in 0..count { self.viewport.remove(current_line_index); + let columns = vec![pad_character; self.width]; self.viewport - .insert(scroll_region_bottom, Row::new().canonical()); + .insert(scroll_region_bottom, Row::from_columns(columns).canonical()); } } } } - pub fn add_empty_lines_in_scroll_region(&mut self, count: usize) { + pub fn add_empty_lines_in_scroll_region( + &mut self, + count: usize, + pad_character: TerminalCharacter, + ) { if let Some((scroll_region_top, scroll_region_bottom)) = self.scroll_region { let current_line_index = self.cursor.y; if current_line_index >= scroll_region_top && current_line_index <= scroll_region_bottom @@ -666,8 +680,9 @@ impl Grid { // of the scroll region for _ in 0..count { self.viewport.remove(scroll_region_bottom); + let columns = vec![pad_character; self.width]; self.viewport - .insert(current_line_index, Row::new().canonical()); + .insert(current_line_index, Row::from_columns(columns).canonical()); } } } @@ -676,9 +691,9 @@ impl Grid { self.cursor.x = column; self.pad_current_line_until(self.cursor.x); } - pub fn move_cursor_to_line(&mut self, line: usize) { + pub fn move_cursor_to_line(&mut self, line: usize, pad_character: TerminalCharacter) { self.cursor.y = std::cmp::min(self.height - 1, line); - self.pad_lines_until(self.cursor.y); + self.pad_lines_until(self.cursor.y, pad_character); self.pad_current_line_until(self.cursor.x); } pub fn replace_with_empty_chars(&mut self, count: usize, empty_char_style: CharacterStyles) { diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index e35c2097..fd83d571 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -378,8 +378,9 @@ impl TerminalPane { self.mark_for_rerender(); } fn add_newline(&mut self) { - self.grid.add_canonical_line(); - // self.reset_all_ansi_codes(); // TODO: find out if we should be resetting here or not + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; + self.grid.add_canonical_line(pad_character); self.mark_for_rerender(); } fn move_to_beginning_of_line(&mut self) { @@ -494,7 +495,9 @@ impl vte::Perform for TerminalPane { } else { (params[0] as usize - 1, params[1] as usize - 1) }; - self.grid.move_cursor_to(col, row); + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; + self.grid.move_cursor_to(col, row, pad_character); } else if c == 'A' { // move cursor up until edge of screen let move_up_count = if params[0] == 0 { 1 } else { params[0] }; @@ -502,7 +505,10 @@ impl vte::Perform for TerminalPane { } else if c == 'B' { // move cursor down until edge of screen let move_down_count = if params[0] == 0 { 1 } else { params[0] }; - self.grid.move_cursor_down(move_down_count as usize); + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; + self.grid + .move_cursor_down(move_down_count as usize, pad_character); } else if c == 'D' { let move_back_count = if params[0] == 0 { 1 @@ -592,8 +598,10 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; self.grid - .delete_lines_in_scroll_region(line_count_to_delete); + .delete_lines_in_scroll_region(line_count_to_delete, pad_character); } else if c == 'L' { // insert blank lines if inside scroll region let line_count_to_add = if params[0] == 0 { @@ -601,8 +609,10 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; self.grid - .add_empty_lines_in_scroll_region(line_count_to_add); + .add_empty_lines_in_scroll_region(line_count_to_add, pad_character); } else if c == 'q' { // ignore for now to run on mac } else if c == 'G' { @@ -620,7 +630,9 @@ impl vte::Perform for TerminalPane { // minus 1 because this is 1 indexed params[0] as usize - 1 }; - self.grid.move_cursor_to_line(line); + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; + self.grid.move_cursor_to_line(line, pad_character); } else if c == 'P' { // erase characters let count = if params[0] == 0 { @@ -658,8 +670,13 @@ impl vte::Perform for TerminalPane { } else { params[0] as usize }; - self.grid.delete_lines_in_scroll_region(count); - self.grid.add_empty_lines_in_scroll_region(count); + let mut pad_character = EMPTY_TERMINAL_CHARACTER; + pad_character.styles = self.pending_styles; + self.grid + .delete_lines_in_scroll_region(count, pad_character); + // TODO: since delete_lines_in_scroll_region also adds lines, is the below redundant? + self.grid + .add_empty_lines_in_scroll_region(count, pad_character); } else { let _ = debug_log_to_file(format!("Unhandled csi: {}->{:?}", c, params)); }