Making the clipboard work between iTerm2, tmux, vim and OS X.

Getting copying and pasting to behave sanely when working with the terminal has been a constant struggle, probably ever since I started working with PuTTY, slackware and what must have been Windows 98.

These days my environment consists of OS X 10.10, tmux, iTerm2 and well, Vim has never gone away. Neither have my issues with copy-pasting though. It seems that every time I have a solution, a few months later a cog in the machine changes and breaks the whole set-up again, which then takes me months to fix due to my lazyness.

I finally took the time again to look into this, and figured I should share. So this is the December 2014 solution! Keep in mind that in January 2015 this may no longer work though…

iTerm2

First: iTerm2. iTerm2 has a setting that allows terminal applications to access the clipboard.

This works through ANSI escape sequences, and you actually want this OFF. Before today I had this setting on, which kinda worked but it always truncated the clipboard, which made it completely frustrating for copy-pasting larger things such as logfiles.

So to repeat this, the “Allow clipboard access to terminal apps” must be OFF

tmux

OS X has two command-line utilities to interact with the clipboard, pbcopy and pbpaste. These utilities break when running inside of tmux.

To fix this, we need a small utility that can be installed using brew:

brew install reattach-to-user-namespace

If you would like to know exactly how this works and why it’s needed, or if you want to install this without using brew, the github project page has all the answers.

Bonus fact: this also fixes launchctl in tmux.

After this, we need to make a few modifications to your ~/.tmux.conf. Add the following lines:

# Copy-paste integration
set-option -g default-command "reattach-to-user-namespace -l bash"

# Use vim keybindings in copy mode
setw -g mode-keys vi

# Setup 'v' to begin selection as in Vim
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"

# Bind ']' to use pbpaste
bind ] run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

The previous lines sets up tmux correctly, and binds various copy and paste keys to use pbpaste and pbcopy.

The one thing I have not figured out here, is that I haven’t been able to get tmux mouse support with this. So if you want to copy and paste to the system clipboard, you need to do this with the keyboard short-cuts.

Know how to extend this feature to get mouse support? Do let me know!

Don’t forget to restart tmux or run:

tmux source-file ~/.tmux.conf

To start using this new configuration.

Vim

Lastly, vim! It would be awesome if we can just ‘yank’ and paste using y and p from Vim as well.

This is rather easy. Open up your .vimrc, or .vim/vimrc file and simply add this line:

set clipboard=unnamed

However, this did not work with the Vim version that OS X shipped with (which is 7.3). To upgrade to 7.4, just use Homebrew again:

brew install vim

Sources

A big thank you to the sources. I got most of my information from the following links:

Bonus tmux feature

Add the following lines in ~/.tmux.conf to automatically open new windows and tabs in the directory from where you opened them:

# New window with default path set to last path
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"

Web mentions

Comments

  • Marcin Kasinski

    Awesome post! Thank you very much for sharing. That is exacltly what I was looking for!

  • Brian Dant

    Nice work! Thank you.

  • Manoj Mahalingam

    You can select with mouse, and before letting go, press y to copy.

    • Evert

      Evert

      I noticed this a little later as well, and this is exactly how I work around that issue. Thanks!

    • alsaid

      good!

    • Boztown

      Thanks dude! This needs to be added to the article.

    • Mars Huang

      You are awesome! Thanks!

    • Bed Intruder

      Doesnt work in tmux (2.1)

  • Mingliang Liu

    Very nice post!

  • Rickard von Essen

    Awesome! Nice bonus.

  • Tanner Jones

    Just an fyi, after 'brew install vim' I lost what I feel like is the correct behavior for the backspace key on Mac OSX. After some searching, it seems that the default behavior for 'backspace' is to only work on characters typed during the current insertion mode. I don't like this... The fix is to put the following in ~/.vimrc
    set backspace=indent,eol,start

    http://stackoverflow.com/qu...

  • John R. Bussiculo

    Thank you!

  • fxi

    July 2015: this still works :) And thanks for the bonus: I haven't even thought that this could be fixed...

  • Dave Hayes

    Thanks, this was a huge help. I'm not sure if it's tmux 2.0, iTerm2 beta 3, or both, but if I leave "Allow clipboard access to terminal apps" enabled, then copy on mouse selection with tmux works properly. I haven't noticed any negative side effects, but like I said... that may be a recent development.

  • Avétis Kazarian

    Actually, you can share clipboard with VIM without all this.

    Simply use the global register '+':

    "+y will yanks to system clipboard.
    "+p will pastes from the system clipboard.

  • Byron Mansfield

    Does anyone know if there is support for highlighting from one bracket to another like in vi/vim? Say I want to select "Some string" from a line like: `command "Some string"`. In vi/vim I can copy that a number of ways like `yi"` or `v%y`. I have my set up as described in this article. But it seems like the tmux vi mode does not support these more complex vim key binds. Any thoughts?

  • S Graham

    wohoo - thanks so much!!

  • Phillip Pope

    Still works in 2017, thanks!

  • johnpark82

    Cool

    It works on me :)

  • Alex

    This post is really very useful. Thanks a lot!
    Regards, Alex

  • Xavier Artot

    Don't forget to upgrade vim...

  • JSThePatriot

    I would like to note ... June 2nd, 2017... I'm using a newer version of tmux, and you cannot use `vi-copy`. Here's an issue comment that describes exactly how one would need to go about it: https://github.com/tmux/tmu... ... well I can't get any of it to work. :( so never mind.

  • Steven Leiva

    This is the best post ever made anywhere.

    In all seriousness, thank you. Probably saved me hours of my time.

  • Robin Nemeth

    In newer versions of tmux the `-t` syntax was slightly changed:
    Change the previous to this and you should be good to go.

    ```
    bind-key -T copy-mode-vi v send-keys -X begin-selection
    bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"

    Update default binding of `Enter` to also use copy-pipe
    unbind -T copy-mode-vi Enter
    bind-key -T copy-mode-vi Enter send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"

    # Bind ']' to use pbpaste
    bind ] run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"
    ```
    See https://github.com/tmux/tmu...

    • rick

      you are correct ! thanks for this

  • Lyndsy Simon

    This seems to still work, but adds a delay of 1-2 seconds when opening a new terminal. I'm using iTerm2 (3.1.5), macOS 10.13.2, and zsh (5.3).