fix(tui): paste text when the terminal forwards Ctrl+V as a key event - #2
Open
NormalDudeBro wants to merge 6 commits into
Open
fix(tui): paste text when the terminal forwards Ctrl+V as a key event#2NormalDudeBro wants to merge 6 commits into
NormalDudeBro wants to merge 6 commits into
Conversation
… input_paste keydown branch only handled images; on key-forwarding terminals (e.g. WT 1.25+ with kitty active) Ctrl+V never emits a bracketed paste, so text was dropped entirely. Insert clipboard text directly with CRLF normalization; terminals that paste natively never deliver the keydown, so no double-insert.
NormalDudeBro
marked this pull request as draft
August 7, 2026 03:07
The prompt's input_paste keydown branch (added for key-forwarding terminals like Windows Terminal 1.25+ with the kitty keyboard protocol active) inserted raw clipboard text directly, bypassing the bracketed-paste pipeline: file paths were not turned into attachments, large text skipped the paste summary, and the layout render flush was missing. Extract handlePastedText() from the onPaste handler and call it from both paste signals so behavior is identical regardless of which signal the terminal delivers. Add testRender-based regression tests covering kitty-forwarded Ctrl+V: text inserts without double-insert, multi-line text renders, empty clipboard is a no-op, plain keys are unaffected.
NormalDudeBro
force-pushed
the
fix/ctrl-v-paste
branch
from
August 7, 2026 03:33
7a5ac76 to
b6564c7
Compare
NormalDudeBro
marked this pull request as ready for review
August 7, 2026 03:45
The prompt.paste command registered keybind input_paste (ctrl+v), and the command dialog's global keypress listener runs before the focused renderable handlers — on a match it calls preventDefault(), which skips the textarea's onKeyDown entirely. On terminals that forward raw 0x16 (WT 1.25+ with kitty active) Ctrl+V therefore never reached the paste branch. Removing the keybind lets Ctrl+V flow to the textarea; the command stays triggerable via command.trigger('prompt.paste') for the image-only bracketed-paste fallback.
Tests: paste-ctrlv.test.tsx now simulates the command-dialog global listener (useKeyboard) alongside the textarea and asserts both configurations — a command claiming Ctrl+V shadows the paste, and with no command claiming it the forwarded Ctrl+V inserts the clipboard text.
…e compiled exe The compiled single-file exe bundles clipboardy's Windows implementation, which spawns its helper binary (clipboard_x86_64.exe) from a virtual in-bundle path (B:/~BUN/...) that cannot be executed, so every clipboard read fails at runtime there and Ctrl+V paste silently does nothing. Use the same PowerShell mechanism as the image probe and the write path; [Console]::Write avoids PowerShell's output formatting so the returned text is byte-exact.
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.
Problem
The TUI prompt's Ctrl+V paste silently does nothing on terminals that forward Ctrl+V to the app instead of pasting natively (e.g. Windows Terminal 1.25+ with the kitty keyboard protocol active). Two gaps combined:
input_pastekeydown handler was image-only - for a text clipboard it read the clipboard, found no image, and fell through, while the terminal-side bracketed paste never fires because the key was forwarded. Text pastes were dropped entirely.prompt.pastecommand registered theinput_pastekeybind, and the command dialog's global keypress listener runs before the focused textarea's handler. On a keybind match it callspreventDefault(), which skips the textarea'sonKeyDownentirely - so the very terminals this targets never delivered the keypress to the paste code.Fix
Three changes:
onPastehandler and the forwarded-Ctrl+Vinput_pastekeydown branch both callhandlePastedText(), so a forwarded Ctrl+V behaves identically to native bracketed paste - CRLF normalization, file/PDF/SVG paths become attachments, large text shows the[Pasted ~N lines]summary, and the layout flush runs.prompt.paste(drop itskeybind: "input_paste"): with the keybind registered, the command dialog's global listener intercepted every forwarded Ctrl+V andpreventDefault()ed before the textarea'sonKeyDownran. With it removed, Ctrl+V flows straight to the textarea's paste branch. The command stays reachable viacommand.trigger("prompt.paste")for the image-only bracketed-paste fallback.clipboard.ts(see below).Double-insert is not possible by construction: terminals that paste natively never deliver the Ctrl+V keydown, so the two paths are mutually exclusive.
Windows clipboard read in the compiled exe (
clipboard.ts)The forwarding fix exposed a second bug that only surfaces in the shipped binary.
clipboardy@4.0.0's Windows implementation spawns a helper binary (clipboard_x86_64.exe) via__dirname; the single-filebun --compilebundle embeds that helper at a virtual in-bundle path (B:\~BUN\fallbacks\windows\clipboard_x86_64.exe) that cannot be executed ("The system cannot find the drive specified"). Every clipboard read therefore failed at runtime in the compiled exe and Ctrl+V silently did nothing, whilebun run devworked because the helper exists on disk innode_modules.clipboard.tsnow reads win32 text via PowerShell before the clipboardy fallback - the same mechanism the code already uses for the image probe and the write path (Add-Type -AssemblyName System.Windows.Forms; [Console]::OutputEncoding = UTF8; [Console]::Write([System.Windows.Forms.Clipboard]::GetText())).[Console]::Writereturns byte-exact text (verified for multi-line content, unlikeGet-Clipboard -Raw, which appends a trailing\r\n); an empty clipboard falls through to the existing clipboardy/prompt-hint fallback. Linux/macOS paths are untouched.Unchanged behavior
Tests
packages/opencode/test/cli/cmd/tui/paste-ctrlv.test.tsx- 6 cases: forwarded Ctrl+V inserts text without double-insert, multi-line text renders, empty clipboard is a no-op, plain keys are unaffected, plus two shadowing regressions - a command claiming the Ctrl+V keybind shadows the textarea paste (listener matched, nothing inserted), and with no command claiming it the forwarded Ctrl+V inserts the clipboard text.The clipboard read was additionally verified at the binary level: a probe compiled with the real build conditions (single-file, Windows x64) fails on the pre-fix clipboardy path and returns the clipboard text byte-exact with the PowerShell read, and the rebuilt exe pastes Ctrl+V end-to-end.
bun run typecheck(all 13 workspace packages) passes./connectdialogs (latest commit80e6610f2)The provider connection flow used separate shared dialog inputs rather than the main prompt textarea, so the prompt-level Ctrl+V fix did not cover them. On terminals that forward Ctrl+V, paste still did nothing in both places users need it most:
DialogSelect)DialogPrompt)Both shared dialogs now recognize the configured
input_pastekeybind in their existing keyboard listeners, prevent the raw key event from reaching the input, and insert clipboard text throughClipboard.pasteText(). The helper accepts text MIME types only, normalizes CRLF/CR newlines, and reuses the existing Windows PowerShell read path in compiled binaries. Image handling and the main prompt paste pipeline are unchanged.Additional verification
clipboard-paste.test.ts: text insertion/newline normalization plus image, empty, and missing clipboard no-ops.dialog-paste-ctrlv.test.tsx: a kitty-forwarded Ctrl+V reaches a dialog keyboard listener and inserts into its focused input.bun typecheck: passed in debug and production checkouts.anthropicinto the/connectprovider search and filtered the list correctly.