My development workflow (vim+tmux+terminal+alfred) Awesomeness
28 Aug 2014For a while now I wanted to share the way I work on Ruby/Rails projects. How I go about handling the multiple processes you need, editor, running tests and other stuff.
Since the way I work is not too common, I think it’s worth sharing and letting people know about it.
Everything in the terminal
100% of the work I do is done inside the terminal, I don’t switch back and forth between programs or between windows.
The only way I really exit the terminal is to Google something or to see how something looks on the web (although that is rare for me).
Since I usually don’t do front-end work, I stick to the terminal for backend work and tests that verify what I do.
Focus on the keyboard and automation
Unless I exit the terminal, I don’t use the mouse at all, I really just use the mouse for browsing online. I don’t treat this as a religion it’s just really convenient for me, I don’t measure every millisecond to say whether it’s faster or not in the long run, it just comes natural (with time).
For example, copying something from the error in the spec output to Google is also done using the keyboard.
Common language
Just to have a common language throughout this post, I want to put a few variables here that will make things clearer.
C
=>CTRL
{tmux_leader}
=>C-a
{vim_leader}
=>,
Not Rails specific
The worflow is definitely not Rails or even Ruby specific, I work the same way with Chef projects (Devops) and even writing this blog post is done using Vim in the terminal.
Tools
- Tmux (+Tmuxinator)
- Vim
How it looks
Here’s a screenshot of what it looks like
As you can see right away the screen is split into multiple parts. I use Tmux to do this (I will go deeper into this in a bit).
Explaining the sections of the screen
The screen is divided into 2 main parts on the “main” tab.
The top part is where code is being edited, I use vim to do all of my work. Whether it’s Ruby, Javascript, CSS or any other language.
The bottom part is also divided into two parts, the left side is rails console (if it’s a rails project) or irb if it’s a Ruby project.
The right side is a pipe reader, basically just a tail of some log (I will explain further later on)
Tabs
Almost every project I have requires multiple tabs, each tabs runs a different process, usually these processes just need to run in the background for the project to be useable.
This of a rails project (not your basic one) you will need:
- Console
- Server
- Foreman
- Spork
- Guard
- SSH into a server of some sort
- Vagrant machine running a service
- add yours here…
Everything needs to run when you boot up the project.
Once you have all the tabs open, you can switch between them by {tmux_leader}+tab_number
, do in order to see the rails server log all I need to do is `{tmux_leader}+2
Adding tabs
Once you are working on a project, you sometimes need to add a tab say for example SSH’ing to a server, tailing a log or anything else really.
That is also super easy, you just do {tmux_leader}+c
, you can also rename the tab to know what’s on it with a glimpse to the status bar, just do {tmux_leader}+,
input the name and you are done
Panes
Switching between panes is also a breeze, you just move about as you’d move in vim, using the same navigation keys. {tmux_leader}+j
will move you down.
I usually resize panes for readability (when I am using the smaller screens like laptop or 24” screen at my sitting desk). Resizing is using the same keys as navigation but using the capital letter. {tmux_leader}+J
will resize down (maximize the upper screen).
Adding/splitting more panes
My home office standing desk is home to my 30” Dell screen (go buy one now), so I have a ton of screen real estate.
Sometimes I split into 6-7 vim buffers and also have 3-4 tmux panes (Heavy debugging sessions for example).
Splitting with tmux is really intuitive {tmux_leader}+-
with split horizontally and {tmux_leader}+|
splits vertically.
The status bar
Tmux status bar (or footer) is usually a place where you have all the info you need. I use tmux-powerline in order to configure this.
Anything that is a bash command can be a part of the status line, you can view your email count, the time, some API command from your server you curl to, really anything.
For me, I have experimented with lots of stuff to minimum, I just use the time (since I am using full screen more), the tabs and the session name, really noting more.
There’s a great blog post about configuring your status line (without poweline) here.
Automating projects start
It can be a real pain to start a rails project, when you start your computer or when you switch between projects.
People usually miss a part or don’t run specs because spork is not running and other lazy-driven excuses.
I basically automate every project using Tmuxinator
Here’s an example of how I configure the Gogobot project
# ~/.tmuxinator/gogobot.yml
# you can make as many tabs as you wish...
name: gogobot
root: ~/Code/gogobot_rails3/www_rails
windows:
- main:
layout: main-horizontal
panes:
- vim .
- ./read_pipe.sh
- server: rm -f log/development.log && rm -f log/test.log && rails server thin
- foreman: bundle exec foreman start
- spork: bundle exec spork
- guard: bundle exec guard -G GuardFileOnlyJasmine
So now, in order to start the project I just run tmuxinator start gogobot
and I am done, it will start up everything and I can start working.
Configurations
Both my vim config and the tmux config are public, you can fork/add/comment or just use them if you’d like
Developer workflows
Before starting this post, I thought to myself, will this be another tmux-vim-shortcut post?
My answer to myself was: “If you don’t share common workflows, it will be exactly that”, I remember before switching tim tmux+vim and seeing those posts, I had lots of questions popping up, like: What about copy+past, what about clipboard, scrolling, selecting, what about running tests etc…
I have identified some workflows that I had a problem with and I will try to clarify these here as best I can. Hopefully this will carry you over the edge of testing this method out.
Running tests
The right side you can see ./read_pipe.sh
, this is an awesome trick I picked up from Gary Bernhardt (@garybernhardt).
Usually, when you run specs inside vim or any other IDE, the specs break your coding cycle, you have to wait for the specs to finish in order to see the screen where your code is.
I found that this is very distracting, I want to keep editing code while specs are running, even if it’s just “browsing” the code, going up/down in the screen, I don’t even want to wait a single second for the specs to finish.
Here’s what it looks like to run specs for example (I use {vim_leader}+;
to run a single spec and {vim_leader}+'
to run a full specs file))
When the specs are running, I can continue with the code, browse to other files and do basically whatever I want.
One more awesome thing about it is that the pipe file can run in any other terminal, so basically I can put it on another tab, another window or anywhere I’d want to.
I usually use it this way: I focus on vim full screen (using tmux focus mode {tmux_leader}+z
), and the specs are running in the background, then, when I want to look at the output, I can just snap out of tmux focus mode and look at the specs output.
Checking some error in Google
A really common workflow with developers is needing to check something on Google from a test output, error or even code. That’s likely something you do dozens of times a day without even thinking about it.
Here’s what I do in order to achieve this.
First, I move to “copy mode” in tmux. I do this by hitting {tmux_leader}+[
.
This puts tmux into copy mode and I can navigate up/down or anywhere on the screen, the great thing about it is that it’s actually using the same navigation commands like vim.
After I select the text I want, I hit CMD+ENTER
in order to pull up Alfred. paste the text and hit ENTER
.
Here’s what it looks like.
Copy + Paste interface
Most of you probably take this one for granted, but having tmux+vim+osx clipboards talking together is really awesome, I can’t really tell you how much better my life became after making this happen.
Also, as you can see I am using Alfred. One of Alfred’s best features is the searchable clipboard history, this means I can search through my vim copy history in a snap.
Working with git
I have found that most commit messages people are making are one liners. I researched my commit messages and I found that there was a point in time where I started to write better longer commit messages. I think this workflow really pushed me towards that.
Using vim, I have 2 shortcuts for git I use all the time.
{vim_leader}+gs
will show a git status screen where I can see all the files that have not been stages and I can stage/unstage files right from vim. (This is done using vim fugutive)
This is what it look like:
You can read more about fugitive in this github repository.
The best thing about fugitive is that you stay inside vim, I have found that staying inside the editor allows you to write more comprehensive commit messages, copy some code or some documentation into the commit message and be more fluent.
Pair programming (Remote or on site)
If you are following me on any social network, you probably already know that I have been working from home for about 5 years now.
This means that usually when I pair program with someone, I am doing it remotely, usually this certain someone is 5,000 miles away.
Pair programming and screen sharing is such a pain without tmux and vim.
When you pair using tmux and vim everything works really well, first, you simply ssh into a machine, just like you do to one of your servers
There’s no rendering involved, so you don’t really need a monster internet connection.
Also, your pair has everything, just like you do, they have the console, the test output, all right there with a click of a key.
You can both SSH together into another machine, you can explain something, view a log together, it’s amazing.
Conclusion
I am really enjoying my development workflow, it works perfectly for me and I strongly believe it can work for anyone.
Using the right configuration of vim+tmux can really smooth out the transition to this workflow and I strongly recommend it.
Like I already mentioned above here, I don’t treat working with the keyboard alone as a religion but it is really faster (at least feels faster). Not switching between screens in order to see some output or to input some kind of command is really convenient.
You can look into (and setup) my configuration, it’s a very nice jump into the world of working completely in the terminal.
If you have any questions/comments please feel free to leave those down here and I will do my best to help out.