Journal Archives About Books Talks

Switch context with less friction using stateful tmux workspaces

As developers, we are well aware of the evils of context switching. Hopping between software projects often means making the mental transition between programming languages and business domains. But hop we must.

Getting your tools to switch as fast as you do can be even harder. For this problem, tmux has changed the way I work.

What is tmux?

Think of tmux as a window manager for your terminal. Instead of terminal tabs, you can run multiple terminal sessions, stitched together into a single terminal window. Evan Travers recently wrote a great introduction to tmux sessions, windows, and panes, the building blocks of what I call tmux workspaces.

Scriptable workspaces

When I sit down to hack on a software project, I need some combination of the following:

I use the venerable Vim as my text editor, so each one of these tools is terminal-based. Since tmux is scriptable, I can unfurl instant workspaces for projects according to own my personal workspace preferences:

~/code/pengwynn/blog master
❯ mx

Running mx from the project root, I build a workspace for working on this blog that includes windows for vim, a shell prompt, a console using racksh, and Foreman to start the server for local preview.

workspace

The script will look for a tmux session based on the current folder name. If no such session is found, it creates one:

# look for a tmux session based on folder name
if ! (tmux has-session -t "$SESSION" >/dev/null 2>&1); then
  if [ -x "$PWD"/.tmux ]; then
    "$PWD"/.tmux "$SESSION"
  else
    tmux new-session -s "$SESSION" -n editor -d
    tmux send-keys "$EDITOR" C-m #':CtrlP' C-m
    tmux new-window -n shell -t "$SESSION"
    _safe_window console script/console
    _safe_window server script/server

    tmux select-window -t "$SESSION":1
  fi
fi

If the folder has a .tmux file, it will run that script to create a custom layout for that project, otherwise it will create four stock windows. It will always create windows for my $EDITOR and a shell. For projects that have console and server scripts, as most of my projects do, the script will create windows for those as well.

If a session already exists, the script will instead attach to the previous session, letting me pick up where I left off.

if [ -z "$TMUX" ]; then
  tmux attach -t "$SESSION"
else
  tmux switch-client -t "$SESSION"
fi

tmux's scriptable command line interface lets me build workspaces quickly, but it's tmux's stateful sessions that make it truly remarkable. Knowing I can quickly reconstruct a workspace makes context switching cheap. Detaching from a workspace, letting it run in the background, makes context switching almost free. I can even jump between workspaces using tmux's built-in session chooser:

screencap-2

It has forever changed the way I work.

# Posted on