Skip to content

feat(composer): mouse + keyboard text selection with copy/cut#1726

Closed
imkingjh999 wants to merge 7 commits into
Hmbown:mainfrom
imkingjh999:feature/composer-text-selection
Closed

feat(composer): mouse + keyboard text selection with copy/cut#1726
imkingjh999 wants to merge 7 commits into
Hmbown:mainfrom
imkingjh999:feature/composer-text-selection

Conversation

@imkingjh999
Copy link
Copy Markdown
Contributor

@imkingjh999 imkingjh999 commented May 17, 2026

Summary

  • Add mouse drag selection in the composer input box
  • Add Shift+Left/Right keyboard text selection
  • Ctrl+C copies selected text; Ctrl+X cuts (or toggles mode if no selection)
  • Ctrl/Cmd+Alt+Left/Right jumps by word (on macOS: Ctrl+Cmd+Left/Right)
  • Selected text highlighted with theme selection_bg color
  • Mouse coordinate mapping accounts for wrapping, scroll offset, and padding

Platform differences

  • macOS: Ctrl+Left/Right intercepted by Mission Control; use Ctrl+Cmd+Left/Right for word jump. Cmd+C intercepted by terminal; use Ctrl+C for copy.
  • Windows: Ctrl+Left/Right reaches the app directly for word jump. Ctrl+C is copy (not interrupt); interrupt uses Ctrl+Break.
  • Linux: Ctrl+Left/Right works for word jump. Alt+Left/Right works if terminal doesn't consume it for window management.

Test plan

  • Mouse drag selects text in composer
  • Shift+Left/Right extends selection
  • Ctrl+C copies selection to clipboard
  • Ctrl+X cuts selection (copies + deletes)
  • Ctrl+X without selection toggles Plan/Agent mode (unchanged)
  • Ctrl/Cmd+Alt+Left/Right moves by word without affecting selection
  • On macOS: Ctrl+Cmd+Left/Right for word jump (Ctrl+Left intercepted by Mission Control)
  • Plain Left/Right clears selection and moves cursor
  • Selection survives text wrapping and scrolling

Mouse: click to position cursor, drag to select text.
Ctrl+C copies composer selection. Ctrl+X cuts when selection
exists, toggles Plan/Agent mode otherwise.
Add keyboard selection with Shift+arrow keys. Plain arrows clear
selection, Ctrl/Alt arrows move by word without affecting selection.
Also gitignore docs/superpowers/ and .serena/.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements keyboard and mouse text selection for the composer input box. Key changes include the addition of a selection anchor to the state, updating editing methods to handle selected ranges, and implementing mouse click-and-drag selection logic. The reviewer identified a logic error in how character ranges are aligned when the composer is scrolled and pointed out significant layout logic duplication that should be refactored. Additionally, feedback was provided to source selection colors from the active theme and to ensure the composer selection is automatically copied to the clipboard on mouse release for consistency with the rest of the application.

Comment thread crates/tui/src/tui/widgets/mod.rs Outdated
Comment thread crates/tui/src/tui/mouse_ui.rs
Comment thread crates/tui/src/tui/ui.rs
Comment thread crates/tui/src/tui/widgets/mod.rs Outdated
- Remove needless borrows flagged by clippy
- Auto-copy selection on mouse release (consistent with transcript)
- Use theme selection_bg instead of hardcoded color
Covered by .gitignore, should not be in the PR.
@imkingjh999
Copy link
Copy Markdown
Contributor Author

@gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces text selection and mouse interaction support for the composer input field, including coordinate mapping for wrapped/scrolled text and support for standard selection shortcuts like Shift+Arrows, Copy, and Cut. Feedback focuses on improving performance and usability: the reviewer recommends removing the automatic 'copy-on-release' behavior to prevent premature clearing of selections, and suggests optimizations to reduce redundant text wrapping and unnecessary memory allocations during the render pass, particularly for large inputs.

Comment thread crates/tui/src/tui/mouse_ui.rs
Comment thread crates/tui/src/tui/ui.rs
Comment thread crates/tui/src/tui/widgets/mod.rs
Comment thread crates/tui/src/tui/widgets/mod.rs
- Revert auto-copy on mouse release (preserves selection for cut/delete)
- Use actual scroll_offset in visible_line_char_ranges instead of inferring
- Use &str slices in line_spans_with_selection to avoid String allocations
@imkingjh999
Copy link
Copy Markdown
Contributor Author

@gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements text selection within the TUI composer, enabling users to select, copy, cut, and delete text using both mouse interactions and keyboard shortcuts (Shift+Arrow). Key changes include adding selection state to the composer, implementing mouse-to-character coordinate mapping that accounts for text wrapping and scrolling, and updating input handlers to respect active selections. Reviewers identified several opportunities to improve efficiency and maintainability by reducing redundant layout calculations and refactoring duplicated wrapping logic across the rendering and event-handling paths.

Comment thread crates/tui/src/tui/mouse_ui.rs
Comment thread crates/tui/src/tui/ui.rs
Comment thread crates/tui/src/tui/widgets/mod.rs
@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 23, 2026

This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current main and reopen. 鲸鱼兄弟们等你 🐋

@Hmbown Hmbown closed this May 23, 2026
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.

2 participants