csi: when REP:ing a "combining" character, use correct width

Before this patch, we just called c32width(), which only works on
actual codepoints. If the last printed character is a "combining"
character, i.e. a key into our lookup table for multi-codepoint
graphemes, we need to lookup the grapheme and pick the width from
there.

See https://gitlab.com/AutumnMeowMeow/jexer/-/issues/119#note_2499712901
This commit is contained in:
Daniel Eklöf 2025-05-16 10:46:25 +02:00
parent 9b0d5e7c96
commit ebd1614316
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 15 additions and 1 deletions

View file

@ -116,6 +116,10 @@
### Removed
### Fixed
* `REP`: wrong width of repeated multi-codepoint graphemes.
### Security
### Contributors

12
csi.c
View file

@ -799,7 +799,17 @@ csi_dispatch(struct terminal *term, uint8_t final)
int count = vt_param_get(term, 0, 1);
LOG_DBG("REP: '%lc' %d times", (wint_t)term->vt.last_printed, count);
const int width = c32width(term->vt.last_printed);
int width;
if (term->vt.last_printed >= CELL_COMB_CHARS_LO) {
const struct composed *comp = composed_lookup(
term->composed, term->vt.last_printed - CELL_COMB_CHARS_LO);
xassert(comp != NULL);
width = comp->forced_width > 0 ? comp->forced_width : comp->width;
} else
width = c32width(term->vt.last_printed);
if (width > 0) {
for (int i = 0; i < count; i++)
term_print(term, term->vt.last_printed, width, false);