fix: land the selection-padding highlight on the dragged cells - #415
Open
Sma1lboy wants to merge 1 commit into
Open
fix: land the selection-padding highlight on the dragged cells#415Sma1lboy wants to merge 1 commit into
Sma1lboy wants to merge 1 commit into
Conversation
A terminal selection anchored in the blank space right of a short line painted its inverse-video padding starting at the line's text width, not at the drag's start column, so the highlight sat too far left over cells the user never selected. Emit the gap before the span as plain spaces and the inverse block at the real start; the copied text was already correct.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Claude finished @Sma1lboy's task in 3m 5s —— View job Verdict: correct, minimal fix with a valid regression test — one house-rule attribution cleanup needed before merge.I traced Blocking
Should-fixNone — the fix itself, its scope, and its test coverage are sound. Nits
Other checks (all clean)
|
Sma1lboy
added a commit
that referenced
this pull request
Aug 27, 2026
…415 and #373 (#588) * fix(terminal): control chars are zero cells and nothing re-floors charWidth Fold PRs #500 and #384 into one change: charWidth now treats C0/DEL/C1 controls as non-printing (zero cells), and terminal-render drops its three charWidth(...) || 1 floors so zero-width marks fold onto their base cell. Landed together because each PR's safety argument depended on the other half's absence — the merged invariant (charWidth alone decides cell math, no consumer re-floors it) is pinned by a test that fails under either half alone. * fix(terminal): start the padding-selection highlight where the drag began A drag anchored in the blank padding right of a short trimmed row painted its inverse block from the row's painted width instead of from the anchor column — display only; the extracted text was already correct. Emit the gap as plain spaces before the inverse block. Re-lands PR #415 on current main. * fix(web): truncate tailPath by code point, not UTF-16 unit A cut landing mid-surrogate-pair bisected an emoji / astral char and the dashboard rendered a replacement glyph. Mirror the TUI's truncateStart (kobe-web can't import it — its only workspace dep is the daemon package), so the seam never splits a character and code-point-count budgets stop clipping paths that already fit. Re-lands PR #373 on current main.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Direction
Bugs / correctness — a self-found rendering bug in the embedded terminal's grid selection, surfaced by a review pass over the pure/near-pure logic modules. (Open issues #362/#307/#259 were either awaiting an owner design decision or too broad for one tightly-scoped slice; this is a smaller, fully-verifiable fix.)
Problem
In
terminal-selection.ts,overlayRowSpanpaints a selection's inverse-video highlight over a row. Snapshot rows are trimmed, not grid-padded (xtermLineToChunksdrops trailing blank cells), while the mouse column is clamped to the grid width — so a drag can anchor in the blank padding to the right of a short line, giving a span whose start columnfromis greater than the row's painted widthcol.The trailing-padding branch computed the highlight width as
to - Math.max(col, from)but appended it immediately after the painted content (at visual columncol). Whenfrom > col, the block rendered at[col, col + (to - from))instead of the intended[from, to)— the highlight was shifted left onto cells the user never dragged over, the gap[col, from)was wrongly inverted, and the row came out too short.Concrete case (grid width 8, row
"ab", select cols 5–7): expected inverse on cols 5/6/7 with cols 2–4 left plain; actual output inverted cols 2/3/4 and produced a 5-cell row. The copied text was already correct (extractSelectionslices the trimmed text independently) — only the on-screen highlight was misplaced.Fix
When the span starts past the painted cells, emit the
from - colgap as plain spaces first, then the inverse block sizedto - Math.max(col, from). Whenfrom <= colthe gap is zero and the inverse block fills[col, to)exactly as before, so the common case is byte-identical.Verification
"ab "with the highlight on cols 2–4.bun test test/tui/terminal-selection.test.ts→ 13/13 pass.bun run lintandbun run typecheck→ both green.test/tui/suite: clean tree 842 pass / 43 fail vs. this branch 843 pass / 43 fail — exactly the one new passing test and zero new failures. (The 43 pre-existing failures are unrelated environment issues in the CI-style checkout — readonlyprocess.platform/Bun-global reassignment in bun's test runner.)Follow-ups deferred
engine/foreground.tscustom-engine gate matchesbasename(argv0)againstextraBinwithout thebinaryName()normalization the builtin path uses (could false-negative onaider.exe), andhandlers-inspect.tsfilters sessions by barestartsWith(taskId)rather than`${taskId}::`— both are lower-confidence and left for a separate, scoped change.Generated by Claude Code