From 0de069f35aae38a8d983044a657bf7f5873b6399 Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Sat, 24 Oct 2026 12:46:53 -0600 Subject: [PATCH] fix(console): count a virama conjunct as one cell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Hindi conjunct such as न्द in हिन्दी drew the --list border one cell short. --- tests/core/test_console_cell_width.py | 5 +++++ unshackle/core/console.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/tests/core/test_console_cell_width.py b/tests/core/test_console_cell_width.py index 5aa2ae1b..c8256253 100644 --- a/tests/core/test_console_cell_width.py +++ b/tests/core/test_console_cell_width.py @@ -22,3 +22,8 @@ def test_panel_pads_an_indic_label_to_the_border() -> None: Console(file=out, width=20, color_system=None).print(Panel("हिंदी")) assert out.getvalue().splitlines()[1] == "│ हिंदी" + " " * 12 + " │" + + +def test_a_virama_conjunct_shares_one_cell() -> None: + assert cell_len("हिन्दी") == 4 # न्द is one conjunct + assert cell_len("ಕನ್ನಡ") == 4 # a Kannada virama does not join, so ನ್ನ keeps two cells diff --git a/unshackle/core/console.py b/unshackle/core/console.py index 843b2fb2..2f0efac2 100644 --- a/unshackle/core/console.py +++ b/unshackle/core/console.py @@ -426,7 +426,23 @@ def _cell_size(character: str, *args: str) -> int: return 1 if unicodedata.category(character) == "Mc" else _rich_cell_size(character, *args) +# the viramas that join the next consonant into one cluster (Unicode InCB=Linker); Tamil and Kannada do not +_JOINING_VIRAMAS = frozenset("्্્୍్്") +_rich_cell_len = rich.cells._cell_len + + +def _cell_len(text: str, *args: str) -> int: + """Count a consonant joined by a virama (the न्द in हिन्दी) as no cell: terminals draw the conjunct in one.""" + width = _rich_cell_len(text, *args) + if _JOINING_VIRAMAS.isdisjoint(text): + return width + return width - sum( + prev in _JOINING_VIRAMAS and unicodedata.category(char) == "Lo" for prev, char in zip(text, text[1:]) + ) + + rich.cells.get_character_cell_size = _cell_size +rich.cells._cell_len = _cell_len rich.cells.cached_cell_len.cache_clear() console = ComfyConsole(