From ebd1614316ea541cd1ac0cc0029f771be333176e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 16 May 2025 10:46:25 +0200 Subject: [PATCH] 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 --- CHANGELOG.md | 4 ++++ csi.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea818d53..00c1f0a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,10 @@ ### Removed ### Fixed + +* `REP`: wrong width of repeated multi-codepoint graphemes. + + ### Security ### Contributors diff --git a/csi.c b/csi.c index e8b2c492..6d4845be 100644 --- a/csi.c +++ b/csi.c @@ -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);