Skip to content

Fix width-measurement starvation for right-aligned text - #43

Open
brainkim wants to merge 1 commit into
mainfrom
measurement-starvation
Open

Fix width-measurement starvation for right-aligned text#43
brainkim wants to merge 1 commit into
mainfrom
measurement-starvation

Conversation

@brainkim

Copy link
Copy Markdown
Member

Clusters near the right margin are never measured in place (pending-wrap poisons the arithmetic), and right-aligned RTL content puts its uncertain clusters — Arabic presentation forms — there every time. They deferred forever, stayed at table widths, and on terminals whose advances disagree (Terminal.app) the rtl example's box borders misaligned permanently.

Fix: a starved cluster rides a probe train on the next frame. The train hides in the first row the frame paints, at a column whose next four cells the row's own content covers, so the residue is overwritten in the same flush — nothing is visible. Starvation is detected the first time the guard defers a cluster that no query has ever carried (append-only set, one ride per cluster, O(1)); a quiet document is made to paint one row rather than clearing the screen (a full clear is archived into tmux scrollback). The margin guard itself is unchanged, and frames with nothing starved pay a single size check.

Tests: six new cases including the repro (right-aligned uncertain clusters on a narrow terminal learn a disagreeing advance and the layout stays corrected — fails without the fix) and a train-invisibility assertion; a tmux scenario runs the rtl example at 40 columns and checks the borders stay square with ~28 forms probed. Full suite after rebasing onto 0.1.3: node 1253, bun 1278, exit 0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01C8sSHf9EvBZroVnsXJbJSD

Right-aligned text paints the same clusters against the last column
every time: the margin guard turns them away, in-place measurement
never gets a readable answer, and on a terminal whose advances differ
from the tables the boxes around them stay a cell out for the life of
the session. The rtl example's Arabic cards are the case.

A cluster deferred by the guard that no query has ever carried is
starved. The next frame asks about it before it paints anything: a
probe train at the far left of the first row it is repainting, one
carriage return per cluster so no advance carries into the next, and
that row's own content lands on top of the residue in the same write.
The queue, the ledger and the per-probe deadline are the ones already
there; being probed anywhere is what takes a cluster out of the set,
which bounds the train to one ride per cluster.

A document still painting carries the train for nothing. Only one that
has gone quiet is made to paint, and then only its topmost row -- a
repaint identical to what the screen already shows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant