[BUG] Copy/paste from terminal has new lines instead of wrapping properly
Status Open
Reported on v2.1.27
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 15 comments · opened Jan 31, 2026
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Because Claude is a TUI, it dynamically renders physical \n unicode to mimic word-wrapping behavior. Can we please inject an invisible unicode character before or after the \n, so that we can use post-processing to fix the copy-paste?
It's incredibly painful right now when you're working in Claude, want to copy a command from Claude and paste into another terminal, and have to manually remove all the line breaks.
What Should Happen?
Inject a character we can parse for programmatically so that we can write scripts or programs to fix the copied text, outside of claude.
Error Messages/Logs
Steps to Reproduce
Copy text
See new lines
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.27
Platform
Anthropic API
Operating System
Other
Terminal/Shell
Other
Additional Information
_No response_
Showing cached comments. Read the full discussion on GitHub ↗
14 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Different issues, this is proposing a solution.
I am also running into this issue. It seems OpenCode handles this well and I'm curious how they do it.
I also am running into this issue +1
This is so annoying.
Can anybody fix it?
The issue is present in iTerm...
I feel like we need to build a new terminal, which would support tools like this nicely.
Or maybe CLI UI is not the best approach?
Root Cause Analysis
I traced the rendering pipeline through the bundled CLI and upstream dependencies:
wrapText()→wrap-ansi(text, maxWidth, { trim: false, hard: true })wrap-ansiinserts literal\ncharacters at wrap boundariesThe 2-space indent reported in related issues (#15199, #13378) comes from Ink's
<Box>padding —applyPaddingToText()prepends spaces to each line after wrapping.Proposed Fix: Let the Terminal Handle Soft Wrapping
The unicode marker idea from the OP would work as a stopgap, but the proper fix is don't application-wrap in the first place.
When you write a line longer than terminal width to stdout, the terminal soft-wraps it visually. The terminal knows it's a single logical line, so copy/paste works correctly — no extra newlines. This is how every other CLI tool works (
git log,man,curloutput, etc.).The fix would be in Ink's rendering pipeline:
Specifically, for
<Text>nodes inside full-width<Box>containers (which is most of Claude Code's markdown output), Ink could skip thewrapAnsi()call and let the terminal handle wrapping natively.This would need to be opt-in (a new
textWrap: 'terminal'style or similar) since Ink's Yoga layout engine needs accurate line counts for multi-component layouts. But for Claude Code's primary use case — streaming markdown into a full-width output area — terminal-native wrapping would work perfectly.Incremental Path
Quick win (Claude Code side): For the main assistant output
<Text>component, skipwrapAnsiand write unwrapped text. This fixes copy/paste for 90% of use cases (the main conversation output). Ink layout still works because the output area is full-terminal-width.Upstream (Ink): Add a
textWrap: 'native'option to<Text>that delegates wrapping to the terminal instead ofwrap-ansi. PR to vadimdemedes/ink.Fallback (if terminal-native doesn't work for the layout engine): Insert
U+200B(zero-width space) before each soft-wrap\nas the OP suggests. This at least enables external tools like claude-fix to reliably strip soft-wrap newlines.Related
This is the root cause behind #15199, #6827, #13378, #4686, #5097, and #859 (37+ upvotes). The community workaround tool claude-code-command-fix exists specifically because of this.
same issue in Ghostty on macOS, affects both prose and code blocks
No literal newlines should be added.
Special case of
git commit: we should default to writing a commit message to a file (and try hard to keep the individual command that is to be copy/pasted on a _single_ line).The issue is still present in 2.1.117.
This is a rather annoying problem. I have had this type of interaction in about every claude session:
Suggesting to build a whole new terminal is insane. Just render the output without newlines and take advantage of terminal auto wrapping.
I am running into this as well on Ghostty on MacOS.
+1 — adding a specific repro flavor that's a sustained productivity tax for power users.
Repro (macOS, Claude Code CLI, also reproduces inside cmux):
oauth2c https://... --client-id ... --client-secret ... --response-types code --grant-type authorization_code --auth-method client_secret_basic --scopes "openid profile email" --callback "http://localhost:9876/callback"(>100 chars).Cmd+C.--callbaon one line andck "..."on the next.Expected: pasted text is the logical line with no embedded
\n.Actual: linebreaks appear at the terminal column boundary, breaking the command.
Why it matters: Claude Code generates long
gh,curl,oauth2c,gcloud, andgit commit -m "$(cat <<EOF...)"commands constantly. Every one of them has to be manually un-wrapped before it can be executed. The friction adds up fast.Proof the underlying text is fine: asking Claude to pipe the same command through
printf '%s' '...' | pbcopyproduces a clipboard string with no embedded newlines and pastes cleanly. So the underlying string is unbroken — the corruption is purely in the copy-from-terminal-render path (Ink'swrap-ansiinserting literal\n, per @ajiblock's analysis above).Also reproduces inside cmux (a multiplexer/wrapper for Claude Code), which suggests the fix needs to land in Claude Code / Ink rather than any downstream terminal layer.
Severity framing: high-severity usability — not a crash, but a sustained tax on every long command. Subscribing for updates.
We need this mate!!!!
Use the
/copycommand.