diff options
author | a5ob7r <12132068+a5ob7r@users.noreply.github.com> | 2021-12-19 00:36:56 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-18 15:36:56 +0000 |
commit | cded85a2f2c1c554d64bae285ccd8f9815468d4d (patch) | |
tree | 758612432075bd9d4fc260fc3e70ad106a6957fb | |
parent | 8e58409930354c71c102ba7b86d1732b6c053642 (diff) | |
download | alacritty-cded85a2f2c1c554d64bae285ccd8f9815468d4d.tar.gz alacritty-cded85a2f2c1c554d64bae285ccd8f9815468d4d.zip |
Keep history position when viewport is cleared
This patch resolves a behavior that display area doesn't keep track of
content in a scrollback buffer due to display offset reset when viewport
clear is invoked.
This is similar to #5341, but this problem is caused by viewport clear
instead of new outputs to the viewport.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | alacritty_terminal/src/grid/mod.rs | 3 | ||||
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 69 |
3 files changed, 63 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 74ab5fc5..64cd7c5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Config option `background_opacity`, you should use `window.opacity` instead - Reload configuration files when their symbolic link is replaced - Strip trailing whitespaces when yanking from a block selection +- Display area keeps history position when viewport is cleared ### Fixed diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs index 230dc5b5..8b94ac41 100644 --- a/alacritty_terminal/src/grid/mod.rs +++ b/alacritty_terminal/src/grid/mod.rs @@ -313,9 +313,6 @@ impl<T: GridCell + Default + PartialEq + Clone> Grid<T> { let positions = (iter.point.line.0 + 1) as usize; let region = Line(0)..Line(self.lines as i32); - // Reset display offset. - self.display_offset = 0; - // Clear the viewport. self.scroll_up(®ion, positions); diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 820d8bd9..c7c461f4 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -1424,10 +1424,15 @@ impl<T: EventListener> Handler for Term<T> { if self.mode.contains(TermMode::ALT_SCREEN) { self.grid.reset_region(..); } else { + let old_offset = self.grid.display_offset(); + self.grid.clear_viewport(); + // Compute number of lines scrolled by clearing the viewport. + let lines = self.grid.display_offset().saturating_sub(old_offset); + self.vi_mode_cursor.point.line = - self.vi_mode_cursor.point.line.grid_clamp(self, Boundary::Cursor); + (self.vi_mode_cursor.point.line - lines).grid_clamp(self, Boundary::Grid); } self.selection = None; @@ -2126,7 +2131,7 @@ mod tests { } #[test] - fn clear_viewport_set_vi_cursor_into_viewport() { + fn clearing_viewport_keeps_history_position() { 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, ()); @@ -2135,20 +2140,66 @@ mod tests { term.newline(); } + // Change the display area. + term.scroll_display(Scroll::Top); + + assert_eq!(term.grid.display_offset(), 10); + + // Clear the viewport. + term.clear_screen(ansi::ClearMode::All); + + assert_eq!(term.grid.display_offset(), 10); + } + + #[test] + fn clearing_viewport_with_vi_mode_keeps_history_position() { + 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(); + } + + // Enable vi mode. + term.toggle_vi_mode(); + // 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)); + assert_eq!(term.grid.display_offset(), 10); + // Clear the viewport. term.clear_screen(ansi::ClearMode::All); + assert_eq!(term.grid.display_offset(), 10); + assert_eq!(term.vi_mode_cursor.point, Point::new(Line(-5), Column(3))); + } + + #[test] + fn clearing_scrollback_resets_display_offset() { + 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. + term.scroll_display(Scroll::Top); + + assert_eq!(term.grid.display_offset(), 10); + + // 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_scrollback_set_vi_cursor_into_viewport() { + fn clearing_scrollback_sets_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, ()); @@ -2157,16 +2208,20 @@ mod tests { term.newline(); } + // Enable vi mode. + term.toggle_vi_mode(); + // 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)); + assert_eq!(term.grid.display_offset(), 10); + // 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); + assert_eq!(term.vi_mode_cursor.point, Point::new(Line(0), Column(3))); } #[test] |