Fix saved cursor handling

This resolves several problems with handling of the saved cursor when
switching between primary and alternate screen. Additionally ref-tests
are also added for all common interactions to make sure the behavior
does not regress.

The behavior is based on XTerm's behavior except for interaction with
`reset`. XTerm does not reset the alternate screen's saved cursor on
`reset`, but VTE does. Since a `reset` should reset as much as possible,
Alacritty copies VTE here instead of XTerm.
This commit is contained in:
Christian Duerr 2020-07-06 19:10:06 +00:00 committed by GitHub
parent 72c916ff43
commit 65bff1878f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 28 additions and 9 deletions

View File

@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Incorrectly deleted lines when increasing width with a prompt wrapped using spaces
- Documentation for class in `--help` missing information on setting general class
- Linewrap tracking when switching between primary and alternate screen buffer
- Preservation of the alternate screen's saved cursor when swapping to primary screen and back
## 0.4.3

View File

@ -1062,18 +1062,16 @@ impl<T> Term<T> {
/// Swap primary and alternate screen buffer.
pub fn swap_alt(&mut self) {
if self.mode.contains(TermMode::ALT_SCREEN) {
let template = self.grid.cursor.template;
self.grid.region_mut(..).each(|c| c.reset(&template));
if !self.mode.contains(TermMode::ALT_SCREEN) {
// Set alt screen cursor to the current primary screen cursor.
self.inactive_grid.cursor = self.grid.cursor;
self.inactive_grid.cursor = self.inactive_grid.saved_cursor;
self.grid.cursor = self.grid.saved_cursor;
} else {
self.inactive_grid.saved_cursor = self.inactive_grid.cursor;
// Drop information about the primary screens saved cursor.
self.grid.saved_cursor = self.grid.cursor;
// Reset wrapline status flag.
self.inactive_grid.cursor.input_needs_wrap = false;
// Reset alternate screen contents.
let template = self.inactive_grid.cursor.template;
self.inactive_grid.region_mut(..).each(|c| c.reset(&template));
}
mem::swap(&mut self.grid, &mut self.inactive_grid);

View File

@ -64,6 +64,8 @@ ref_tests! {
clear_underline
region_scroll_down
wrapline_alt_toggle
saved_cursor
saved_cursor_alt
}
fn read_u8<P>(path: P) -> Vec<u8>

View File

@ -0,0 +1,8 @@
[undeadleech@archhq saved_cursor]$ echo -e "\e7 \e(0 test \e8 xxx"
7 (0 test 8 xxx
[undeadleech@archhq saved_cursor]$ echo -e "\e[?1049h \e(0 test \e[?1049l xxx"
[?1049h (0 test [?1049l xxx
[undeadleech@archhq saved_cursor]$ echo -e "\e7 \e(0 \e[?1049h test \e[?1049l \e8 xxx"
7 (0 [?1049h test [?1049l 8 xxx
[undeadleech@archhq saved_cursor]$ exit
exit

View File

@ -0,0 +1 @@
{"history_size":0}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}

View File

@ -0,0 +1,4 @@
[undeadleech@archhq saved_cursor_alt]$ echo -e "\e(0\e[10;$(tput cols)H \e[?1049h\e7 \e[?1049l \e(B\e[H \e[?1049h test\e8xxx"
(0 [?1049h7 [?1049l (B [?1049h test8xxx
[undeadleech@archhq saved_cursor_alt]$ exit
exit

View File

@ -0,0 +1 @@
{"history_size":0}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}