Skip to content

fix(tui): make selection copy reliable and improve copy affordances#3535

Merged
dgageot merged 1 commit into
mainfrom
fix/tui-selection-copy-ux
Jul 8, 2026
Merged

fix(tui): make selection copy reliable and improve copy affordances#3535
dgageot merged 1 commit into
mainfrom
fix/tui-selection-copy-ux

Conversation

@Sayt-0

@Sayt-0 Sayt-0 commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Copying from the chat via cursor selection was unreliable (random one-word or one-line copies, trailing padding, UI glyphs in the clipboard), and the message copy button was a 1-cell target with no click feedback. This PR makes the selection copy path deterministic and improves the copy affordances.

Selection copy fixes

Cause Symptom Fix
Motion/release routed by vertical region; a drag ending over the editor never reached the messages component No copy, stale drag, late debounced copy wrote one word Motion and release forwarded to the chat whenever a selection drag is active (IsSelecting() plumbed messages -> chat page -> app)
Triple-click (often a misdetected quick retry) copied the line on press and dropped the drag One-line copies while dragging Triple-click anchors the line, drag extends it, copy on release or debounce
Double/triple-click on a blank line failed silently Dead drag, clipboard unchanged Falls back to a plain drag selection
Completed drags fed the multi-click counter Retries misdetected as double/triple clicks Click tracking reset after a drag; count cycles after triple
Per-line TrimSpace and no content filtering Lost code indentation; copied ⎘ copy, , [+] expand ... labels and padding lines TrimRight, common-prefix dedent, affordance-line filter, boundary blank trim
findClosestRuneIndex walked backwards past end-of-line Last character missing Columns beyond the line map one past the last rune

Drag lifecycle after the routing fix:

press (chat)       motion (anywhere)            release (anywhere)
  start/anchor  ->  IsSelecting() forwards to ->  finalize + copy
                    chat, selection extends

Copy affordances

  • becomes ⎘ copy on assistant messages and code blocks (7-cell click target instead of 1)
  • The clicked label flashes a same-width copied confirmation for 1.5s; view-time overlay, render caches untouched

Tests

  • New unit tests for selection extraction, anchored drags, click tracking, and the flash overlay
  • New tuitest Drag helper and e2e TestChat_DragSelectionCopiesAcrossRegions: drags from the response text and releases over the editor region; verified to fail without the routing fix
  • Full pkg/tui and e2e/tui suites and linters pass

Selection copy:
- Route mouse motion and release to the chat while a text-selection
  drag is active, so a drag that ends over the editor or status bar
  still extends and finalizes the selection instead of dropping it.
- Treat triple-click like double-click: anchor the line, let the drag
  extend it, and copy on release or via the debounce, instead of
  copying the line immediately on press and ignoring the drag.
- Fall back to a plain drag selection when a double or triple click
  lands on a blank line instead of leaving a dead drag.
- Reset multi-click tracking after a completed drag and cycle the
  click count after a triple-click, so quick selection retries are
  not misdetected as word or line selections.
- Preserve code indentation (dedent to the common prefix), trim the
  right-hand width padding, and drop UI affordance lines (copy, edit,
  retry labels, expand and collapse indicators) and boundary blank
  lines from copied text.
- Fix findClosestRuneIndex dropping the last character when the
  selection extends past the end of an unpadded line.

Copy affordances:
- Widen the copy labels from "⎘" to "⎘ copy" on assistant messages
  and code blocks for a larger click target.
- Flash a same-width "copied" confirmation in place of the clicked
  label for 1.5s.

Adds a tuitest Drag helper and an e2e test that releases the drag
over the editor region, which fails without the routing fix.
@Sayt-0 Sayt-0 requested a review from a team as a code owner July 8, 2026 12:38
@aheritier aheritier added area/tui For features/issues/fixes related to the TUI kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Jul 8, 2026
@dgageot dgageot merged commit 49584e6 into main Jul 8, 2026
14 checks passed
@dgageot dgageot deleted the fix/tui-selection-copy-ux branch July 8, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tui For features/issues/fixes related to the TUI kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants