vim + COPY + mac over SSH

MacosVimSsh

Macos Problem Overview


I access a sever over ssh on which I run vim for editing files. When I try to yank text from vim into an editor locally on my mac (lion) either with y OR "+y it does not work. I end up with the text I copied last locally. It does work if I just use p within vim alright.

Macos Solutions


Solution 1 - Macos

To expand on Ray's answer…

When you are using Vim on a remote server via SSH, everything you do in Vim is done on the remote server. The remote server and the remote Vim that you are running on it have zero practical knowledge of your local computer and its system clipboard.

Because of that, y will never put the yanked text in your local clipboard.

In order to copy a chunk of text from the remote Vim to your local machine's clipboard you have three options:

  • Select the text with your mouse and hit Cmd+C like in any Mac OS X application.

    Obviously, it seems to be the easiest but it has at least three limitations:

    1. It is limited to the current screen. If the text you want to yank is not displayed entirely you won't be able to copy all of it.

    2. It doesn't play well with set mouse=a. With this option, any attempt to select something with the mouse will result in a visual mode selection which can't be copied with Cmd+C. As a workaround, you can use Alt+mouse to select the text without entering visual mode or simply remove this setting from your remote ~/.vimrc.

    3. Line numbers are copied as well.

  • Put the yanked text in a temporary file, scp it to your local machine and use pbcopy to put it in your system clipboard.

    This solution seems to be a little convoluted but it works (and the problem itself is also a little bit convoluted). Over the years I've seen a lot of different implementations ranging from simple one liners to client/server setups. Here is one, feel free to google around for others.

  • Use X-forwarding to connect your local clipboard to the remote clipboard if available.

Solution 2 - Macos

Had this problem - log in from OSX over SSH to a linux box and cannot copy text from a file, opened with vim.

My workaround is :set mouse=i

By default mouse is enabled in all modes. When you set it to be enabled only in Insert mode you can scroll around and copy when you are not editing (normal mode) but when you start editing (by hitting the I or Insert key) and enter insert mode the mouse acts as cursor placement and you cannot copy from terminal.

You can set that option in ~/.vimrc

See :help mouse for more information about the values you can set and the modes.

Solution 3 - Macos

My first answer on stackoverflow, but I feel it's a cool (albeit tiny) trick and it's worth posting. So here's what I do :

cat <filename>

When the text is printed onto the terminal, I select all the text with my mouse (the mouse scroll works since we're on the terminal window). Then copy that text with Cmd+C and paste into my local text editor.

The only flaw with this trick is that it's impractical to use if your files are tens of thousands of lines long since selecting all the lines with your mouse would be a task in itself. But for a file of ~2k lines it works well.

Solution 4 - Macos

My go-to solution is to edit the file with vim from your local machine via scp.

:e scp://[email protected]//path/to/document

This keeps your buffer local and makes it easy to copy to your local clipboard.

The other advantage is that you get to use your local vim setup (.vimrc settings, plugins, etc.)

Solution 5 - Macos

iTerm2 Shell Utilities come with it2copy which allows copying from a remote server to a client clipboard. Install Shell Utilities on the remote server and make sure you have Applications in terminal may access clipboard checked. enter image description here

Then, go into visual mode, select the text and execute <,'>:w !it2copy

Solution 6 - Macos

Yanking within vi in a terminal to which you ssh'd into copies the lines into vi's internal buffer on the remote machine, not into your Mac's clipboard.

Use your mouse. :)

Solution 7 - Macos

On MacOS, when SSH from machine A to machine B and using vim in machine B, I add this to my .vimrc in machine B:

nmap yr :call system("ssh $machineA_IP pbcopy", @*)<CR>

That way, in normal mode, if you copy something to * register, then type yr, the content of * register in vim@machine_B is copied to machine A's local clipboard, assuming you have setup Vim correctly with +clipboard and * register

Solution 8 - Macos

https://github.com/ojroques/vim-oscyank + iTerm2 + tmux worked in my case, this is my workflow:

Some parts of my .vimrc

Plug 'ojroques/vim-oscyank'  " clipboard over ssh through tmux

" yank operation don't need to use the *" register (system clipboard)
set clipboard+=unnamedplus

autocmd TextYankPost * if v:event.operator is 'y' && v:event.regname is '' | OSCYankReg " | endif

Solution 9 - Macos

Here's an update on the solution #2 from romainl. It creates and alias of the ssh command and launches the remotecopyserver if it's not running and installs the remotecopy(rclip) in the remote server. In short, you don't have to do anything except paste the code snippet below into your bash_profile.

######################## For SSH Remote Copy #########################
export LC_SETUP_RC='command -v rclip >/dev/null 2>&1 || { echo "executing"; mkdir -p /usr/local/bin; if [ ! -f /usr/local/bin/rclip ];then wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopy -P /usr/local/bin/; ln -s /usr/local/bin/remotecopy /usr/local/bin/rclip; chmod +x /usr/local/bin/remotecopy; fi; if [[ \":\$PATH:\" == *\"/usr/local/bin:\"* ]]; then export PATH=/usr/local/bin:$PATH; fi } > /var/log/rclip.log 2>&1 || echo "Some error occured in setting up rclip. check /var/log/rclip.log"'

ssh_function() {
count="`ps -eaf | grep remotecopyserver | grep -v grep | wc -l`";
if [ "$count" -eq "0" ]; then 
   mkdir -p $HOME/bin;
   if [ ! -f $HOME/bin/remotecopyserver ]; then 
      wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopyserver -P $HOME/bin;
      chmod +x $HOME/bin/remotecopyserver;
   fi;
   nohup $HOME/bin/remotecopyserver & 
fi;
ssh_cmd=`which ssh`
PARAMS=""
for PARAM in "$@"
do
  PARAMS="${PARAMS} \"${PARAM}\""
done
bash -c "ssh ${PARAMS} -R 12345:localhost:12345 -t 'echo \$LC_SETUP_RC | sudo bash; bash -l'"
}
alias ssho=`which ssh`
alias ssh=ssh_function
alias ssh2=ssh_function

vssh_function() {
ssh_config=`vagrant ssh-config`;
if [ "$?" -eq "1" ]; then
echo "Problem with Vagrant config. run 'vagrant ssh-config' to debug"
return 1
fi
PORT=`echo "$ssh_config" | grep Port | grep -o "[0-9]\+"`; 
ID_FILE=`echo "$ssh_config" | grep IdentityFile | awk '{print $2}'`
ssh2 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PasswordAuthentication=no -i $ID_FILE vagrant@localhost -p $PORT "$@"
}
alias vssh=vssh_function

Once the alias is activated, you can normally use ssh and whenever you need to copy to local clipboard from vim, use

:w !rclip 

to copy the whole file to clipboard

:'<,'> !rclip

to copy selected lines from visual mode. You have to press "Cmd+V" or "Ctrl+V" whenever it asks for the secret key.

Bonus

For those who work on Vagrant, there's a wrapper vssh which will execute vagrant ssh but also launches and install the necessary components.

Reference

Latest code snippet here - https://gist.github.com/ningsuhen/7933b206b92fc57364b2

http://endot.org/2011/12/04/remotecopy-copy-from-remote-terminals-into-your-local-clipboard/

https://github.com/justone/remotecopy

Caveats

The alias wraps the ssh command and there might be some unexpected issues. ssho is available if you need to execute ssh without the whole remotecopyserver thing. Alternatively, you can use the alias ssh2 and keep the ssh command as it is.

Solution 10 - Macos

One trick which i use often during copying vim text using mouse if number of lines get little over-flown my screen is to minimize (Cmd + '-') the text. :) Minimize so much that you can not see by eyes but you can copy all the text in one go.

Solution 11 - Macos

Or, from the terminal, write less [filename] to get it written to the terminal. Then start byt selecting with your mouse, while you hold down-arrow-key down. Then you can select the whole bunch.

Solution 12 - Macos

I was hoping to improve on my solution here, but instead will share it as it seems on par with some of the others.

When using iTerm2 on a Mac, sshing into machines, running tmux, and then editing with Vim, I have a vertical split iTerm2 window on the Mac that I pull all the way off to the side to make it as skinny as possible.

Then when I want to copy text from Vim, I will click into the tiny slice of iTerm2 window, and go back over and highlight and then copy the text from Vim. This works the best for single lines of text.

If there is a tmux vertical split, highlighting multiple lines in the Vim buffer won't wrap properly, and will copy text from the other tmux window, but otherwise this is great for copying 90% of what I need, without having to exit Vim, cat a file, or do something else.

I also have ample horizontal window space, making the small iTerm2 window not a space hog.

Solution 13 - Macos

Just use MobaXterm.
I tried lots of ways and none of them is easy. So the only solution I could find is using MobaXterm. You can see all of the files and open them any way you want.

Solution 14 - Macos

The easiest way to copy to local machine is via selecting with mouse and then CMD + c to copy. As is noted in another answer this has a few limitations/drawbacks. Consequently, I sought out the alternatives, but after trying for hours (unsuccessfully) to get X11 forwarding working, I instead came up with the following simple workaround (at least for the line-numbering caveat) for aid in mouse copying.

Add the following to your .vimrc to easily toggle line numbers for mouse copying:

nnoremap L :set invnumber <CR>

You can easily change the L to any key of your choice that you wish to be the shortcut key.

Solution 15 - Macos

Try the other clipboard register - "*y.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionevolutionView Question on Stackoverflow
Solution 1 - MacosromainlView Answer on Stackoverflow
Solution 2 - MacosDimitar KView Answer on Stackoverflow
Solution 3 - MacosMohit GiananiView Answer on Stackoverflow
Solution 4 - MacosDeanView Answer on Stackoverflow
Solution 5 - MacosandrewgazelkaView Answer on Stackoverflow
Solution 6 - MacosRay ToalView Answer on Stackoverflow
Solution 7 - MacosLinhView Answer on Stackoverflow
Solution 8 - MacosMauricio PoppeView Answer on Stackoverflow
Solution 9 - MacosningsuhenView Answer on Stackoverflow
Solution 10 - MacosmdevView Answer on Stackoverflow
Solution 11 - MacosZethView Answer on Stackoverflow
Solution 12 - MacosCameron GagnonView Answer on Stackoverflow
Solution 13 - MacosSahinView Answer on Stackoverflow
Solution 14 - MacosAugustine CalvinoView Answer on Stackoverflow
Solution 15 - MacosIdan AryeView Answer on Stackoverflow