mirror of
https://github.com/Textualize/rich.git
synced 2025-07-07 21:04:58 +00:00
Fix hang when Rule title greater than required space
This commit is contained in:
parent
d9a0d47946
commit
dbb27d30a7
4 changed files with 67 additions and 16 deletions
|
@ -80,7 +80,7 @@ def set_cell_size(text: str, total: int) -> str:
|
|||
return text + " " * (total - size)
|
||||
return text[:total]
|
||||
|
||||
if not total:
|
||||
if total <= 0:
|
||||
return ""
|
||||
cell_size = cell_len(text)
|
||||
if cell_size == total:
|
||||
|
|
31
rich/rule.py
31
rich/rule.py
|
@ -63,10 +63,7 @@ class Rule(JupyterMixin):
|
|||
|
||||
chars_len = cell_len(characters)
|
||||
if not self.title:
|
||||
rule_text = Text(characters * ((width // chars_len) + 1), self.style)
|
||||
rule_text.truncate(width)
|
||||
rule_text.plain = set_cell_size(rule_text.plain, width)
|
||||
yield rule_text
|
||||
yield self._rule_line(chars_len, width)
|
||||
return
|
||||
|
||||
if isinstance(self.title, Text):
|
||||
|
@ -76,10 +73,16 @@ class Rule(JupyterMixin):
|
|||
|
||||
title_text.plain = title_text.plain.replace("\n", " ")
|
||||
title_text.expand_tabs()
|
||||
rule_text = Text(end=self.end)
|
||||
|
||||
required_space = 4 if self.align == "center" else 2
|
||||
truncate_width = max(0, width - required_space)
|
||||
if not truncate_width:
|
||||
yield self._rule_line(chars_len, width)
|
||||
return
|
||||
|
||||
rule_text = Text(end=self.end)
|
||||
if self.align == "center":
|
||||
title_text.truncate(width - 4, overflow="ellipsis")
|
||||
title_text.truncate(truncate_width, overflow="ellipsis")
|
||||
side_width = (width - cell_len(title_text.plain)) // 2
|
||||
left = Text(characters * (side_width // chars_len + 1))
|
||||
left.truncate(side_width - 1)
|
||||
|
@ -90,12 +93,12 @@ class Rule(JupyterMixin):
|
|||
rule_text.append(title_text)
|
||||
rule_text.append(" " + right.plain, self.style)
|
||||
elif self.align == "left":
|
||||
title_text.truncate(width - 2, overflow="ellipsis")
|
||||
title_text.truncate(truncate_width, overflow="ellipsis")
|
||||
rule_text.append(title_text)
|
||||
rule_text.append(" ")
|
||||
rule_text.append(characters * (width - rule_text.cell_len), self.style)
|
||||
elif self.align == "right":
|
||||
title_text.truncate(width - 2, overflow="ellipsis")
|
||||
title_text.truncate(truncate_width, overflow="ellipsis")
|
||||
rule_text.append(characters * (width - title_text.cell_len - 1), self.style)
|
||||
rule_text.append(" ")
|
||||
rule_text.append(title_text)
|
||||
|
@ -103,6 +106,12 @@ class Rule(JupyterMixin):
|
|||
rule_text.plain = set_cell_size(rule_text.plain, width)
|
||||
yield rule_text
|
||||
|
||||
def _rule_line(self, chars_len: int, width: int) -> Text:
|
||||
rule_text = Text(self.characters * ((width // chars_len) + 1), self.style)
|
||||
rule_text.truncate(width)
|
||||
rule_text.plain = set_cell_size(rule_text.plain, width)
|
||||
return rule_text
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> Measurement:
|
||||
|
@ -110,12 +119,16 @@ class Rule(JupyterMixin):
|
|||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from rich.console import Console
|
||||
import sys
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
try:
|
||||
text = sys.argv[1]
|
||||
except IndexError:
|
||||
text = "Hello, World"
|
||||
console = Console()
|
||||
console.print(Rule(title=text))
|
||||
|
||||
console = Console()
|
||||
console.print(Rule("foo"), width=4)
|
||||
|
|
|
@ -61,6 +61,47 @@ def test_rule_cjk():
|
|||
assert console.file.getvalue() == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"align,outcome",
|
||||
[
|
||||
("center", "───\n"),
|
||||
("left", "… ─\n"),
|
||||
("right", "─ …\n"),
|
||||
],
|
||||
)
|
||||
def test_rule_not_enough_space_for_title_text(align, outcome):
|
||||
console = Console(width=3, file=io.StringIO(), record=True)
|
||||
console.rule("Hello!", align=align)
|
||||
assert console.file.getvalue() == outcome
|
||||
|
||||
|
||||
def test_rule_center_aligned_title_not_enough_space_for_rule():
|
||||
console = Console(width=4, file=io.StringIO(), record=True)
|
||||
console.rule("ABCD")
|
||||
assert console.file.getvalue() == "────\n"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("align", ["left", "right"])
|
||||
def test_rule_side_aligned_not_enough_space_for_rule(align):
|
||||
console = Console(width=2, file=io.StringIO(), record=True)
|
||||
console.rule("ABCD", align=align)
|
||||
assert console.file.getvalue() == "──\n"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"align,outcome",
|
||||
[
|
||||
("center", "─ … ─\n"),
|
||||
("left", "AB… ─\n"),
|
||||
("right", "─ AB…\n"),
|
||||
],
|
||||
)
|
||||
def test_rule_just_enough_width_available_for_title(align, outcome):
|
||||
console = Console(width=5, file=io.StringIO(), record=True)
|
||||
console.rule("ABCD", align=align)
|
||||
assert console.file.getvalue() == outcome
|
||||
|
||||
|
||||
def test_characters():
|
||||
console = Console(
|
||||
width=16,
|
||||
|
|
|
@ -34,7 +34,6 @@ def test_spinner_render():
|
|||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Broken with Rule.__rich__measure in place")
|
||||
def test_spinner_update():
|
||||
time = 0.0
|
||||
|
||||
|
@ -47,17 +46,15 @@ def test_spinner_update():
|
|||
spinner = Spinner("dots")
|
||||
console.print(spinner)
|
||||
|
||||
spinner.update(text="Bar", style="green", speed=2)
|
||||
time += 80 / 1000
|
||||
console.print(spinner)
|
||||
rule = Rule("Bar")
|
||||
|
||||
spinner.update(text=Rule("Bar"))
|
||||
spinner.update(text=rule)
|
||||
time += 80 / 1000
|
||||
console.print(spinner)
|
||||
|
||||
result = console.end_capture()
|
||||
print(repr(result))
|
||||
expected = f"⠋\n\x1b[32m⠙\x1b[0m Bar\n\x1b[32m⠸\x1b[0m \x1b[92m────── \x1b[0mBar\x1b[92m ───────\x1b[0m\n"
|
||||
expected = "⠋\n⠙ \x1b[92m─\x1b[0m\n"
|
||||
assert result == expected
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue