aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-01-15 23:45:11 +0800
committerGitHub <noreply@github.com>2024-01-15 23:45:11 +0800
commit9c202b9392f3d42618cc576aab00a50ed2f7bdeb (patch)
treec45df8faac5372593dd780335185c57189aceb45 /src
parent7ed69660237bd052d11af454503a986c22c507a7 (diff)
downloadrneovim-9c202b9392f3d42618cc576aab00a50ed2f7bdeb.tar.gz
rneovim-9c202b9392f3d42618cc576aab00a50ed2f7bdeb.tar.bz2
rneovim-9c202b9392f3d42618cc576aab00a50ed2f7bdeb.zip
fix(grid): handle clearing half a double-width char (#27023)
Diffstat (limited to 'src')
-rw-r--r--src/nvim/grid.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index e4a34ae74a..32b1d3f8eb 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -655,6 +655,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
// two-cell character in the same grid, truncate that into a '>'.
if (col > 0 && grid->chars[off_to + (size_t)col] == 0) {
linebuf_char[col - 1] = schar_from_ascii('>');
+ linebuf_attr[col - 1] = grid->attrs[off_to + (size_t)col - 1];
col--;
}
@@ -676,7 +677,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
}
- redraw_next = grid_char_needs_redraw(grid, col, (size_t)col + off_to, endcol - col);
+ redraw_next = grid_char_needs_redraw(grid, col, off_to + (size_t)col, endcol - col);
int start_dirty = -1;
int end_dirty = 0;
@@ -688,7 +689,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
char_cells = 2;
}
bool redraw_this = redraw_next; // Does character need redraw?
- size_t off = (size_t)col + off_to;
+ size_t off = off_to + (size_t)col;
redraw_next = grid_char_needs_redraw(grid, col + char_cells,
off + (size_t)char_cells,
endcol - col - char_cells);
@@ -732,16 +733,22 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
if (clear_next) {
// Clear the second half of a double-wide character of which the left
// half was overwritten with a single-wide character.
- grid->chars[(size_t)col + off_to] = schar_from_ascii(' ');
+ grid->chars[off_to + (size_t)col] = schar_from_ascii(' ');
end_dirty++;
}
+ // When clearing the left half of a double-wide char also clear the right half.
+ if (off_to + (size_t)clear_width < max_off_to
+ && grid->chars[off_to + (size_t)clear_width] == 0) {
+ clear_width++;
+ }
+
int clear_dirty_start = -1, clear_end = -1;
// blank out the rest of the line
// TODO(bfredl): we could cache winline widths
col = clear_start;
while (col < clear_width) {
- size_t off = (size_t)col + off_to;
+ size_t off = off_to + (size_t)col;
if (grid->chars[off] != schar_from_ascii(' ')
|| grid->attrs[off] != bg_attr
|| rdb_flags & RDB_NODELTA) {