Wizard text is clipped to the panel and measured in cells; the list header says what is shown (review B1, B2, Codex P2 on #304)
Every wizard write goes through Panel, which clips to the panel and saturates its height arithmetic, so no step panics on a small terminal. The bottom row truncates in cells, so a wrapped message with a multibyte character is drawn whole. A scrolling list's range is named on its header row, where no item can cover it. Tests: a multibyte message at every width, wrap bytes vs cells, a no-panic sweep of every step at 20-100 x 3-20, the first item filling the list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
+20
-4
@@ -569,10 +569,14 @@ one-line message therefore draws exactly as before, which is why the pinned
|
||||
frames (`every_step_draws_what_it_drew_before`,
|
||||
`the_formula_step_draws_its_transient_state`) did not move.
|
||||
|
||||
**Lists scroll by item, and say what they hide.** `draw_scrolling` draws the
|
||||
items from `WizardCache::scroll` on, each one wrapped whole. It writes a
|
||||
`▲ n more above` or `▼ n more below` row instead of cutting an item in half.
|
||||
`ImportWizard::scroll` clamps to `len - 1`, so the last item can reach the top
|
||||
**Lists scroll by item, and the header says what is shown.** `Panel::scrolling`
|
||||
draws the items from `WizardCache::scroll` on, each one wrapped whole. The
|
||||
list's own header row reads `Colliding records 3–9 of 14 (PgUp/PgDn):` whenever
|
||||
some items are off screen. A first version put "more above" and "more below"
|
||||
markers inside the list's rows. When the first item filled the list exactly,
|
||||
the marker landed on the hint row and was drawn over (Codex, PR #304). The
|
||||
header row belongs to no item, so no item can cover it, and no item loses a line
|
||||
to make room for a marker. `ImportWizard::scroll` clamps to `len - 1`, so the last item can reach the top
|
||||
and the list can never scroll away. It is by item, not by line, because the
|
||||
wizard state cannot know the panel width that line-level clamping needs. The
|
||||
residual is honest. A **single** item taller than the whole list area, roughly
|
||||
@@ -580,5 +584,17 @@ residual is honest. A **single** item taller than the whole list area, roughly
|
||||
wizard warning is that long today: a collision tuple is bounded by twelve
|
||||
categories plus labels, but a label value is not bounded.
|
||||
|
||||
**Every write is clipped to the panel.** The widget draws through `Panel`,
|
||||
whose `put` writes only inside the panel's inner rectangle, and its height
|
||||
arithmetic saturates. Before this change, the duplicates step wrote at an
|
||||
unbounded row and ratatui panicked at 80×10, and four older steps panicked on
|
||||
`u16` underflow at heights of 3 to 5 (review B2 on PR #304). The bottom row's
|
||||
`set_bottom_line` now truncates in cells through `ui::text::truncate`. It had
|
||||
used the widget's byte-measured `truncate`, so a wrapped line holding a `←`
|
||||
was cut one character early, with `…`, although it fit (review B1). The local
|
||||
byte `truncate` still draws field names and labels. It is byte-identical on
|
||||
ASCII, which keeps every pinned frame, and those rows are labels rather than
|
||||
messages.
|
||||
|
||||
Other TUI surfaces still truncate text a user needs. They are out of this
|
||||
ticket's scope and reported in its hand-back rather than fixed here.
|
||||
|
||||
Reference in New Issue
Block a user