Merge pull request #6038 from Textualize/expand-tabs-fix

fix for expand tabs
This commit is contained in:
Will McGugan
2025-08-12 13:40:45 +01:00
committed by GitHub
3 changed files with 52 additions and 6 deletions

View File

@@ -334,10 +334,7 @@ class Content(Visual):
"""
if not text:
return Content("")
span_length = cell_len(text) if cell_length is None else cell_length
new_content = cls(
text, [Span(0, span_length, style)] if style else None, span_length
)
new_content = cls(text, [Span(0, len(text), style)] if style else None)
return new_content
@classmethod
@@ -844,6 +841,8 @@ class Content(Visual):
total_cell_length: int | None = self._cell_length
for content in iter_content():
if not content:
continue
extend_text(content._text)
extend_spans(
_Span(offset + start, offset + end, style)
@@ -1437,6 +1436,9 @@ class Content(Visual):
if "\t" not in self.plain:
return self
if not self._spans:
return Content(self.plain.expandtabs(tab_size))
new_text: list[Content] = []
append = new_text.append
@@ -1449,7 +1451,7 @@ class Content(Visual):
for part in parts:
if part.plain.endswith("\t"):
part = Content(
part._text[-1][:-1] + " ", part._spans, part._cell_length
part._text[:-1] + " ", part._spans, part._cell_length
)
cell_position += part.cell_length
tab_remainder = cell_position % tab_size

View File

@@ -41,7 +41,7 @@ _get_hash_attributes = attrgetter(
)
@rich.repr.auto(angular=True)
@rich.repr.auto()
@dataclass(frozen=True)
class Style:
"""Represents a style in the Visual interface (color and other attributes).

View File

@@ -294,3 +294,47 @@ def test_simplify():
assert content.spans == [Span(0, 3, "bold"), Span(3, 6, "bold")]
content.simplify()
assert content.spans == [Span(0, 6, "bold")]
@pytest.mark.parametrize(
["input", "tab_width", "expected"],
[
(Content(""), 8, Content("")),
(Content("H"), 8, Content("H")),
(Content("Hello"), 8, Content("Hello")),
(Content("\t"), 8, Content(" " * 8)),
(Content("A\t"), 8, Content("A" + " " * 7)),
(Content("ABCD\t"), 8, Content("ABCD" + " " * 4)),
(Content("ABCDEFG\t"), 8, Content("ABCDEFG ")),
(Content("ABCDEFGH\t"), 8, Content("ABCDEFGH" + " " * 8)),
(Content("Hel\tlo!"), 4, Content("Hel lo!")),
(Content("\t\t"), 4, Content(" " * 8)),
(Content("FO\t\t"), 4, Content("FO ")),
(Content("FO\tOB\t"), 4, Content("FO OB ")),
(
Content("FOO", spans=[Span(0, 3, "red")]),
4,
Content("FOO", spans=[Span(0, 3, "red")]),
),
(
Content("FOO\tBAR", spans=[Span(0, 3, "red")]),
8,
Content("FOO BAR", spans=[Span(0, 3, "red")]),
),
(
Content("FOO\tBAR", spans=[Span(0, 3, "red"), Span(4, 8, "blue")]),
8,
Content("FOO BAR", spans=[Span(0, 3, "red"), Span(8, 11, "blue")]),
),
(
Content("foo\tbar\nbaz", spans=[Span(0, 11, "red")]),
8,
Content("foo bar\nbaz", spans=[Span(0, 15, "red")]),
),
],
)
def test_expand_tabs(input: Content, tab_width: int, expected: Content):
output = input.expand_tabs(tab_width).simplify()
print(repr(output))
assert output.plain == expected.plain
assert output._spans == expected._spans