fix(terminal): paste multiline as LF in bracketed paste (PowerShell whitespace)#84
Merged
Merged
Conversation
…ll whitespace) Right-click / Ctrl+V paste of a multiline command into a PowerShell pane injected stray whitespace and split the command line-by-line. Root cause: normalizePasteText collapsed every newline to a lone CR, but inside a bracketed-paste body PSReadLine treats CR as Enter and misplaces the cursor (PSReadLine #3939, #417 -- both recommend LF as the in-body separator). - normalizePasteText(text, bracketed): LF when bracketed (the body is inserted, not executed), CR otherwise (each line is an Enter). Non-bracketed path unchanged. - pastePtyChunked sanitizes a raw ESC in the bracketed body to U+241B so a pasted close-marker cannot be forged and run trailing bytes as a command (paste injection). - chunkOnDataIfNeeded is covered automatically (it delegates to pastePtyChunked), so all four paste paths (Ctrl+V, Ctrl+Shift+V, right-click, onData) are fixed at once. Intentionally diverges from xterm.js (which normalizes to CR in both modes); wmux bypasses xterm's paste pipeline and owns this choice. Verified against real pwsh 7.6 / PSReadLine 2.4.5: CR splits the command, LF buffers it as one multiline command. clipboardChunk 35 tests (16 new) + full suite 2057 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Ctrl+Up/Down bookmark-jump handler was removed in an earlier change; Ctrl+M marking and the gutter indicators still work. The README kept advertising the jump, so a user following it would hit a dead shortcut. Drop the jump mention from both the feature list and the shortcuts summary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
openwong2kim
pushed a commit
that referenced
this pull request
May 30, 2026
…iline-paste fix, stability batch Bundles #81 (tmux-style Quit=detach, recovered-session reattach fix, Ctrl+Shift+Arrow pane nav, completion blink, RAM RSS, token-chip removal, WebGL LRU pool) and #84 (multiline paste LF + paste-injection guard) -- everything merged since v2.15.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes the multiline-paste-whitespace bug in PowerShell panes. Two commits:
clipboardChunk.ts): the bracketed-paste body now uses LF as the in-body line separator instead of a lone CR, plus ESC sanitization to block paste-injection.README.md): drop the removedCtrl+Up/Downscroll-bookmark jump shortcut.Root cause
Right-click / Ctrl+V paste of a multiline command into a PowerShell pane injected stray whitespace and split the command line-by-line.
normalizePasteTextcollapsed every newline to a lone CR, but inside a bracketed-paste body PSReadLine treats CR as Enter and misplaces the cursor (PSReadLine #3939, #417 -- both recommend LF as the in-body separator).Fix
normalizePasteText(text, bracketed): LF when bracketed (the body is inserted, not executed), CR otherwise (each line is an Enter). Non-bracketed path unchanged.pastePtyChunkedsanitizes a raw ESC in the bracketed body to U+241B so a pasted close marker cannot be forged to run trailing bytes as a command (paste injection).chunkOnDataIfNeededis covered automatically (it delegates topastePtyChunked), so all four paste paths (Ctrl+V, Ctrl+Shift+V, right-click, onData) are fixed at once.Test Coverage
clipboardChunk.test.ts: +16 tests (bracketed to LF separators, ESC-injection guard, non-bracketed CR unchanged, empty/edge). 35 total in the file.tsc --noEmitclean.scripts/paste-repro.cjs, real pwsh 7.6 / PSReadLine 2.4.5): a CR body splits the command, an LF body buffers it as one multiline command.Review
/plan-eng-review: 2 decisions locked (separator policy = bracketed->LF; ESC sanitize folded in). Design notes inplans/paste-newline-fix.md.Test plan
🤖 Generated with Claude Code