summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authora5ob7r <12132068+a5ob7r@users.noreply.github.com>2021-12-19 00:36:56 +0900
committerGitHub <noreply@github.com>2021-12-18 15:36:56 +0000
commitcded85a2f2c1c554d64bae285ccd8f9815468d4d (patch)
tree758612432075bd9d4fc260fc3e70ad106a6957fb
parent8e58409930354c71c102ba7b86d1732b6c053642 (diff)
downloadalacritty-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.md1
-rw-r--r--alacritty_terminal/src/grid/mod.rs3
-rw-r--r--alacritty_terminal/src/term/mod.rs69
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(&region, 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]