summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2021-04-29 17:06:44 +0000
committerGitHub <noreply@github.com>2021-04-29 17:06:44 +0000
commit4d982894a6859b6d4eeb967ec6dbbf5965c79165 (patch)
treec9ccb721497b6f4d6f26002b9b5e76babab189ac
parent11cbc439c8785ed937125e0ba2a60ef470564a5e (diff)
downloadalacritty-4d982894a6859b6d4eeb967ec6dbbf5965c79165.tar.gz
alacritty-4d982894a6859b6d4eeb967ec6dbbf5965c79165.zip
Fix replacement of fullwidth characters
Fixes #3726.
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty_terminal/src/term/cell.rs8
-rw-r--r--alacritty_terminal/src/term/mod.rs62
3 files changed, 51 insertions, 20 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 094bfb58..a4bf4095 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Incorrect underline cursor thickness on wide cell
- Viewport moving around when resizing while scrolled into history
- Block cursor not expanding across fullwidth characters when on the right side of it
+- Overwriting fullwidth characters only clearing one of the involved cells
### Removed
diff --git a/alacritty_terminal/src/term/cell.rs b/alacritty_terminal/src/term/cell.rs
index 255cbce7..64de5492 100644
--- a/alacritty_terminal/src/term/cell.rs
+++ b/alacritty_terminal/src/term/cell.rs
@@ -99,6 +99,14 @@ impl Cell {
self.extra = None;
}
}
+
+ /// Remove all wide char data from a cell.
+ #[inline(never)]
+ pub fn clear_wide(&mut self) {
+ self.flags.remove(Flags::WIDE_CHAR);
+ self.drop_extra();
+ self.c = ' ';
+ }
}
impl GridCell for Cell {
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index 0e6fa07f..409d4ebe 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -761,13 +761,33 @@ impl<T> Term<T> {
/// Write `c` to the cell at the cursor position.
#[inline(always)]
- fn write_at_cursor(&mut self, c: char) -> &mut Cell {
+ fn write_at_cursor(&mut self, c: char) {
let c = self.grid.cursor.charsets[self.active_charset].map(c);
let fg = self.grid.cursor.template.fg;
let bg = self.grid.cursor.template.bg;
let flags = self.grid.cursor.template.flags;
- let cursor_cell = self.grid.cursor_cell();
+ let mut cursor_cell = self.grid.cursor_cell();
+
+ // Clear all related cells when overwriting a fullwidth cell.
+ if cursor_cell.flags.intersects(Flags::WIDE_CHAR | Flags::WIDE_CHAR_SPACER) {
+ // Remove wide char and spacer.
+ let wide = cursor_cell.flags.contains(Flags::WIDE_CHAR);
+ let point = self.grid.cursor.point;
+ if wide {
+ self.grid[point.line][point.column + 1].flags.remove(Flags::WIDE_CHAR_SPACER);
+ } else {
+ self.grid[point.line][point.column - 1].clear_wide();
+ }
+
+ // Remove leading spacers.
+ if point.column <= 1 && point.line != self.topmost_line() {
+ let column = self.last_column();
+ self.grid[point.line - 1i32][column].flags.remove(Flags::LEADING_WIDE_CHAR_SPACER);
+ }
+
+ cursor_cell = self.grid.cursor_cell();
+ }
cursor_cell.drop_extra();
@@ -775,8 +795,6 @@ impl<T> Term<T> {
cursor_cell.fg = fg;
cursor_cell.bg = bg;
cursor_cell.flags = flags;
-
- cursor_cell
}
}
@@ -810,18 +828,18 @@ impl<T: EventListener> Handler for Term<T> {
// Handle zero-width characters.
if width == 0 {
// Get previous column.
- let mut col = self.grid.cursor.point.column.0;
+ let mut column = self.grid.cursor.point.column;
if !self.grid.cursor.input_needs_wrap {
- col = col.saturating_sub(1);
+ column.0 = column.saturating_sub(1);
}
// Put zerowidth characters over first fullwidth character cell.
let line = self.grid.cursor.point.line;
- if self.grid[line][Column(col)].flags.contains(Flags::WIDE_CHAR_SPACER) {
- col = col.saturating_sub(1);
+ if self.grid[line][column].flags.contains(Flags::WIDE_CHAR_SPACER) {
+ column.0 = column.saturating_sub(1);
}
- self.grid[line][Column(col)].push_zerowidth(c);
+ self.grid[line][column].push_zerowidth(c);
return;
}
@@ -830,16 +848,14 @@ impl<T: EventListener> Handler for Term<T> {
self.wrapline();
}
- let num_cols = self.columns();
-
// If in insert mode, first shift cells to the right.
- if self.mode.contains(TermMode::INSERT) && self.grid.cursor.point.column + width < num_cols
- {
+ let columns = self.columns();
+ if self.mode.contains(TermMode::INSERT) && self.grid.cursor.point.column + width < columns {
let line = self.grid.cursor.point.line;
let col = self.grid.cursor.point.column;
let row = &mut self.grid[line][..];
- for col in (col.0..(num_cols - width)).rev() {
+ for col in (col.0..(columns - width)).rev() {
row.swap(col + width, col);
}
}
@@ -847,10 +863,12 @@ impl<T: EventListener> Handler for Term<T> {
if width == 1 {
self.write_at_cursor(c);
} else {
- if self.grid.cursor.point.column + 1 >= num_cols {
+ if self.grid.cursor.point.column + 1 >= columns {
if self.mode.contains(TermMode::LINE_WRAP) {
// Insert placeholder before wide char if glyph does not fit in this row.
- self.write_at_cursor(' ').flags.insert(Flags::LEADING_WIDE_CHAR_SPACER);
+ self.grid.cursor.template.flags.insert(Flags::LEADING_WIDE_CHAR_SPACER);
+ self.write_at_cursor(' ');
+ self.grid.cursor.template.flags.remove(Flags::LEADING_WIDE_CHAR_SPACER);
self.wrapline();
} else {
// Prevent out of bounds crash when linewrapping is disabled.
@@ -860,14 +878,18 @@ impl<T: EventListener> Handler for Term<T> {
}
// Write full width glyph to current cursor cell.
- self.write_at_cursor(c).flags.insert(Flags::WIDE_CHAR);
+ self.grid.cursor.template.flags.insert(Flags::WIDE_CHAR);
+ self.write_at_cursor(c);
+ self.grid.cursor.template.flags.remove(Flags::WIDE_CHAR);
// Write spacer to cell following the wide glyph.
self.grid.cursor.point.column += 1;
- self.write_at_cursor(' ').flags.insert(Flags::WIDE_CHAR_SPACER);
+ self.grid.cursor.template.flags.insert(Flags::WIDE_CHAR_SPACER);
+ self.write_at_cursor(' ');
+ self.grid.cursor.template.flags.remove(Flags::WIDE_CHAR_SPACER);
}
- if self.grid.cursor.point.column + 1 < num_cols {
+ if self.grid.cursor.point.column + 1 < columns {
self.grid.cursor.point.column += 1;
} else {
self.grid.cursor.input_needs_wrap = true;
@@ -1046,7 +1068,7 @@ impl<T: EventListener> Handler for Term<T> {
}
}
- /// Backspace `count` characters.
+ /// Backspace.
#[inline]
fn backspace(&mut self) {
trace!("Backspace");