Configuring cross-platform vim-like copy/paste support in tmux


I’m a heavy tmux user, and I’m also constantly switching between macOS, GNU/Linux, and Windows, therefore it was critical for me to make sure my tmux copy/paste configuration worked everywhere, which is even trickier given that tmux v2.4 introduced various breaking changes. I’m also a vim user, so my copy/paste bindings are inspired by it, but it should be simple to adapt.

macOS

We will first need to install the reattach-to-user-namespace tool in order to get tmux to communicate with pbcopy and pbpaste. This package is available from Homebrew: brew install reattach-to-user-namespace or from MacPorts: port install tmux-pasteboard. We can configure tmux to use this package as follows:

set-option -g default-command "reattach-to-user-namespace -l zsh"

We also have to add the following snippet, independently of the tmux version we’re running:

unbind p
bind p run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

Once that’s set, if we have tmux < v2.4, then we can do:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"

Otherwise, we can do:

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

GNU/Linux

We will rely on the xsel command. First add the following snippet:

unbind p
bind p run "xsel -o | tmux load-buffer - ; tmux paste-buffer"

Given tmux < v2.4, we can do:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy y copy-pipe "xsel -i -p -b"
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "xsel -i -p -b"

Otherwise, we can do:

bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel -i -p -b"
unbind -T copy-mode-vi Enter
bind-key -t vi-copy Enter copy-pipe "xsel -i -p -b"

Windows

The simplest way is to use the Windows Subsystem for Linux and follow the GNU/Linux instructions. Otherwise, I had some luck configuring Cygwin as follows, which assumes we have the cygutils-extra package that provides putclip:

unbind p
bind p run "putclip | tmux load-buffer - ; tmux paste-buffer"

Given tmux < v2.4, we can do:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy y copy-pipe "putclip"
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "putclip"

Otherwise, we can do:

bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "putclip"
unbind -T copy-mode-vi Enter
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "putclip"