summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-07-06 05:08:36 +0000
committerGitHub <noreply@github.com>2020-07-06 05:08:36 +0000
commit72c916ff434e23d44e2a31e6a8d5f7b8ae649008 (patch)
tree5060c4144153e2e55527c29aa109acec0c79fd85 /alacritty_terminal/src
parent92ea355eeea538bd868eaebdc03469630aba281c (diff)
downloadalacritty-72c916ff434e23d44e2a31e6a8d5f7b8ae649008.tar.gz
alacritty-72c916ff434e23d44e2a31e6a8d5f7b8ae649008.zip
Preserve linewrap flag across alt screen switches
While neither VTE, URxvt nor Kitty handle this, preserving the linewrap flag across alternate screen switches seems like the correct thing to do. XTerm also does handle this correctly, which indicates that it is a bug and not a feature.
Diffstat (limited to 'alacritty_terminal/src')
-rw-r--r--alacritty_terminal/src/grid/mod.rs10
-rw-r--r--alacritty_terminal/src/term/mod.rs32
2 files changed, 23 insertions, 19 deletions
diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs
index 5178ed99..5ad7e8d6 100644
--- a/alacritty_terminal/src/grid/mod.rs
+++ b/alacritty_terminal/src/grid/mod.rs
@@ -71,6 +71,16 @@ pub struct Cursor {
/// Currently configured graphic character sets.
pub charsets: Charsets,
+
+ /// Tracks if the next call to input will need to first handle wrapping.
+ ///
+ /// This is true after the last column is set with the input function. Any function that
+ /// implicitly sets the line or column needs to set this to false to avoid wrapping twice.
+ ///
+ /// Tracking `input_needs_wrap` makes it possible to not store a cursor position that exceeds
+ /// the number of columns, which would lead to index out of bounds when interacting with arrays
+ /// without sanitization.
+ pub input_needs_wrap: bool,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index 16e4de92..a1f816b6 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -741,13 +741,6 @@ pub struct Term<T> {
pub selection: Option<Selection>,
- /// Tracks if the next call to input will need to first handle wrapping.
- /// This is true after the last column is set with the input function. Any function that
- /// implicitly sets the line or column needs to set this to false to avoid wrapping twice.
- /// input_needs_wrap ensures that cursor.col is always valid for use into indexing into
- /// arrays. Without it we would have to sanitize cursor.col every time we used it.
- input_needs_wrap: bool,
-
/// Currently active grid.
///
/// Tracks the screen buffer currently in use. While the alternate screen buffer is active,
@@ -839,7 +832,6 @@ impl<T> Term<T> {
Term {
dirty: false,
visual_bell: VisualBell::new(config),
- input_needs_wrap: false,
grid,
inactive_grid: alt,
active_charset: Default::default(),
@@ -1079,6 +1071,9 @@ impl<T> Term<T> {
} else {
self.inactive_grid.saved_cursor = self.inactive_grid.cursor;
self.grid.saved_cursor = self.grid.cursor;
+
+ // Reset wrapline status flag.
+ self.inactive_grid.cursor.input_needs_wrap = false;
}
mem::swap(&mut self.grid, &mut self.inactive_grid);
@@ -1235,7 +1230,7 @@ impl<T> Term<T> {
}
self.grid.cursor.point.col = Column(0);
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
/// Write `c` to the cell at the cursor position.
@@ -1347,7 +1342,7 @@ impl<T: EventListener> Handler for Term<T> {
}
// Move cursor to next line.
- if self.input_needs_wrap {
+ if self.grid.cursor.input_needs_wrap {
self.wrapline();
}
@@ -1376,7 +1371,7 @@ impl<T: EventListener> Handler for Term<T> {
self.wrapline();
} else {
// Prevent out of bounds crash when linewrapping is disabled.
- self.input_needs_wrap = true;
+ self.grid.cursor.input_needs_wrap = true;
return;
}
}
@@ -1392,7 +1387,7 @@ impl<T: EventListener> Handler for Term<T> {
if self.grid.cursor.point.col + 1 < num_cols {
self.grid.cursor.point.col += 1;
} else {
- self.input_needs_wrap = true;
+ self.grid.cursor.input_needs_wrap = true;
}
}
@@ -1415,7 +1410,7 @@ impl<T: EventListener> Handler for Term<T> {
self.grid.cursor.point.line = min(line + y_offset, max_y);
self.grid.cursor.point.col = min(col, self.grid.num_cols() - 1);
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
#[inline]
@@ -1476,14 +1471,14 @@ impl<T: EventListener> Handler for Term<T> {
trace!("Moving forward: {}", cols);
let num_cols = self.grid.num_cols();
self.grid.cursor.point.col = min(self.grid.cursor.point.col + cols, num_cols - 1);
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
#[inline]
fn move_backward(&mut self, cols: Column) {
trace!("Moving backward: {}", cols);
self.grid.cursor.point.col = Column(self.grid.cursor.point.col.saturating_sub(cols.0));
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
#[inline]
@@ -1526,7 +1521,7 @@ impl<T: EventListener> Handler for Term<T> {
#[inline]
fn put_tab(&mut self, mut count: i64) {
// A tab after the last column is the same as a linebreak.
- if self.input_needs_wrap {
+ if self.grid.cursor.input_needs_wrap {
self.wrapline();
return;
}
@@ -1561,7 +1556,7 @@ impl<T: EventListener> Handler for Term<T> {
if self.grid.cursor.point.col > Column(0) {
self.grid.cursor.point.col -= 1;
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
}
@@ -1570,7 +1565,7 @@ impl<T: EventListener> Handler for Term<T> {
fn carriage_return(&mut self) {
trace!("Carriage return");
self.grid.cursor.point.col = Column(0);
- self.input_needs_wrap = false;
+ self.grid.cursor.input_needs_wrap = false;
}
/// Linefeed.
@@ -1933,7 +1928,6 @@ impl<T: EventListener> Handler for Term<T> {
if self.mode.contains(TermMode::ALT_SCREEN) {
mem::swap(&mut self.grid, &mut self.inactive_grid);
}
- self.input_needs_wrap = false;
self.active_charset = Default::default();
self.mode = Default::default();
self.colors = self.original_colors;