Update 07/18/2012: We have added tmux-vim autosaving support as a Vim plugin. It’s available here: https://github.com/pivotal/tmux-config
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
sshaccess you’re good to go
Disadvantages vs. Desktop Screen Sharing
sshaccess 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.
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.
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: https://github.com/pivotal/tmux-config. We’ve also integrated it into our vim-config configuration here: https://github.com/pivotal/vim-config.
By default tmux has very little mouse support. We enabled significant mouse support within iTerm by customizing our
- Selecting tmux panes
- Resizing tmux panes
.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.
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 ⌘.
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 c– create 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 SPACE– change arrangement of panes. Repeat to cycle through various arrangements.
CTL+b w– list 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.