Question

In one of my Linux machines, I create a long line and pipe it to gnu less like this:

seq -w 1 999 | xargs echo | less

If I select the text that appears from gnu less (version 394), and copy+paste it somewhere else, the long line is broken down into multiple lines, each as long as the width of the terminal, which is not what I expected.

If I do the same in a different Linux box (less version 444), I can select from the gnu less buffer and copy+paste it somewhere else as one single long line, which is the desired behaviour. See image:

enter image description here

Effect of pasting into emacs, underired effect first, desired effect below:

enter image description here

In both linux boxes, if I use cat instead of less and select from the output in the terminal, I can also copy+paste everything in one single line:

seq -w 1 999 | xargs echo > /tmp/f
cat /tmp/f

In contrast, in both linux boxes, the more command behaves the other way around, also breaking down the long line into multiple lines when selecting for copy+pasting:

seq -w 1 999 | xargs echo > /tmp/f
more /tmp/f

Any ideas what might be going on? How can I copy+paste from a gnu less buffer with the same consistent behaviour I see when I do cat?

Was it helpful?

Solution

I compiled a newer version of less, and now it behaves as expected.

OTHER TIPS

Let me answer the "what is going on" part of your question without addressing the "how to fix it" part. The major difference between cat and less or more from your terminal point of view is the mode of operation. When you cat something, the terminal sees the actual characters and when it reaches the end of the line it is the responsibility of the terminal emulator to cause a line break. Modern terminal emulators remember whether they did such a line break for each line and when you copy text, the line break is not included in the copy buffer.

Now less and more use your terminal in an entirely different way (with ncurses). These tools are aware of the width of the terminal and will not cause a line break by overflowing the line. They will issue a line break themselves. Your terminal emulator cannot distinguish such a line break from a "meaningful" line break, so when you copy text these line breaks are included in the copy buffer.

You can actually ask more to not include these line breaks using the -f option, but for less no corresponding option exists mostly due to the fact that you can scroll back.

less has a -S option that tells it to break long lines. It's not on by default.

Luckily, most less flags can be changed even while it runs. Just press -S to toggle long-line-mode / broken-line-mode

this can be done with vim:

  1. pipe text to vim:

    seq -w 1 999 | xargs echo | vim -

  2. setup wrapping (http://vim.wikia.com/wiki/Word_wrap_without_line_breaks):

    :set wrap
    :set linebreak
    :set nolist " list disables linebreak
    :set nonumber " hide line numbers to don't copy them

  3. copy and paste!

afaik, the only drawback is that vim opens big files (tens of megabytes) way slower than less. though this can be fixed, see http://vim.wikia.com/wiki/Faster_loading_of_large_files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top