From 7f0674ac277c9e39977af1dd1887883c1ad78e24 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 7 Sep 2018 10:08:25 +0530 Subject: [PATCH] Fix backspacing of wide characters in wide-character unaware programs not working Fixes #875 --- docs/changelog.rst | 2 ++ kitty/screen.c | 10 +++++++++- kitty_tests/screen.py | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 3190ee57e..7b39358b8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,8 @@ Changelog font fallback for all subsequent characters that cannot be rendered in the main font to fail (:iss:`799`) +- Fix backspacing of wide characters in wide-character unaware programs not working (:iss:`875`) + - Linux: Fix number pad arrow keys not working when Numlock is off (:iss:`857`) - Wayland: Implement support for clipboard copy/paste (:iss:`855`) diff --git a/kitty/screen.c b/kitty/screen.c index 0000f5e36..872eed784 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -708,7 +708,15 @@ screen_is_cursor_visible(Screen *self) { void screen_backspace(Screen *self) { - screen_cursor_back(self, 1, -1); + unsigned int amount = 1; + if (self->cursor->x < self->columns && self->cursor->x > 1) { + // check if previous character is a wide character + linebuf_init_line(self->linebuf, self->cursor->y); + unsigned int xpos = self->cursor->x - 2; + GPUCell *gpu_cell = self->linebuf->line->gpu_cells + xpos; + if ((gpu_cell->attrs & WIDTH_MASK) == 2) amount = 2; + } + screen_cursor_back(self, amount, -1); } void diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index dc96c8068..ed35559be 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -222,6 +222,15 @@ class TestScreen(BaseTest): for i in range(1, 5): self.ae(str(s.line(i)), '12345') + def test_backspace_wide_characters(self): + s = self.create_screen() + s.draw('⛅') + self.ae(s.cursor.x, 2) + s.backspace() + s.draw(' ') + s.backspace() + self.ae(s.cursor.x, 0) + def test_resize(self): s = self.create_screen(scrollback=6) s.draw(''.join([str(i) * s.columns for i in range(s.lines)]))