Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

How We Use tmux for Remote Pair Programming

Update 07/18/2012: We have added tmux-vim autosaving support as a Vim plugin. It’s available here:

Update 07/20/2012: There is a lively discussion on Hacker News about this post in addition to the comments below.

tmux is the cool kid on the block for remote pair programming, as long as you are using a terminal based editor such as Vim or Emacs.

There is no shortage of tutorials and guides regarding how to use tmux, thus my only introduction to tmux will be this: tmux is a terminal multiplexer and supports shared terminal usage.

Our large software project used tmux regularly for remote pair programming and settled on a configuration that has worked well for our team. Read on to learn about tmux’s advantages and disadvantages vs. desktop screen sharing, why and how we used it, and how we addressed the many challenges of remote pairing using tmux.

Advantages vs. Desktop Screen Sharing

  • Fast! tmux has the least latency of any collaborative code editing we have used
  • Addictive usage model: tmux’s multiple terminal pane usage model is very handy in general. Some of us now use tmux even when we are not remote pairing
  • No extra heavyweight software: if you have tmux and ssh access you’re good to go

Disadvantages vs. Desktop Screen Sharing

  • Requires ssh access and thus possibly a VPN
  • Extra overhead of learning and using tmux commands
  • Lack of desktop friendly UX, such as mouse support, function keys, ⌘ key
  • Only for terminal based editors, such as Vim and Emacs
  • Might still need desktop screen sharing for GUI-based tools and tasks: shared web browser for web development, etc.

Why We Used It for Remote Pairing

Due to network latency GUI-based desktop screen sharing was intolerably slow for coding. tmux made network latency a non issue. My personal experience was that tmux + Vim was so fast when working remotely that it was usually indistinguishable from coding locally.

Monitor Setup

We use two monitors: the iMac’s main 27″ monitor and a large (usually at least 24″) LCD rotated vertically.

We usually had iTerm running a shared tmux session on the large 27″ display and a desktop screen sharing session on the vertical display. The vertical display usually had the shared web browser visible since we were usually doing web development.

Challenges and How We Addressed Them

Most of our in-office developers only used tmux when remote pairing: the majority of their development was in-person pair programming using MacVim and “normal” tabbed iTerm. The occasional switch to terminal-based Vim within tmux and a bunch of tmux terminal panes was the most challenging aspect of using tmux as part of our development stack. The major difference were:

  • Automatic saving within MacVim was lost
  • No mouse support
  • Scrolling onerous in tmux
  • Copy-paste actions onerous in tmux
  • MacVim keymapping not fully supported in terminal Vim
  • Learning tmux specific commands

Read on to see how (or if) we addressed the above challenges.

Automatic Saving

Once you have automatic saving it’s tough to give it up. Our buffers automatically saved whenever MacVim lost focus. After quite a bit of work we were able to add automatic Vim saving support within tmux. It’s not as good as MacVim’s autosave, but it’s pretty close. Please see this Github pull request for how to set up automatic saving. (Note, I’ll update this post as the pull request progresses.)

Update 07/18/2012: Our tmux-vim automatic saving Vim plugin is available here: We’ve also integrated it into our vim-config configuration here:

Mouse Support

By default tmux has very little mouse support. We enabled significant mouse support within iTerm by customizing our .tmux.conf:

  • Selecting tmux panes
  • Resizing tmux panes
  • Scrolling

See this .tmux.conf template for more, but here’s the interesting section:

 # ~/.tmux.conf
 # Enable mouse support (works in iTerm)
 set-window-option -g mode-mouse on
 set-option -g mouse-select-pane on
 set-option -g mouse-resize-pane on
 set-option -g mouse-select-window on

Note that iTerm supports this configuration. We cannot vouch for Mac’s Terminal application’s level of mouse support.

OS-Level Copy-Paste

Highlighting with the mouse triggers tmux’s text selection, which is not OS X’s highlighting, and thus ⌘+c will not copy the highlighted text. Though we never fully solved this issue there is a workaround: hold down the ⌥ key (ALT/Option) while highlighting to trigger OS X’s selection — ⌘+c will now copy the text.

tmux selection — OS X will not copy this

Holding ⌥ — OS X will copy this!

Unfortunately this technique does not respect tmux’s panes and will select across the entire screen, but it’s better than nothing.

MacVim vs. Terminal Vim Keybindings

Why did MacVim and Vim have different keybindings if both use the ~/.vimrc file? The answer is the ⌘ key. To ease the transition from RubyMine and TextMate to MacVim we mapped many common ⌘-based keybinding which were unavailable in terminal-based Vim. My personal advice is to stay away from the ⌘ key if your team uses both MacVim and terminal Vim, but if that’s not possible at least make an extra <leader> KEY mapping for everything that uses ⌘.

Take a look at our sophisticated ~/.vimrc setup, including the keybindings file, where ⌘ bindings are paired with non- ⌘ keybindings.

Learning tmux-Specific Commands

There’s no way around this one. Though mouse support means one can avoid the tmux-pane selection and scrolling commands I highly recommend learning tmux well if you are using it consistently.

In practice we only use a handful of tmux commands often:

  • CTL+b % – new vertical split
  • CTL+b " – new horizontal split
  • CTL+b o – switch to other pane. Repeat to cycle through.
  • CTL+b ccreate new tmux tab/window
  • CTL+b n/p/l – switch to next, previous, or last tmux tab/windows
  • CTL+b [ – Enter scroll/copy mode

Here are a couple of fun ones:

  • CTL+b SPACEchange arrangement of panes. Repeat to cycle through various arrangements.
  • CTL+b wlist tmux tabs/windows
  • CTL+b ,rename tmux tab/window

Once your team gets the hang of it they might even prefer the multiple tmux-pane workflow to a multi-app, multi-tab setup.

It’s a Fast Paced World

With such a plethora of remote pairing software and configurations it’s impossible to keep up. We would love to hear about your own experiences remote pairing with tmux and how you might improve upon our own techniques and configurations. Please post comments and let us know what you think.

  1. I solved the copy/paste from `tmux` sessions over `SSH` by using X as a transport, and the [`xsel`]( command to put the `tmux` buffer into the X clipboard.

    Please note that you need `X11Forwarding on` in your `~/.ssh/config` file, X11 open on your Mac, Pasteboard Syncing enabled in the preferences and the following shortcut into your `~/.tmux.conf`:

    # Copy into the X clipboard
    bind-key C-c run ‘tmux show-buffer | xsel -pbi’

    After you select text in the tmux window, it is automatically copied in the tmux buffer, then when you’ll hit `C-b C-c` it gets copied in the X buffer by xsel, that gets forwarded over `SSH` to X11 on your mac, and synched in your OSX Pasteboard by

    The same can be accomplished in Vim, thanks to [this tip](, that boils down to these lines in your `~/.vimrc`:

    “Copy and paste from X clipboard –
    com -range Cz :silent :,w !xsel -i -b
    ca cz Cz

    Then you select in visual mode in Vim, hit `:cz` and the code goes through the same SSH/X11 pipe as described above :-).

    This is mostly useful when you use vertical split panes, and when you don’t want to copy Vim generated source line numbers :-).

  2. Joe Moore says:

    Marcello — Thanks! We’ll set that up and try it out.

  3. Mental note: Never work at PivotalLabs.

  4. A B says:

    Thanks for great article. Unfortunately topic was not covered, hope to get more information how to setup tmux for remote programming in next article.

  5. Evan Light says:

    Checkout vimux for even more awesomeness between vim and tmux (

  6. Henrik N says:

    In case you didn’t know, you don’t have to explicitly enter scroll mode. `ctrl+b, PageUp` (or `PageDown`) enters scroll mode and scrolls in that direction. E.g. `Enter` or `ctrl+c` exits scroll mode.

    The opt+select trick is neat. I’ve had mouse mode off because of the selection issue, but maybe I’ll try turning it on again. Though most of the time I copy within Vim using Vim, which of course stays within the current tmux pane. I use [reattach-to-user-namespace]( to map the tmux clipboard to the OS X clipboard, then use `,y` and `,p` [like so](

  7. Henrik N says:

    Oh, and I [blogged about Vimux]( (that Evan Light mentioned) just the other day. If you use Vim in tmux, it’s very nice for running tests and other things.

  8. Joe Moore says:

    Henrik — Thank you! We’ll definitely check out your links, especially Vimux.

  9. Jack says:

    Are you really using the default ctrl-b?
    I have mapped caps-lock to ctrl, and ctrl-a as the tmux prefix, as I’m sure many others have.
    It makes it very easy to type tmux commands, because you can just use a single gesture; hit caps-lock and ‘a’ at the same time with the appropriate fingers “locked” together.

    On a different level, facilities like panes and tabs should really be provided at the OS window-manager level. This would give a consistent set of commands for navigating and manipulating panes and tabs across apps, and even allow you to break-out panes into tabs or seperate windows, and vice-versa, at the window manager level.
    It’s a sign that the OS window managers aren’t good enough when each application has to implement the functionality within itself, leading to multiple incompatible layers.

  10. Joe Moore says:

    Hi everyone. Our tmux-vim automatic saving Vim plugin is available here: []( We’ve also integrated it into our vim-config configuration here: [](

  11. Ivan Torres says:

    This is what I use for autosave (.vimrc):

    ” Autosave
    set updatetime=1000
    autocmd BufLeave * update
    autocmd CursorHold * update
    autocmd InsertLeave * update

  12. Joe Moore says:


  13. Joe Moore says:

    Ivan — We have that, also, and it works great in MacVim, but do those setting trigger an autowrite when jumping from a Vim pane to another tmux pane? It doen’t for us. If it works for you maybe you could your .vimrc?

  14. Joe Moore says:

    There is a [lively discussion on Hacker News]( about this post in addition to the comments below.

  15. Matt says:

    You can also prevent tmux from using the alternate scrollback, therefore allowing you to use the native OS X scrolling in Terminal (inc. via mouse wheel) without needing to enter scroll mode.

    set -g terminal-overrides ‘xterm-256color:smcup@:rmcup@’

    Also, to prevent the terminal from resizing when the other client is NOT active (i.e. keeping your terminal as large as you prefer, more often):

    setw -g aggressive-resize on

  16. I use [reattach-to-user-namespace]( plus `pbcopy` to get the tmux buffer onto the OSX clipboard.

    bind y run-shell “reattach-to-user-namespace -l /bin/zsh -c ‘tmux show-buffer | pbcopy'”

    It doesn’t solve the remote problem, but it works well locally.

    You can also hit `v` while in tmux copy-mode to get visual block highlighting, ala using `C-v` in vim.

    ![tmux visual block highlighting](

  17. Joe Moore says:

    I will be speaking about remote pair programming at the Pivotal NYC office on 08/2012 at 12:45. Please join us or join the [](

  18. You can use “Ctrl+B, Z” to make your pane full screen. You can then use the Alt key copy and paste method.

    You can use the same command to bring your panes back.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *