Getting tmux to copy a buffer to the clipboard

I am trying to figure out a decent way to copy what I have in a tmux buffer into my clipboard. I have tried a couple of different things like

bind-key p select-pane -t 2 ; split-window 'xsel -i -b' ; paste-buffer

which gets me fairly close, all I have to do is hit control-d after I do prefix-p.

I tried fixing that by doing

bind-key p select-pane -t 2 ; split-window 'xsel -i -b << HERE; tmux paste-buffer; echo HERE'

But that just doesn’t work. In fact if I pair this down to just

bind-key p select-pane -t 2 ; split-window 'xsel -i -b << HERE'

it doesn’t do anything so I am assuming that split-window doesn’t like << in a shell command.

Any ideas?

Edit:
You can skip the select-pane -t 2 if you want, it isn’t really important. I just use a specific layout and pane 2 is the one I prefer to split when I doing something else so that goes into my bindings involving splits by default.

Asked By: Digital Powers

||

Here documents need newlines. For example, in a shell script, you can write

cat <<EOF >somefile; echo  done
file contents
EOF

I don’t think tmux lets you put newlines there, and even if it did, this wouldn’t be a good approach. What if the data itself contains HERE alone on a line (e.g. because you’re copying your .tmux.conf)?

I suggest to write the buffer contents to a temporary file. Untested:

bind-key p save-buffer ~/.tmux-buffer ; run-shell "xsel -i -b <~/.tmux-buffer && rm ~/.tmux-buffer"

There’s a race condition if you use this command in two separate tmux instances. I don’t know how to solve this.

There is a solution on the Arch Wiki using xclip:

# move tmux copy buffer into x clipboard
bind-key C-y save-buffer /tmp/tmux-buffer ; run-shell "cat /tmp/tmux-buffer | xclip"

https://wiki.archlinux.org/index.php/Tmux

Answered By: jasonwryan

This should work:

# move x clipboard into tmux paste buffer
bind C-p run "tmux set-buffer "$(xclip -o)"; tmux paste-buffer"
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i"
Answered By: Grauwolf

A solution for Mac OS X. Follow these 2 steps:

  1. Use Chris Johnsen’s workaround: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

  2. Add this code to your tmux config (~/.tmux.conf)

# paste clipboard into tmux buffer
bind v run-shell "reattach-to-user-namespace -l zsh -c 'tmux set-buffer \"$(pbpaste)\"; tmux paste-buffer'"
# put tmux buffer into x clipboard
bind y run-shell "reattach-to-user-namespace -l zsh -c 'tmux show-buffer | pbcopy'"

Answered By: Alex Gaudio

A simpler solution for Mac OS-X

This builds off of Alex’s answer and uses stuff that didn’t exist at the time.

If you are using homebrew (and if you aren’t, why aren’t you?) then you can just do this:

brew install reattach-to-user-namespace

Then in your ~/.tmux.conf:

set-option -g default-command "reattach-to-user-namespace -l zsh" # or bash...
bind C-c run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
bind C-v run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

To copy the buffer from tmux (you should have already copied something using tmux) into the Mac pasteboard, use <tmux-key> Control-c. It will now be available for Command-v or pbpaste

To paste something from the Mac pasteboard, use <tmux-key> Control-v.

Answered By: docwhat

After trying different solution, here is my final setup:

# move x clipboard into tmux paste buffer
bind C-p run "xclip -o | tmux load-buffer -
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i -selection clipboard"

using save-buffer instead of show-buffer gives the real data without the data as shown with line-breaks when you are in splits.

I also use this to begin selection/copy in tmux copy-mode:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'y' copy-selection

I guess it could be possible to merge the copy-selection with the ‘y’ key AND move it to the x clipboard.

Answered By: Ownatik

I dislike having extra key presses, so I wanted something more ambitious. Enter copy mode with [, highlight the right text, and then press ] to copy the text to the clipboard.

Also, tmux likes to include newlines in expressions that wrap (and oddly those newlines are in the wrong place! They aren’t where the expression wrapped on the screen). So I wanted C-] to copy the expression removing the newlines.

On tmux 1.6 I tried this:

bind [ copy-mode
bind -t vi-copy ] run "tmux send-keys Enter; tmux show-buffer | xclip -i -selection clipboard;"
bind -t vi-copy C-] run "tmux send-keys Enter; tmux show-buffer | perl -pe 's/n//' | xclip -i -selection clipboard;"

but that didn’t work because tmux doesn’t seem happy to bind complex things to the vi-copy table. So I ended up doing this instead:

bind [ copy-mode ;                                                        
    bind -n ] run                                                          
    "tmux send-keys Enter;                                                 
     tmux show-buffer | xclip -i -selection clipboard;                     
     tmux unbind -n C-];                                                   
     tmux unbind -n ]" ;                                                  
    bind -n C-] run                                                        
    "tmux send-keys Enter;                                                 
     tmux show-buffer | perl -pe 's/n//' | xclip -i -selection clipboard; 
     tmux unbind -n C-];                                                   
     tmux unbind -n ]"

This leads to weird things (] or C-] will act funny the next time you use them, but only once) if you exit from copy mode in another way besides ] or C-]. This could be fixed with some more bindings I imagine, but this does what I want most of the time.

Answered By: Leif

I am trying to figure out a decent way to copy what I have in a tmux
buffer into my clipboard. I have tried a couple of different things
like

For emacs style bindings there are a few different options. (Vi-style should be similar?) The typical binding for doing “copy-selection” in emacs is M-w, so it would be very convenient to have the same binding in tmux.

1 — Would be ideal, but is non-working (due to tmux limitation?)

unbind-key -t emacs-copy M-w
bind-key -t emacs-copy M-w copy-selection; 
  run-shell "tmux save-buffer - | xsel --input --clipboard"

2 — Compromise that works well for me: Accept using a different keybinding for emacs-copy in tmux. Use for example C-M-w. (This binding which will be defined “globally” — not only in copy-mode — but only useful in copy-mode)

bind-key -n C-M-w send-keys M-w; 
 run-shell "tmux save-buffer - | xsel --input --clipboard" 
Answered By: Hugo Heden

The copy-pipe command was added as of version 1.8. It copies a selection to the tmux buffer and pipes it to a command. Now there is no need for a prefix binding. Here’s an example:

bind -t vi-copy y copy-pipe "xclip"

# For OS X users:
bind -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

Now when you have some text selected in copy-mode, y will copy that text to the tmux buffer as well as the OS clipboard. However, it doesn’t help if you want to get text from the clipboard to the tmux buffer.

Answered By: Tyler Holien

A slightly modified variant of the accepted answer, which I cooked up.

I also prefer to use the system clipboard (Ctrl-C, Ctrl-V) in addition to xclip’s primary default clipboard (the one you get with mouse selection and mouse middle-clicks). For choosing the system clipboard you need to pass -selection clipboard argument to xclip.

Also while copying a buffer into a clipboard, I like the ability to choose which buffer I want to copy. It is done using choose-buffer and then passing buffer the argument to save-buffer using -b %%.

# Copy into clipboard
bind C-c choose-buffer "run "tmux save-buffer -b %% - | xclip -i -selection clipboard""
# Paste from clipboard
bind C-v run "xclip -o -selection clipboard | tmux load-buffer - ; tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run "tmux save-buffer -b %% - | xclip -i ""
# Paste from primary
bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"

UPDATE:
Somehow with tmux 1.8 and two of my openSUSE 12.2 installations, I see a hang when tmux run-shell is invoked with xclip reading from stdin over a pipe. I instead decided to give xsel a try and that seems to work. These are the equivalent key bindings using xsel. I also used && to chain the commands in paste for more robustness.

# Copy into clipboard
bind C-c choose-buffer "run "tmux save-buffer -b '%%' - | xsel -i -b""
# Paste from clipboard
bind C-v run "xsel -o -b | tmux load-buffer - && tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run "tmux save-buffer -b '%%' - | xsel -i""
# Paste from primary
bind C-p run "xsel -o | tmux load-buffer - && tmux paste-buffer"
Answered By: Tuxdude

Many of these answers didn’t work for my Ubuntu 14.04 on zsh as-is. Not sure if my shell had anything to do with it, but here is my working version of using this strategy for copy, and this strategy for paste.

    bind-key -t vi-copy 'v' begin-selection
    bind-key -t vi-copy 'y' copy-pipe "xclip -sel clip -i"
    bind-key ] run-shell "xclip -sel clip -o | tmux load-buffer - ; tmux paste-buffer" 

Some notes:

  • for copy-pipe, I needed to specify my clipboard with -sel clip -i. That line combines the yank to tmux buffer and sends it to xclip.
  • to actually paste it, I needed to again specify which clipboard with -sel clip -o

This works beautifully now for my vim/zsh/tmux setup.

Answered By: brianclements

You might want to try tmux-yank plugin. It enables copying straight to system clipboard (OS X and Linux) and some other goodies like yanking the current shell line.

Answered By: user80379

And improved version of @Leif answer could be:

tmux bind-key '[' run "tmux copy-mode;
tmux bind-key -n ']' run "tmux send-keys Enter; tmux save-buffer - | xclip -i -selection clipboard;
tmux unbind-key -n ']'";
tmux bind-key -n q run "tmux unbind -n ']'; tmux send-keys q";
tmux bind-key -n C-c run "tmux unbind -n ']'; tmux send-keys C-c""

This way there are no consequences if you exit from copy mode in another way besides ], the above code is wrapped in tundle/tmux-yank a tmux plugin for copying tmux text into the system clipboard, it targets tmux >= 1.6 on OS X and Linux.

Answered By: Javier López

On OS-X with tmux version 2.2 or later the following will work:

bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "pbcopy"
bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "pbcopy"
Answered By: Kyle Kloepper

This is my rather lengthy answer that should fix two major problems with using xclip to copy the buffer from a remote (ssh) tmux session:

1. Irresponsive xclip

For me @Grauwolf’s answer with xclip didn’t work (renders tmux pane totally irresponsive).
I found out why in the Tmux page of the Arch wiki:

xclip could also be used for that purpose, unlike xsel it works better on printing raw bitstream that doesn’t fit the current locale. Nevertheless, it is neater to use xsel instead of xclip, because xclip does not close STDOUT after it has read from tmux’s buffer. As such, tmux doesn’t know that the copy task has completed, and continues to wait for xclip’s termination, thereby rendering tmux unresponsive. A workaround is to redirect STDOUT of xclip to /dev/null

So the binding should be:

bind-key C-y run "tmux save-buffer - | xclip -i -sel clip > /dev/null"

Now, this will work if your tmux session is local.

2. xclip unable to connect to X

If you are using tmux over ssh -X, there are big chances this won’t work directly.

That’s because the shell variable $DISPLAY needs to be set properly.

Complete solution

So for me, the complete working solution is to put the following lines in my ~/.tmux.conf:

set-option -g update-environment "DISPLAY"
bind-key C-y run "export DISPLAY=`tmux show-env | sed -n 's/^DISPLAY=//p'`; tmux save-buffer - | xclip -i -selection clipboard >/dev/null"
# Or more concise:
bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's/^DISPLAY=//p'` >/dev/null

For pasting from primary:

bind-key C-p run "xclip -d `tmux show-env | sed -n s/^DISPLAY=//p` -o | tmux load-buffer - && tmux paste-buffer"

I don’t fully understand why $DISPLAY isn’t correctly set while sourcing .tmux.conf, so this is why I have to extract it with tmux show-env and sed.

If you have tmux >= 1.8, you can adapt this command with copy-pipe:

bind-key -t vi-copy y copy-pipe 'xclip -in -selection clipboard -d `tmux show-env | sed -n s/^DISPLAY=//p` >/dev/null'
Answered By: PlasmaBinturong

Here is an attempt at a comprehensive answer.

First a little history

When this question was first asked (June, 2011) copying text from Tmux to the clipboard had to be a two-step process, first copy the selected text to Tmux’s buffer, then copy the text from Tmux’s buffer to the system clipboard.

In 1.8 (March, 2013) the copy-pipe command was added which allows you to copy the selected text straight into the system clipboard (or other destination).

Then in 2.4 (April, 2017) the key tables were significantly changed rendering many of the answers on this page obsolete.

Answering the original question

Linux:

bind-key C-y run-shell "tmux save-buffer - | xclip -i -r > /dev/null" ; display-message "Copied tmux buffer to selection"
bind-key C-Y run-shell "tmux save-buffer - | xclip -i -r -selection clipboard > /dev/null" ; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"

Mac:

If you are using homebrew then you should install reattach-to-user-namespace by running the following command in a terminal:

brew install reattach-to-user-namespace

Then in your ~/.tmux.conf:

bind-key C-y run-shell "tmux save-buffer - | reattach-to-user-namespace pbcopy" ; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "reattach-to-user-namespace pbpaste | tmux load-buffer - ; tmux paste-buffer"

The Shorter Method (copy and paste a selection straight from and to the clipboard for tmux>2.4)

Note: there are two versions for Linux because Linux has a primary and secondary clipboard (also known as selection).

Linux:

bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -r" ; display-message "Copied to selection"
bind-key -T copy-mode-vi Y send-keys -X copy-pipe "xclip -r -selection clipboard" ; display-message "Copied to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - && tmux paste-buffer"

Mac:

bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" ; display-message "Copied to clipboard"

Customizing these commands

  • If you don’t want the command to tell you what it did in the status line then just remove the display-message (as well as the ; that comes before it).

  • If you are using the Emacs style copy-mode instead of vi then replace any instance of copy-mode-vi with just copy-mode

  • If you are running Linux and you want to use xsel instead of xclip replace xclip -r with xsel -i -p and xclip -o with xsel -o -p

  • The -r in xclip -r is optional, it removes the last newline. It is useful for copying commands, then when you paste them they won’t be immediately executed.

  • If you are tunneling over SSH then you should consult https://unix.stackexchange.com/a/354581/14252

References:

Answered By: Jason Axelson

I use copyq a multiline clipboard manager. (It works with Windows, OSX, Linux.)

  • Add the following lines in ~/.tmux.conf:

    set-window-option -g mode-keys vi
    bind C-y run 'out=`tmux save-buffer - ` && copyq add "$out"'
    
  • cygwin demands copyq.exe location in ~/.bashrc:

    export PATH="$PATH:/cygdrive/c/Program Files (x86)/CopyQ"
    
Answered By: Oleg Svechkarenko

I use the following config:

bind-key -T root C-p run-shell "tmux capture-pane -pS - | xclip -in -selection clipboard"

In this case the key binding is Ctrl + P, but you can change it as per your liking.

Answered By: Ahmad Ismail