Conversation
Adds a copy handler that trims trailing whitespace from each line when copying text from the terminal. This matches the default behavior of iTerm2 and other popular terminal emulators. Fixes #1018
📝 WalkthroughWalkthroughAdded a new copy event handler to the terminal that automatically trims trailing whitespace from copied text while preserving line breaks. The handler is integrated into the terminal's lifecycle hooks with proper cleanup during unmount. Changes
Sequence DiagramsequenceDiagram
actor User
participant XTerm
participant CopyHandler
participant Clipboard
User->>XTerm: Initiates copy action
XTerm->>CopyHandler: Copy event fires
CopyHandler->>CopyHandler: Get selected text via xterm.getSelection()
CopyHandler->>CopyHandler: Trim whitespace from each line
CopyHandler->>Clipboard: setData("text/plain", trimmedText)
Clipboard-->>User: Cleaned text available
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts`:
- Around line 340-341: The current copy handler calls event.preventDefault()
unconditionally then uses event.clipboardData?.setData("text/plain",
trimmedText), which can silently fail if clipboardData is null; change the logic
in the copy handler so you only preventDefault when you have a successful path
to place text on the clipboard (e.g. check event.clipboardData exists before
calling event.preventDefault() and event.clipboardData.setData(...)), and add a
fallback that attempts navigator.clipboard.writeText(trimmedText) (with
try/catch) if event.clipboardData is absent; update references to
event.preventDefault, event.clipboardData?.setData and trimmedText in the
handler accordingly and surface/log errors if both methods fail.
| event.preventDefault(); | ||
| event.clipboardData?.setData("text/plain", trimmedText); |
There was a problem hiding this comment.
Potential silent copy failure if clipboardData is null.
When event.preventDefault() is called unconditionally on line 340, the default copy behavior is blocked. If clipboardData happens to be null (edge case in some browser/Electron contexts), line 341's optional chaining silently skips the write, leaving the user with an empty clipboard and no indication of failure.
Consider guarding the preventDefault() call or adding a fallback:
🛡️ Proposed fix
const handleCopy = (event: ClipboardEvent) => {
const selection = xterm.getSelection();
if (!selection) return;
+ if (!event.clipboardData) return;
// Trim trailing whitespace from each line while preserving intentional newlines
const trimmedText = selection
.split("\n")
.map((line) => line.trimEnd())
.join("\n");
event.preventDefault();
- event.clipboardData?.setData("text/plain", trimmedText);
+ event.clipboardData.setData("text/plain", trimmedText);
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| event.preventDefault(); | |
| event.clipboardData?.setData("text/plain", trimmedText); | |
| const handleCopy = (event: ClipboardEvent) => { | |
| const selection = xterm.getSelection(); | |
| if (!selection) return; | |
| if (!event.clipboardData) return; | |
| // Trim trailing whitespace from each line while preserving intentional newlines | |
| const trimmedText = selection | |
| .split("\n") | |
| .map((line) => line.trimEnd()) | |
| .join("\n"); | |
| event.preventDefault(); | |
| event.clipboardData.setData("text/plain", trimmedText); | |
| }; |
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts`
around lines 340 - 341, The current copy handler calls event.preventDefault()
unconditionally then uses event.clipboardData?.setData("text/plain",
trimmedText), which can silently fail if clipboardData is null; change the logic
in the copy handler so you only preventDefault when you have a successful path
to place text on the clipboard (e.g. check event.clipboardData exists before
calling event.preventDefault() and event.clipboardData.setData(...)), and add a
fallback that attempts navigator.clipboard.writeText(trimmedText) (with
try/catch) if event.clipboardData is absent; update references to
event.preventDefault, event.clipboardData?.setData and trimmedText in the
handler accordingly and surface/log errors if both methods fail.
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Summary
TrimWhitespaceOnCopydefaults totrue)Test plan
Fixes #1018
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.