summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authora5ob7r <12132068+a5ob7r@users.noreply.github.com>2021-12-03 16:45:05 +0900
committerGitHub <noreply@github.com>2021-12-03 07:45:05 +0000
commit7e736c00f68ca133ca3380c1ddd78ba61ced1f8e (patch)
tree20742613e38284289a6f15fe9df2d2bbc5d98f63
parent4c6a763850a5dec0fa34d15e356dcba19875690a (diff)
downloadalacritty-7e736c00f68ca133ca3380c1ddd78ba61ced1f8e.tar.gz
alacritty-7e736c00f68ca133ca3380c1ddd78ba61ced1f8e.zip
Fix crash when vi cursor in history during clear
Fixes #5544.
-rw-r--r--CHANGELOG.md2
-rw-r--r--alacritty_terminal/src/grid/mod.rs3
-rw-r--r--alacritty_terminal/src/term/mod.rs50
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, ());