Closed louib closed 5 years ago
The reason for this more philosophical than technical. The default conventions are different between the "Unix commands" and "GUI clipboard" worlds, and wl-clipboard has to bridge between them.
In Unix commands, the convention is that everything always ends with a \n
, including command output. For example, if you run echo "hello"
, it does actually call write("hello\n")
, because that's the convention, to always end your output with a newline. And echo
has an -n
option to turn this off too, if you know what you're doing. Many Unix programs treat newline as a line separator rather than as a character in its own right. For example, if you use grep '^$'
, you're asking it to look for "empty" lines, not lines containing just a '\n'
character.
In the GUI clipboard world, the convention is for clipboard to contain the exact thing you want to copy, without an extra newline at the end. For example, if I select this word hello and press Ctrl-C, my clipboard will contain hello
, not hello\n
. If your selection happens to contain a newline character, it is copied, cut and pasted just like other characters.
wl-clipboard exists between these worlds, and it tries to do its best to be a good citizen of both. If you copy hello and then wl-paste
it, wl-clipboard will append a \n
, just like echo
, giving you the expected output, and just like echo
it has the -n
option to override this behavior (and it will also automatically not do this with binary data and in watch mode). If you wl-copy hello
, then it, unlike echo
, copies "hello"
sans the '\n'
to the clipboard, so that you get the expected result when you paste into your text editor.
But if you're giving a file as an input to wl-copy
(think wl-copy < war-and-peace.txt
), it won't, by default, modify it, and will copy the exact bytes to the clipboard as is. Still, in many cases the file may actually be an output of a Unix command and you'd like it not to end with a newline. You can either ask that command not to add a newline — so, in your example, echo -n hello | wl-copy
, or explicitly ask wl-copy
to trim it (wl-copy -n
).
To summarize, there is a difference in conventions, and wl-clipboard goes to great lengths to do the most intuitive thing most of the time. But there are some scenarios that still uncover the issue — thankfully, copying using command line and then pasting back using command line is a pretty rare thing to do (outside testing wl-clipboard behavior, of course).
And here's a short guide with different versions of your example:
echo hello | wl-copy && wl-paste
— 2 newlines (one from echo
, one from wl-paste
)echo -n hello | wl-copy && wl-paste
— 1 newline (from wl-paste
)echo hello | wl-copy -n && wl-paste
— 1 newline (from wl-paste
; the one echo
produced was trimmed by wl-copy
)wl-copy hello | wl-paste
— 1 newline (from wl-paste
)echo hello | wl-copy && wl-paste -n
— 1 newline (from echo
)echo -n hello | wl-copy && wl-paste -n
— no newlinesecho hello | wl-copy -n && wl-paste -n
— no newlines (the one echo
produced was trimmed by wl-copy
)wl-copy hello && wl-paste -n
— no newlines@bugaevc thanks for the explanation!
I'm not convinced about the newline handling on this one:
Why is there a second newline appended? From the manpage:
So I guess I could be using the
-n
option, I just don't understand why that would not be the default in that case.Thanks!!