Skip to content

Commit 5fd2fd0

Browse files
committed
fix(tui): prevent input top-border label from wrapping on narrow terminals
The flushed-right effort label was appended unconditionally; when the rule was shorter than the label plus its gap, the line overflowed and wrapped, contradicting the method's stated no-wrap invariant. Fall back to the plain full-width rule when the label cannot fit, and add a regression test.
1 parent a3c88fc commit 5fd2fd0

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/pythinker_code/ui/shell/prompt.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,11 @@ def _render_input_top_border(self, columns: int, fallback: str) -> list[tuple[st
24772477
return [(border_style, rule)]
24782478
gap = 2
24792479
label_width = sum(get_cwidth(ch) for _, text in label for ch in text)
2480-
rule_width = max(0, len(rule) - gap - label_width)
2480+
if len(rule) <= gap + label_width:
2481+
# Too narrow for the label plus its gap; a flushed-right label here
2482+
# would overflow and wrap, so fall back to the plain full-width rule.
2483+
return [(border_style, rule)]
2484+
rule_width = len(rule) - gap - label_width
24812485
return [
24822486
(border_style, "─" * rule_width + " " * gap),
24832487
*label,

tests/ui_and_conv/test_prompt_tips.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,29 @@ def test_input_top_border_hides_effort_label_for_native_and_nonthinking() -> Non
681681
]
682682

683683

684+
def test_input_top_border_falls_back_to_plain_rule_when_too_narrow() -> None:
685+
from prompt_toolkit.utils import get_cwidth
686+
687+
from pythinker_code.ui.theme import set_active_theme
688+
689+
set_active_theme("dark")
690+
session = _make_toolbar_session(
691+
model_name="fast-model", model_capabilities={"thinking"}, tips=[]
692+
)
693+
session._thinking = True
694+
session._thinking_effort = "high"
695+
696+
# At this width the rule is too short for the label plus its gap; appending
697+
# the flushed-right label would overflow the rule and wrap the line, so the
698+
# border must collapse to the plain full-width rule instead.
699+
narrow = 6
700+
fragments = session._render_input_top_border(narrow, "class:fallback")
701+
702+
assert fragments == [("class:compact-input.frame", shell_prompt._prompt_rule(narrow))]
703+
total = sum(get_cwidth(ch) for _, text in fragments for ch in text)
704+
assert total == len(shell_prompt._prompt_rule(narrow))
705+
706+
684707
def test_card_toolbar_separator_uses_standard_frame_for_non_thinking_models(
685708
monkeypatch: Any,
686709
) -> None:

0 commit comments

Comments
 (0)