Monday, May 21, 2012

tmux for Ruby on Rails

A couple of weeks ago I stumbled on tmux as a way to manage the proliferation of terminal windows when doing Ruby on Rails development.

My Rails 3.2 development environment is a Ubuntu guest OS running on a VirtualBox VM hosted on my Windows 7 desktop. Since I wanted to stay on my Windows desktop most of the time, rather than interact with Ubuntu through the somewhat laggy Virtualbox display, I would ssh into the Ubuntu guest using a Cygwin terminal (mintty). And being a good ol' Rails fanboy, I started using Vim and all its plugins as a really nice Rails/Ruby editor.

However: once I got a couple of Vim editors, a rails server, a rails console, a log file tail, and a Guard or RSpec session all running at once, plus the Ruby on Rails tutorial and Rails app open in browser windows, my Windows desktop started to look like Mah Jongg game in full swing. I was spending more time tabbing around looking for the right window than actually learning anything!

Tmux brings some order to that chaos. According to the tmux man page, "tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen." After some tweaking and fiddling, this is the layout I've settled on:


I've split a single "window" named "rails" into to three "panes": top-left I have Guard running Rspec tests, bottom-left I have the Rails server, and at right my main Vim editing session. On a second window named "logs" I have a tail on the Rails server log file.

The cool thing about this is that it all starts up automatically when I run a shell script that instructs tmux to set up the windows and start all of the processes I need for my Rails development session. Tmux will even maintain the session in case my terminal connection dies.

I relied on these excellent introductions to TMUX to get started:
Here's the shell script I cobbled together to create that session:

#!/bin/sh
# ====================================================================
# This is the tmux configuration I use for setting up my Ruby on Rails
# Tutorial session
#
BASE="$HOME/sites/sample_app"
cd $BASE
tmux start-server
# new-session creates first window named 'rails'
tmux new-session -d -s sampleapp -n rails
# split window 'h'orizontally (into two vertical panes)
tmux split-window -t sampleapp:rails -h
# select the left-most pane
tmux last-pane
# split this pane 'v'ertically (into two horizontal panes)
tmux split-window -t sampleapp:rails -v
# create a second window for 'logs'
tmux new-window -t sampleapp:2 -n logs
# start a vim editor in the left-most vertical pane
tmux send-keys -t sampleapp:rails.2 "cd $BASE; vim" C-m
# widen the vim editor pane by 20 cells
tmux resize-pane -L -t sampleapp:rails.2 20
# run guard -c clears shell after each change
tmux send-keys -t sampleapp:rails.0 "cd $BASE; guard -c" C-m
# start rails server
tmux send-keys -t sampleapp:rails.1 "cd $BASE; rails s" C-m
# start logging
tmux send-keys -t sampleapp:logs "cd $BASE; tail -f log/*.log" C-m
# select the vim pane in the rails window
tmux select-window -t sampleapp:rails
tmux select-pane -t sampleapp:rails.2
# make the tmux session active
tmux attach-session -d -t sampleapp
view raw rumble.sh hosted with ❤ by GitHub


And my .tmux.conf file:

# bind tmux commands to Ctrl-A for Vim compatibility
# and better ergonomics :)
unbind C-b
set -g prefix C-a
# Ctrl-A Ctrl-A switches to last window
bind C-a last-window
bind a send-prefix
# Rebind Ctrl-| to split the window horizontally [ | ]
# inserts a split vertically
unbind %
bind | split-window -h
# Bind Ctrl-- (dash) to split the window vertically [ --- ]
# inserts a split horizontally
bind - split-window -v
# start window numbering at 1
set -g base-index 1
# set the status bar look 'n feel
set -g status-bg black
set -g status-fg white
set -g status-left '#[fg=green]#H'
# enable aggressive resize when using multiple clients
# setw -g aggressive-resize on
# vim key bindings
setw -g mode-keys vi
# highlight active window
set-window-option -g window-status-current-bg red
# tell tmux to use 256 colors
set -g default-terminal "screen-256color"
view raw .tmux.conf hosted with ❤ by GitHub


4 comments:

  1. Any idea how to get the red/green from guard&rspec into the tmux status bar?

    ReplyDelete
    Replies
    1. Hi Gordon, sorry, no, I don't know, but that's a very cool idea! Next time I'm messing around with tmux, I'll have a look.

      Delete
  2. I'm new to this .. can you please tell me how do you run your rumble shell script?
    Thanks!

    ReplyDelete
    Replies
    1. Hey Ketan, thanks for commenting on my blog post! This one is an oldie, and I haven't run tmux or rails or any of that stuff for a loooong time! As far as I can remember, it should "just run" in a bash shell. I wish I could help you more. I'd suggest you copy the script and the tmux config file to your environment and play around with it. THat's how I developed it in the first place.

      Best of luck to you!
      Philip

      Delete

Note: Only a member of this blog may post a comment.