135

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.

3
  • 2
    Make sure to look at the below 2014 answer, which is more recent than some of the other ones. It recommends the tmux yank plugin which works very well.
    – dmonopoly
    Commented Jan 28, 2015 at 5:02
  • For an answer that is up-to-date with Tmux 2.4 (released April 2017) and 2.6 see my answer Commented Dec 9, 2017 at 20:52
  • Tmux 3.0a Ubuntu 20.04 unix.stackexchange.com/a/607112/148062 Commented Oct 29, 2020 at 21:21

17 Answers 17

97

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"
10
  • 1
    So it does. That's much nicer than using a temporary file, thanks. It even automatically copes with multiple concurrent sessions, thanks to the TMUX environment variables. Commented Jul 10, 2011 at 16:05
  • 22
    A better instruction for the C-p would be: bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer" -- no quoting issues or command line limit issues.
    – docwhat
    Commented Feb 23, 2012 at 3:37
  • 11
    Does tmux have a hook to copy the selection into the clipboard when in copy-mode? Commented Feb 5, 2013 at 18:56
  • 2
    xclip -o option didn't worked for me so I've changed to bind C-c run "tmux save-buffer - | xclip -selection c"\; display-message "Buffer copied to clipboard"
    – Pawka
    Commented Aug 23, 2013 at 12:46
  • 6
    Every time I do the copy this way, tmux stops responding to any keyboard shortcuts. Any solution to that?
    – skrat
    Commented Jun 2, 2015 at 11:59
45

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.

7
  • 1
    Works perfectly and is the simplest solution of the bunch.
    – Naseer
    Commented Jun 3, 2014 at 18:05
  • 2
    Doesn't work for me under Linux, this one does though: unix.stackexchange.com/a/131074/13601 Commented Jul 2, 2014 at 15:45
  • 1
    As of OS X 10.10, it appears reattach-to-user-namespace is not necessary.
    – Chris
    Commented Jul 23, 2015 at 6:45
  • 11
    This no longer works for Tmux 2.4 which was released on April 20, 2017. Instead you need to use bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip" and for OS X: bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" Commented Dec 9, 2017 at 19:01
  • 1
    It still does not work...
    – Madeo
    Commented Jul 20, 2021 at 1:44
43

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.

4
  • 2
    This answer is superb. I was using tmux show-buffer which caused line wrap issues tmux save-buffer - solved it.
    – event_jr
    Commented Mar 18, 2012 at 5:00
  • What does the - at the end of tmux save-buffer - do? Commented Apr 13, 2012 at 17:58
  • Emits the save-buffer to stdout. You can replace the - with a filename and it'll save it there. This prevents you from writing (and having to clean up) a file.
    – docwhat
    Commented Apr 15, 2012 at 4:54
  • 1
    As of OS X 10.10 reattach-to-user-namespace is no longer necessary. Almost every tutorial and documentation regarding tmux and OS X mentions it, because copy & pasting wasn’t easily possible a couple of years ago. These days it (mostly) works out of the box. Commented Aug 3, 2015 at 8:01
24

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.

4
  • Thanks works perfectly, the race condition isn't a concern for me, I only use 1 session. Commented Jun 27, 2011 at 20:53
  • To avoid race condition, I'd suggest using mktemp which is widely available
    – Grief
    Commented Jul 8, 2016 at 19:40
  • @Grief Good idea. In this case, using the PID of the tmux process would work as well and would probably be easier to arrange ($PPID in a shell launched by tmux). But how do you get the variable file name (however it's constructed) into the argument of save-buffer? I guess save-buffer - | … like in Grauwolf's answer, which does away with a temporary file altogether? Commented Jul 8, 2016 at 19:44
  • You are correct, my fault, this would not be possible.
    – Grief
    Commented Jul 8, 2016 at 19:50
17

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.

1
  • 8
    This is a great, clean solution and should be considered more since it's a much more recent answer than the others. Thanks for sharing!
    – dmonopoly
    Commented Jan 28, 2015 at 5:00
16

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:

2
  • Is this command bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer", still valid? for tmux>2.4
    – alpha_989
    Commented May 30, 2018 at 19:31
  • Maybe I'm too new to to tmux but I didn't understand how to use it on linux: I've added this: <bind-key C-y run-shell "tmux save-buffer - | xclip -i -r > /dev/null" \; display-message "Copied tmux buffer to selection"> And after seeing I've copied data to my buffer, I'm trying to press C-P for pasting which doesn't paste the stuff I have in the buffer... help? Commented Mar 9, 2022 at 12:17
9

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.

1
  • I was trying to merge both commands as you mentioned with no success. Any ideas on how to do it? Commented Jun 6, 2013 at 22:25
7

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.

1
5

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

5

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

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'
4
  • /home/linux/.tmux.conf:11: invalid or unknown command: bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's[0/0] PLAY=//p'` >/dev/null
    – user
    Commented Apr 19, 2019 at 1:59
  • @user the sed command you show is not the same as the one I wrote... Is this what you wrote in your .tmux.conf? Commented Apr 23, 2019 at 14:59
  • I just copied and pasted your code.
    – user
    Commented Apr 23, 2019 at 19:09
  • @user, strange. There could be many sources of errors. Check first that your quoting is alright. Then, are you familiar with sed? The command should be: sed -n s/^DISPLAY=//p. Alternatively, you could use cut: tmux show-env DISPLAY | cut -d'=' -f2. It might also be worth checking your tmux version. Commented Apr 25, 2019 at 8:40
4

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

2
  • 2
    Does tmux create the save-buffer file securely in a shared directory? Otherwise putting it in /tmp is a security hole. There's a useless use of cat, and the removal of the temporary file is missing. Then it's a matter of xsel vs xclip, which are equivalent here, and you have my (indenpendently written) solution. Commented Jun 27, 2011 at 21:09
  • 1
    Thanks Gilles. I'll update the wiki to reflect your points.
    – jasonwryan
    Commented Jun 27, 2011 at 21:12
3

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

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.

1
  • thank you! -sel clip -i solves the problem. Although, I do not understand why you need to specify clipboard again to paste it (standard ] works for me)
    – melekes
    Commented Jun 11, 2014 at 11:39
2

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

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.

1

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"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .