At Braintree we take our tools seriously. We are always looking for ways to improve our toolchain to make us more productive. Because we pair-program full-time, we have a standard set of dotfiles so that any two developers can work together without having to fumble with different keyboard shortcuts or aliases. For the past year we have been using vim as our text editor, running inside tmux. Today I'm going to talk about some of the ways we use vim and tmux together to make development easier as well as introduce a new vim plugin called vimux that we have been using successfully at Braintree.
We have been using console vim running inside tmux for close to a year (our dotfiles can be found on GitHub). Tmux is a terminal multiplexer that allows us to create sessions that act roughly like terminal windows, create windows that act like tabs, and create panes that let us split tmux windows horizontally and vertically. Since multiple people can connect to a tmux session at a time it gives us the ability to pair on remote machines or even from separate locations.
Some of these features may sound familiar if you have used GNU screen before. While screen offers many similar features as tmux, we have found some of tmux's features more essential to our workflow.
Being able to vertically split panes alone is an important enough feature to give tmux a try. When we are working on any remote server we keep a tail of the logs on one side while we run commands on the other so we can instantly get feedback if something changes. Tmux also has a consistent command interface that has great documentation, which makes managing our configuration and scripting new commands easy.
These are just a few of the many reasons we have found tmux to be an integral tool at Braintree. If you're unfamiliar with tmux I added a number of useful links to get started at the bottom of this post.
One problem we have faced using vim at Braintree was finding a simple way to run ruby tests and get feedback. Until recently we have been using ruby_focused_unit_test_vim written by another Braintree developer, Drew Olson. While ruby_focused_unit_test_vim works well, it blocks the entire vim process while executing the test. We have found this to be a limitation of vim itself.
I have tried multiple solutions to solve this problem. One thing that I tried was using a terminal emulator embedded in vim called conque shell and another was tslime.vim with turbux.vim to run tests using a tmux pane. However nothing gave me the uninterrupted workflow I was looking for. I found tslime.vim interesting because once you had it running it not only made running ruby tests simple but working in other languages productive as well. When I started using tslime.vim more frequently, I was frustrated with bugs and the fact it wasn't optimized for having a smaller pane in the current window to execute commands in, which is my primary use case.
With these issues in mind, I started working on my own vim plugin that would work similarly to tslime.vim, which I named vimux. Vimux at it's core is a vim function
RunVimTmuxCommand that executes commands you pass to it, in a 20% horizontal split pane, inside your current tmux window that vimux will create for you if it does not exist. You can add more split panes, resize them, move them around and vimux will consistently execute commands in the original pane. Vimux provides a few other functions and options that make it easy to create language/platform specific vim functions to run tests and also to compile code or execute chunks of code in a REPL. With the simple functions provided we've found vimux to make development in multiple environments more productive. You can check out vimux-ruby-test, written by another Braintree developer, Paul Gross, which provides vim functions to run ruby tests with vimux. You can also check out my erlang_mappings.vim file to see examples of projects built on top of vimux.
The disadvantage of using vimux over some other plugins that print command output directly into vim is sometimes you have to leave vim. While I thought this would be a disadvantage when I first started using vimux, I've now found that it's much better to let vim do the job it's best at, which is editing text. Using a tmux split gives us a complete shell where we can run commands like rake tasks or tests. We can also have a REPL running where we test out methods and objects we just wrote. The most important aspect of vimux is it lets you do these things without ever interrupting your use of vim. Vim is completely unblocked and you can continue to edit code while the command finishes. These are just a few of the ways you could use vimux today. What makes me most excited is to see the new ways people will use vimux to create functions and plugins to do other things I have never thought of.
You can download a zip or tar of the latest version of vimux and move
plugin/vimux.vim from the unarchived folder into
~/.vim/plugin/ or if you use pathogen you can move the unarchived folder into
Once you have the vimux installed as a vim plugin you should be able to start vim and run
:PromptVimTmuxCommand. If vimux was installed correctly you should see
Command? You can then type any command to be executed and watch vimux create a pane for you.
After you have vimux up and running, I would recommend adding a keyboard shortcut for
RunLastVimTmuxCommand in your vim config. Between these two commands you can be very productive in whatever language or platform you're working on.
Here is an example of some keyboard shortcuts for vimux:
" Prompt for a command to runmap
rp :PromptVimTmuxCommand " Run last command executed by RunVimTmuxCommandmap rl :RunLastVimTmuxCommand " Inspect runner panemap ri :InspectVimTmuxRunner " Close all other tmux panes in current windowmap rx :CloseVimTmuxPanes " Interrupt any command running in the runner panemap rs :InterruptVimTmuxRunner
You can read more about vimux by checking it out on GitHub. We're always looking for contributors to improve the vimux project or build other projects on top of vimux for a specific language or platform.
- A Tmux Crash Course via Thoughtbot
- TMUX - The Terminal Multiplexer (Part 1) via Hawk Host Blog
- Episode 0.7.3 - Tmux with Brian Hogan and Josh Clayton via The Changelog
- Tmux via Arch Linux Wiki
- tmux: Productive Mouse-Free Development a Pragmatic Programmers book