If you spend some time in the macOS terminal, you probably use pbcopy. It's the native way to pipe terminal output directly to your clipboard.
Butttt, pbcopy is fundamentally broken for modern developer workflows.
Have you ever piped a token to your clipboard (echo "hunny-bunny-secret-society" | pbcopy) and it copies that new line character in the end and that annoyed you?
Or have you ever piped fancy colored texts ( like log errors ), and pasted a crap of invisible ANSI color codes?
I got so so annoyed by this, and built a replacement for it.
3 FUNDAMENTAL PROBLEMS WITH pbcopy
- New line character copy
- ANSI color code copy
- MOST IMPORTANT: a bad name (pbcopy suckss)
Meet CopyCopy (cpcp for short).
What makes cpcp better?
I built cpcp with a "Do What I Mean" philosophy.
1. It cleans your text automatically
By default, cpcp strips trailing whitespaces, newlines, and ANSI escape codes.
# Old way: Pastes "password123\n"
echo "password123" | pbcopy
# New way: Pastes exactly "password123"
echo "password123" | cpcp
(Need the raw output? Just pass the -r or --raw flag).
2. Smart File vs. Text Detection
If you pass an argument to pbcopy, it just copies the literal string. cpcp checks if the string is a valid file path first.
# Copies the text contents of the file
cpcp notes.txt
# Copies the actual image asset to your clipboard
cpcp screenshot.png
You can run cpcp never_gona_give_you_up.png and immediately hit Cmd+V in Figma, Slack, or where ever you want .
3. Human Feedback (but Script Safe)
pbcopy is dead silent. You never actually know if it worked until you paste.
cpcp detects whether stderr is connected to a human interactive terminal (TTY). If you're a human, it prints a subtle success message: β Copied 42 characters. If you are piping it inside a bash script, it stays dead silent so it doesn't corrupt your logs.
The Technical Challenge: The Sandbox Trap
Building this in Swift surfaced a really interesting quirk about the macOS clipboard and modern app sandboxing.
When I first built the image copy feature, I just wrote the file's URL to the NSPasteboard.
pb.writeObjects([url as NSURL])
This worked perfectly if I pasted into Finder (it moved the file). But if I pasted into Slack or Google Chrome, absolutely nothing happened.
Why? Because modern web browsers and chat apps run in strict security sandboxes. They are intentionally blocked from reading arbitrary local file:// paths off your clipboard. They expect raw image data (like public.png).
The Fix: I had to utilize "Multiple Representations." A single item on the macOS clipboard can hold several formats at once. I used NSWorkspace to dynamically detect the file type, and attached both the file URL and the raw binary data to a custom NSPasteboardItem:
let item = NSPasteboardItem()
// 1. For Finder (File Reference)
item.setString(url.absoluteString, forType: .fileURL)
// 2. For Sandboxed Apps (Raw Asset Data)
if let typeString = try? NSWorkspace.shared.type(ofFile: url.path),
let fileData = try? Data(contentsOf: url) {
let pasteboardType = NSPasteboard.PasteboardType(typeString)
item.setData(fileData, forType: pasteboardType)
}
pb.writeObjects([item])
Now, Finder consumes the URL representation, and Slack consumes the raw data representation. Best of both worlds!
Try it out (and a quick favor! π)
You can install cpcp right now via Homebrew:
brew tap vansh-j/cpcp
brew trust vansh-j/cpcp
brew install cpcp
I have a goal: I want to get cpcp merged into the official homebrew-core repository so nobody has to use those tap or trust commands ever again.
However, Homebrew Core requires a repository to have at least 75 GitHub Stars β.
If you find this utility useful, I would massively appreciate a star on the GitHub repo β to help me hit that milestone!
Let me know what you think, or if you have any feature requests, drop them in the comments!
Top comments (0)