fix(web): close a run at the line end and count columns correctly
Eight findings, each terminal case verified in a real terminal first: `\x1b[32mdone\rok\x1b[0m` then `plain` shows `okne` green and `plain` in the DEFAULT color. The replay returned the last written cell's state, so a reset landing after the final write vanished from both the text and the returned state — and every build tool writes exactly that shape, so the color leaked onto all later output. The replay now converges to the state the scan ended in, which is also what it hands to the next line. `abcd\b\x1b[1K|` shows ` |`: CSI 1K erases THROUGH the cursor column, and the loop stopped before it. The erase mode also reads only the first parameter now, since a terminal treats `1;2K` exactly as `1K`. `éx\rYZ` shows `YZ`: a combining mark takes no column, so it attaches to the cell already written instead of advancing the cursor and leaving the `x` standing. `中x\rA` shows `A x`: overwriting a wide character's lead cell leaves its spacer as a blank rather than closing the gap, which would shift everything after it one column left. The banner lost its span when the gutter became padding — a plain block child only reaches the content box, so the reserved column was painted in the body color and the card's top-left radius drawn in it. Invisible in the light theme, where banner and body share a token; visible in the dark one. The header now pulls back across the gutter and re-insets by the same amount. The replay trigger matches the same CSI shape the parser accepts, so a form like `\x1b[1;2K` can no longer skip its own erase, and `replayLine`'s JSDoc documents its new parameter and returned pair. Docs: four places still described the dot as sitting left of the card surface, which stopped being true when the gutter became the card's own padding, and two fixture comments still referenced the exit marker that was deliberately removed.
This commit is contained in:
@@ -30,9 +30,15 @@
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
/* No left padding: the card's gutter already insets this row, and the banner
|
||||
background still has to span the full surface. */
|
||||
padding: 9px 14px 9px 0;
|
||||
/* Pulled back across the card's gutter padding so the banner background and
|
||||
its top-left radius span the FULL surface, then re-inset by the same amount
|
||||
so the prompt text and the dot keep their positions. A plain block child
|
||||
only reaches the content box, which left the gutter column painted in the
|
||||
body color and drew the card's top-left corner in it — invisible in the
|
||||
light theme, where banner and body share a token, and visible in the dark
|
||||
one, where they do not. */
|
||||
margin-left: calc(-1 * var(--dsl-terminal-gutter));
|
||||
padding: 9px 14px 9px var(--dsl-terminal-gutter);
|
||||
background: var(--dsw-alias-markdown-code-block-banner);
|
||||
border-top-left-radius: var(--dsl-terminal-radius);
|
||||
border-top-right-radius: var(--dsl-terminal-radius);
|
||||
|
||||
Reference in New Issue
Block a user