From 4f40703e4fa01a749b306b2161a425a314b85606 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 4 Oct 2024 11:55:26 +0100 Subject: [PATCH] fix for split cells --- rich/segment.py | 33 +++++++++++++++------------------ tests/test_segment.py | 15 ++++++++++----- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/rich/segment.py b/rich/segment.py index 5986aac72..34f84b9dc 100644 --- a/rich/segment.py +++ b/rich/segment.py @@ -129,34 +129,31 @@ def _split_cells(cls, segment: "Segment", cut: int) -> Tuple["Segment", "Segment cell_size = get_character_cell_size - pos = int((cut / cell_length) * (len(text))) - 1 - if pos < 0: - pos = 0 + pos = int((cut / cell_length) * len(text)) - before = text[:pos] - cell_pos = cell_len(before) - if cell_pos == cut: - return ( - _Segment(before, style, control), - _Segment(text[pos:], style, control), - ) - while pos < len(text): - char = text[pos] - pos += 1 - cell_pos += cell_size(char) + while True: before = text[:pos] - if cell_pos == cut: + cell_pos = cell_len(before) + out_by = cell_pos - cut + if not out_by: return ( _Segment(before, style, control), _Segment(text[pos:], style, control), ) - if cell_pos > cut: + if out_by == -1 and cell_size(text[pos]) == 2: + return ( + _Segment(before[:pos] + " ", style, control), + _Segment(" " + text[pos + 1 :], style, control), + ) + if out_by == +1 and cell_size(text[pos]) == 2: return ( _Segment(before[: pos - 1] + " ", style, control), _Segment(" " + text[pos:], style, control), ) - - raise AssertionError("Will never reach here") + if cell_pos < cut: + pos += 1 + else: + pos -= 1 def split_cells(self, cut: int) -> Tuple["Segment", "Segment"]: """Split segment in to two segments at the specified column. diff --git a/tests/test_segment.py b/tests/test_segment.py index 4dac53c8c..4bdb01453 100644 --- a/tests/test_segment.py +++ b/tests/test_segment.py @@ -288,11 +288,16 @@ def test_split_cells_emoji(text, split, result): def test_split_cells_mixed() -> None: """Check that split cells splits on cell positions.""" # Caused https://github.com/Textualize/textual/issues/4996 in Textual - test = Segment("早乙女リリエル (CV: 徳井青)") - for position in range(1, test.cell_length): - left, right = Segment.split_cells(test, position) - assert cell_len(left.text) == position - assert cell_len(right.text) == test.cell_length - position + tests = [ + Segment("早乙女リリエル (CV: 徳井青)"), + Segment("メイド・イン・きゅんクチュアリ☆"), + Segment("TVアニメ「メルクストーリア -無気力少年と瓶の中の少女-」 主題歌CD"), + ] + for test in tests: + for position in range(1, test.cell_length): + left, right = Segment.split_cells(test, position) + assert cell_len(left.text) == position + assert cell_len(right.text) == test.cell_length - position def test_split_cells_doubles() -> None: