4

I wanted to copy a public key from one machine to the other. I opened up vim and had two terminal buffers - one for each machine. In the terminal in which I had the first machine I went into normal mode and that automatically made the public key appear as if it is on multiple lines which is not what I wanted.

How can I copy a long line from a terminal buffer as it is?

edit: the suggested duplicate refers to just resizing the window which even if it works is still a limited solution.

5
  • 2
    Possible duplicate of Vim 8 terminal change width
    – filbranden
    Commented Aug 2, 2019 at 7:06
  • I looked into it but in my vim(8.0) there seems to be no such thing as a termwinsize. Also just setting term size gives out E474. I think the problem might be different. Even if I resize the window there might still be lines which are too long for the screen. Also the question basically uses :terminal almost as "read !command" while I open a terminal buffer which I use to ssh and move around. Then once I need to copy from the terminal and go into normal mode during that ssh session does the problem occur.
    – ivan
    Commented Aug 2, 2019 at 7:42
  • Maybe have a look here? vi.stackexchange.com/questions/84/… If you yank the line, it will be in the system clipboard and then you can paste it
    – ChatterOne
    Commented Aug 2, 2019 at 11:46
  • 1
    Why not ssh-copy-id or scp???
    – D. Ben Knoble
    Commented Aug 2, 2019 at 12:04
  • That's what I ended up doing. There are always workarounds. I would have preferred to have done it the other way though.
    – ivan
    Commented Aug 2, 2019 at 12:15

1 Answer 1

2

I'm assuming that by "terminal buffers" you mean the :terminal command. In theory you can just use the ++cols=1000 option or :set termsize (8.0)/set termwinsize (8.1) commands to set a wider terminal width, at the expense of having to scroll to read the whole line. In practice, this new feature seems rather buggy.

There are other options, however.

Copying Using the Terminal Program's Cut and Paste

TLDR: Avoid "visual" (curses-using) programs such as Vim or less when copying from a terminal; instead just cat or type the file in a terminal and use the terminal program's copy function.

The most common way of handling this is to use the terminal's ability to do cut and paste to the windowing system's clipboard. Select the text in one window using your mouse, choose "Copy" from the terminal application's menu or via hotkey, move the focus to the other window, put vim into insert mode, and choose "Paste" from that terminal application's menu or via a hotkey. Vim will see this text as being "typed in" from the keyboard; the terminal application is what's "typing" the characters.

When you do that sort of copy above, it's best to use a non-visual mode program to display the text. If you cat or type a file with lines that wrap, the terminal will see this as a long string of characters with a newline, and the terminal, though it will wrap the text (if configured to do so), will know that there is no LF, CR or similar between the last character on one row and the first character on the subsequent row; this will be reflected on what gets copied. On the other hand, programs like vim may not send the text to the terminal that way since they're concerned primarily with a nice visual display and it's safer to send a CR or cursor movement command when printing on a new line than to rely on the terminal's automatic wrapping; the terminal may see this as a newline when copying.

In particular, :terminal in Vim itself is doing exactly this kind of wrapping (turning a single output line into multiple lines as it wraps), which appears to be the problem you're experiencing.

Command-line Vim and the Windowing System's Clipboard

Another option is to use vim's interface to the windowing system's clipboard. This has several requirements:

  1. Your windowing system is X11 (Linux, *BSD, X11 server running under Windows, etc.).
  2. Any remote machine you're using has a connection to that X11 server (e.g., via ssh -X. (Local terminals need access to, but this is typically automatic via the DISPLAY environment variable.)
  3. You're using a version of vim with support for X11 communications (vim --version shows +X11, not -X11).

In these cases you can use vim on both sides, yanking into the "+ or "* buffer in one vim and pasting from that buffer in the other vim.

Actually, the command-line version of Vim for windows can have these capabilities too when run locally. The version I have, built for MSYS and run from bash in a mintty terminal, works well for this. I believe that this was installed along with various other Unix-y tools when I installed Git for Windows, but I'm sure that there are various sources for various builds of Vim to run under both MSYS or at regular Windows command lines.

3
  • 2
    Terminal buffer is what you get in vim8 when you do :terminal
    – D. Ben Knoble
    Commented Aug 3, 2019 at 12:27
  • I can't use the "+ or "* registers because that would mean I have to be in normal mode. The moment I go into normal mode vi will make the text into a multi-line one. I can't copy it using the terminal directly with ctrl+shift+v because I can't select anything with the mouse within the terminal buffer.
    – ivan
    Commented Aug 5, 2019 at 7:30
  • @ivan I'm not sure what's up with not being able to use the mouse to select in the terminal buffer; it's not as if the terminal should know that that part of the screen is a "vim terminal buffer" and other parts aren't. I just checked with vim 8.0/bash/mintty and I don't have that issue. Regardless, even if you could select it's likely still to be split; as I said, don't copy output of a visual mode program using terminal cut/paste.
    – cjs
    Commented Aug 5, 2019 at 7:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.