diff options
author | a5ob7r <12132068+a5ob7r@users.noreply.github.com> | 2021-12-03 16:45:05 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-03 07:45:05 +0000 |
commit | 7e736c00f68ca133ca3380c1ddd78ba61ced1f8e (patch) | |
tree | 20742613e38284289a6f15fe9df2d2bbc5d98f63 | |
parent | 4c6a763850a5dec0fa34d15e356dcba19875690a (diff) | |
download | alacritty-7e736c00f68ca133ca3380c1ddd78ba61ced1f8e.tar.gz alacritty-7e736c00f68ca133ca3380c1ddd78ba61ced1f8e.zip |
Fix crash when vi cursor in history during clear
Fixes #5544.
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | alacritty_terminal/src/grid/mod.rs | 3 | ||||
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 50 |
3 files changed, 55 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec65dce..157c7150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Vi mode search starting in the line below the vi cursor - Invisible cursor with matching foreground/background colors - Crash when hovering over a match emptied by post-processing +- Crash when the vi cursor is on the scrollback and viewport clear is invoked +- Freeze when the vi cursor is on the scrollback and scrollback clear is invoked ### Removed diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs index df83d7e3..230dc5b5 100644 --- a/alacritty_terminal/src/grid/mod.rs +++ b/alacritty_terminal/src/grid/mod.rs @@ -376,6 +376,9 @@ impl<T> Grid<T> { pub fn clear_history(&mut self) { // Explicitly purge all lines from history. self.raw.shrink_lines(self.history_size()); + + // Reset display offset. + self.display_offset = 0; } /// This is used only for initializing after loading ref-tests. diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 9b7a4c35..2ea0afc3 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -1424,6 +1424,9 @@ impl<T: EventListener> Handler for Term<T> { self.grid.reset_region(..); } else { self.grid.clear_viewport(); + + self.vi_mode_cursor.point.line = + self.vi_mode_cursor.point.line.grid_clamp(self, Boundary::Cursor); } self.selection = None; @@ -1431,6 +1434,9 @@ impl<T: EventListener> Handler for Term<T> { ansi::ClearMode::Saved if self.history_size() > 0 => { self.grid.clear_history(); + self.vi_mode_cursor.point.line = + self.vi_mode_cursor.point.line.grid_clamp(self, Boundary::Cursor); + self.selection = self.selection.take().filter(|s| !s.intersects_range(..Line(0))); }, // We have no history to clear. @@ -2119,6 +2125,50 @@ mod tests { } #[test] + fn clear_viewport_set_vi_cursor_into_viewport() { + let size = SizeInfo::new(10.0, 20.0, 1.0, 1.0, 0.0, 0.0, false); + let mut term = Term::new(&Config::default(), size, ()); + + // Create 10 lines of scrollback. + for _ in 0..29 { + term.newline(); + } + + // Change the display area and the vi cursor position. + term.scroll_display(Scroll::Top); + term.vi_mode_cursor.point = Point::new(Line(-5), Column(3)); + + // Clear the viewport. + term.clear_screen(ansi::ClearMode::All); + + assert_eq!(term.grid.display_offset(), 0); + assert_eq!(term.vi_mode_cursor.point.line.0, 0); + assert_eq!(term.vi_mode_cursor.point.column.0, 3); + } + + #[test] + fn clear_scrollback_set_vi_cursor_into_viewport() { + let size = SizeInfo::new(10.0, 20.0, 1.0, 1.0, 0.0, 0.0, false); + let mut term = Term::new(&Config::default(), size, ()); + + // Create 10 lines of scrollback. + for _ in 0..29 { + term.newline(); + } + + // Change the display area and the vi cursor position. + term.scroll_display(Scroll::Top); + term.vi_mode_cursor.point = Point::new(Line(-5), Column(3)); + + // Clear the scrollback buffer. + term.clear_screen(ansi::ClearMode::Saved); + + assert_eq!(term.grid.display_offset(), 0); + assert_eq!(term.vi_mode_cursor.point.line.0, 0); + assert_eq!(term.vi_mode_cursor.point.column.0, 3); + } + + #[test] fn clear_saved_lines() { let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&Config::default(), size, ()); |