Skip to content

Fix multi-line paste appearing in reverse order in PowerShell#131

Closed
ToxMox wants to merge 1 commit into
psmux:masterfrom
ToxMox:fixes/paste-line-endings
Closed

Fix multi-line paste appearing in reverse order in PowerShell#131
ToxMox wants to merge 1 commit into
psmux:masterfrom
ToxMox:fixes/paste-line-endings

Conversation

@ToxMox

@ToxMox ToxMox commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Multi-line paste into PowerShell/PSReadLine displays lines in reverse order
  • Clipboard text arrives with LF (\n) or CRLF (\r\n), but ConPTY's input parser expects CR (\r) for Enter
  • Bare LF is misinterpreted by PSReadLine, causing reverse line insertion
  • Fix: normalize line endings to CR in write_paste_chunked before writing to ConPTY

Test plan

  • Paste multi-line text into PowerShell — lines should appear in correct order
  • Paste multi-line text into Claude Code — should still work correctly
  • Paste into nvim/helix — verify no regressions with bracket paste

Normalize line endings to CR (\r) in write_paste_chunked before writing
to ConPTY's input pipe.  Clipboard text arrives with LF (\n) or CRLF
(\r\n), but ConPTY expects CR for Enter.  Bare LF is misinterpreted by
PSReadLine, causing multi-line pastes to display in reverse order.

CRLF → CR, LF → CR.  Existing CR bytes are preserved as-is.
psmux pushed a commit that referenced this pull request Mar 18, 2026
…ncoding (PR #132)

PR #131 - Multi-line paste reverse order in PowerShell:
- Root cause: write_paste_chunked sends clipboard text with bare LF to PTY pipe.
  ConPTY expects CR for Enter; bare LF confuses PSReadLine, causing reversed order.
- Fix: Normalize line endings (LF->CR, CRLF->CR) in write_paste_chunked before
  writing to the PTY pipe.

PR #132 - Shift+Enter not working for VS Code terminal / Node.js apps:
- Root cause (client): VS Code xterm.js sends ESC+CR for Shift+Enter. ConPTY
  interprets ESC as Alt prefix, so crossterm misreports Alt+Enter.
- Root cause (server): CSI 13;2~ encoding is non-standard (code 13 not in VT
  function key table) and silently dropped by ConPTY.
- Fix (client): augment_enter_shift polls GetAsyncKeyState(VK_SHIFT) to detect
  physical Shift key and remaps crossterm's misreported Alt+Enter to Shift+Enter.
- Fix (server): encode_key_event and send_key_to_active send ESC+CR instead of
  CSI 13;mod~ for Shift/Alt+Enter on Windows. This matches VS Code xterm.js
  encoding and round-trips through ConPTY -> libuv correctly.
- Ctrl+Enter variants still use CSI encoding (unaffected by ConPTY).

Tests: 7 new unit tests covering paste normalization (LF, CRLF, mixed, bracketed)
and Shift/Alt+Enter ConPTY encoding. All 68 tests pass.
@psmux

psmux commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Hey @ToxMox, thanks for catching this — you nailed the root cause. Multi-line paste was indeed broken because write_paste_chunked was sending bare LF bytes straight through the PTY pipe, and ConPTY/PSReadLine expects CR for Enter. The clipboard normalization in
ead_from_system_clipboard() converts CRLF→LF, but that last LF→CR step for ConPTY input was completely missing.

I wrote targeted unit tests (LF-only, CRLF-only, mixed endings, and bracketed paste) — all of them failed against the current code, confirming the bug. After adding the normalization logic (same approach you proposed: CRLF→CR, LF→CR in write_paste_chunked), all tests pass and no regressions in the existing 62-test suite.

Fixed in abd5e25. I'm closing this PR since the fix is already on master, but really appreciate the diagnosis — it was spot-on.

@psmux

psmux commented Mar 19, 2026

Copy link
Copy Markdown
Owner

Let me know if you find it fixed in the latest commit. Thank you.

ohboyftw pushed a commit to ohboyftw/psmux that referenced this pull request Mar 19, 2026
Brings 17 upstream commits into ohboy-builds:
- fix: warm claim race condition (psmux#136)
- fix: client_prefix flag, window_zoomed_flag (psmux#125, psmux#126)
- fix: Shift+Enter/Ctrl+Enter modifiers, paste normalization (psmux#131, psmux#132)
- fix: backslash escape, 6 client-server bugs (psmux#118, psmux#123)
- fix: -f global option (psmux#119)
- fix: set-hook replace/remove, zoomed navigation wrap (psmux#133, psmux#134)
- fix: TERM env var mapping, hyphenated option leak (psmux#137)
- feat: bell/activity/silence monitoring, allow-rename, update-environment
- feat: vim-style bind-key C-hjkl pane navigation (psmux#130)
- feat: XDG plugin path support (psmux#135)
- feat: auto-generate changelog in release workflow
- refactor: move Rust tests to tests-rs/ directory
- refactor: rich test dashboard

Also applies ohboy-builds stashed changes:
- Remove claude-code-fix-tty (Claude Code now auto-detects $TMUX)
- Migrate env::set_var to safe crate::util::set_env wrappers (Rust 1.83)
- Selection clamp to pane boundaries in copy mode
- Fix clippy warnings in forked crates (vt100-psmux, portable-pty-psmux)
souhaiebtar pushed a commit to souhaiebtar/psmux that referenced this pull request Mar 20, 2026
…PTY encoding (PR psmux#132)

PR psmux#131 - Multi-line paste reverse order in PowerShell:
- Root cause: write_paste_chunked sends clipboard text with bare LF to PTY pipe.
  ConPTY expects CR for Enter; bare LF confuses PSReadLine, causing reversed order.
- Fix: Normalize line endings (LF->CR, CRLF->CR) in write_paste_chunked before
  writing to the PTY pipe.

PR psmux#132 - Shift+Enter not working for VS Code terminal / Node.js apps:
- Root cause (client): VS Code xterm.js sends ESC+CR for Shift+Enter. ConPTY
  interprets ESC as Alt prefix, so crossterm misreports Alt+Enter.
- Root cause (server): CSI 13;2~ encoding is non-standard (code 13 not in VT
  function key table) and silently dropped by ConPTY.
- Fix (client): augment_enter_shift polls GetAsyncKeyState(VK_SHIFT) to detect
  physical Shift key and remaps crossterm's misreported Alt+Enter to Shift+Enter.
- Fix (server): encode_key_event and send_key_to_active send ESC+CR instead of
  CSI 13;mod~ for Shift/Alt+Enter on Windows. This matches VS Code xterm.js
  encoding and round-trips through ConPTY -> libuv correctly.
- Ctrl+Enter variants still use CSI encoding (unaffected by ConPTY).

Tests: 7 new unit tests covering paste normalization (LF, CRLF, mixed, bracketed)
and Shift/Alt+Enter ConPTY encoding. All 68 tests pass.
@ToxMox ToxMox closed this Apr 1, 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