Skip to content

fix(terminal): paste multiline as LF in bracketed paste (PowerShell whitespace)#84

Merged
openwong2kim merged 2 commits into
mainfrom
fix/terminal-paste-multiline-newline
May 30, 2026
Merged

fix(terminal): paste multiline as LF in bracketed paste (PowerShell whitespace)#84
openwong2kim merged 2 commits into
mainfrom
fix/terminal-paste-multiline-newline

Conversation

@openwong2kim
Copy link
Copy Markdown
Owner

Summary

Fixes the multiline-paste-whitespace bug in PowerShell panes. Two commits:

  • Paste fix (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.
  • Docs (README.md): drop the removed Ctrl+Up/Down scroll-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. 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).

Fix

  • 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 to 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.

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.
  • Full suite: 2057 pass, tsc --noEmit clean.
  • Dynamic repro (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 in plans/paste-newline-fix.md.
  • GUI dogfood: confirmed by maintainer -- multiline right-click paste into a PowerShell pane no longer injects whitespace.

Test plan

  • clipboardChunk 35 tests pass
  • Full vitest suite 2057 pass
  • tsc --noEmit clean
  • GUI dogfood: multiline paste into PowerShell pane

🤖 Generated with Claude Code

iamwongeeeee and others added 2 commits May 30, 2026 22:09
…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 openwong2kim merged commit dbc8c6b into main May 30, 2026
4 checks passed
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>
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