Skip to content

Instantly share code, notes, and snippets.

@brendanhay
Created February 8, 2012 14:15
Show Gist options
  • Star 71 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save brendanhay/1769870 to your computer and use it in GitHub Desktop.
Save brendanhay/1769870 to your computer and use it in GitHub Desktop.
Tmux, copy-mode, and OSX shenanigans.

Copy, with line wrapping!

If you've been trying to copy/paste text from a multi-pane tmux session with the mouse, you've probably been pretty pissed at the blissful ignorance a terminal application has of the rodent in your hand.

The alternative, which is quote-unqoute native copy/pasting using copy-mode takes a bit to get used to. So this is one solution for copying and pasting lines from a session with correct line wrapping behaviour, albeit keyboard only.

Disclaimer

Since copy-mode has similar concepts of marks, regions, and temp buffers to Emacs .. you'll probably find it straight forward if you're familar with Emacsen. For people using vi-mode in tmux, the same still applies but obviously the default key bindings will differ alot from what I show below.

I've listed C-a as the send-prefix key even though C-b is the default. The word on the street is tmux developers don't even use C-b.

The following steps work for me using a OSX/iterm2/tmux/dvtm combo, if you really need the mouse, you can try out: http://code.google.com/p/iterm2/wiki/TmuxIntegration


Steps:

1) Follow the instructions here: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard to get pbcopy/pbpaste working from inside of tmux.

2) Doctor the following code snippet for your tastes and add it to ~/.tmux.conf:

# Set bash to whichever shell you are using, zsh for example
set-option -g default-command "reattach-to-user-namespace -l bash" 

# Remove the default binding for copy-selection, substitute emacs-copy with vi-copy if you're using vi-mode
unbind -t emacs-copy M-w

# Bind a different key to copy-selection
bind -t emacs-copy c copy-selection

# Bind prefix-M-w to copy-selection, save selection to buffer, and then pipe it's contents to pbcopy
bind M-w send-keys c\;\
         save-buffer /tmp/tmux-buffer\;\
         run-shell "reattach-to-user-namespace -l bash -c 'cat /tmp/tmux-buffer|pbcopy'"

The above code removes the default copy-selection key in copy-mode (M-w in my case) and substitutes it with a prefixed version: C-a M-w. This is because (without patching) tmux cannot bind multiple commands to a key under a specific key-table, only globally.

3) You can check what keys you currently have set for copy-mode by using C-a -> list-keys -t vi-copy|emacs-copy to list mode key bindings or use setw -g mode-keys vi|emacs to switch modes.

To copy the desired piece of text from a tmux pane to your OS' clipboard, you will need to do the following:

  • Mark the start of the region using C-a C-space
  • Use next/previous char/line to expand the marked region until it encompasses what you want to copy
  • C-a Alt-w to copy the region into a buffer (success will cause the highlighted region to become unselected)
  • C-] to paste the buffer to the current cursor position (outside of copy-mode)

tmux homepage http://tmux.sourceforge.net/

man tmux http://manpages.ubuntu.com/manpages/lucid/man1/tmux.1.html

.tmux.conf https://github.com/brendanhay/dotfiles/blob/master/.tmux.conf


Default emacs-copy keys:

  • C-a Prefix
  • C-a [ Copy mode
  • C-a C-space Mark
  • C-n Next line
  • C-p Previous line
  • C-f Next char
  • C-b Previous char
  • C-a Alt-w Copy marked region into buffer
  • C-a ] Paste saved buffer
  • ESC Exit copy mode
@pbarnes
Copy link

pbarnes commented Jun 20, 2013

For Mac OS X you need to run it through reattach-to-user-namespace (not original, just did some combining of others ideas). This works for me:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'x' copy-selection
bind-key 'p' run-shell "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"
bind-key 'y' send-keys x; run-shell "tmux save-buffer - | reattach-to-user-namespace pbcopy"; display-message "copied"

@ff3
Copy link

ff3 commented Feb 5, 2014

For anyone still fighting with this I recommend the following link:
http://robots.thoughtbot.com/tmux-copy-paste-on-os-x-a-better-future

# 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"

@jasonm23
Copy link

jasonm23 commented Apr 3, 2015

Shouldn't Exit copy mode be listed as ESC Enter ?

@scottstanfield
Copy link

scottstanfield commented Jan 27, 2018

For those of you finding this in 2018, with tmux 2.6, you don't need the reattach-to-user-namespace gymnastics anymore. This is all I need with iTerm2 (3.1.5), tmux (2.6) and macOS High Sierra (10.13.2).

In iTerm 2 preferences, first tab "General", enable "Applications in terminal may access clipboard".

# tmux 2.6 doesn't need the 'reattach-to-user-namespace' gymnastics
setw    -g  mode-keys    vi
bind-key -T edit-mode-vi Up                send-keys -X history-up
bind-key -T edit-mode-vi Down              send-keys -X history-down
bind-key -T copy-mode-vi v                 send      -X begin-selection
bind-key -T copy-mode-vi [                 send-keys -X begin-selection
bind-key -T copy-mode-vi y                 send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi Enter             send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi ]                 send-keys -X copy-selection

@cevaris
Copy link

cevaris commented Mar 31, 2018

FYI for emacs mode in tmux 2.6 without reattach-to-user-namespace on Mac OS X

# Copy & Paste
set -g mode-keys emacs
bind-key -T copy-mode [    send-keys -X begin-selection
bind-key -T copy-mode M-w  send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode ]    send-keys -X copy-selection

@kamoljan
Copy link

kamoljan commented Apr 9, 2018

@cevaris like this?

➜  ~ cat ~/.tmux.conf
# Remove the default binding for copy-selection, substitute emacs-copy with vi-copy if you're using vi-mode
unbind -t emacs-copy M-w

# Bind a different key to copy-selection
bind -t emacs-copy c copy-selection

# Bind prefix-M-w to copy-selection, save selection to buffer, and then pipe it's contents to pbcopy
bind M-w send-keys c\;\
         save-buffer /tmp/tmux-buffer\;\
         run-shell "reattach-to-user-namespace -l bash -c 'cat /tmp/tmux-buffer|pbcopy'"

# Copy & Paste
set -g mode-keys emacs
bind-key -T copy-mode [    send-keys -X begin-selection
bind-key -T copy-mode M-w  send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode ]    send-keys -X copy-selection

@paraita
Copy link

paraita commented Dec 5, 2018

thanks for the clarification @scottstanfield

@taylormade84
Copy link

For those of you finding this in 2018, with tmux 2.6, you don't need the reattach-to-user-namespace gymnastics anymore. This is all I need with iTerm2 (3.1.5), tmux (2.6) and macOS High Sierra (10.13.2).

In iTerm 2 preferences, first tab "General", enable "Applications in terminal may access clipboard".

# tmux 2.6 doesn't need the 'reattach-to-user-namespace' gymnastics
setw    -g  mode-keys    vi
bind-key -T edit-mode-vi Up                send-keys -X history-up
bind-key -T edit-mode-vi Down              send-keys -X history-down
bind-key -T copy-mode-vi v                 send      -X begin-selection
bind-key -T copy-mode-vi [                 send-keys -X begin-selection
bind-key -T copy-mode-vi y                 send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi Enter             send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi ]                 send-keys -X copy-selection

OMG YOU SAVED MY LIFE that was the issue, I owe you a beer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment