Tmux Only For Long-Running Processes

@croaky and Thoughtbot crew,

I’m curious what the breakdown is at Thoughtbot between heavy Tmuxers (which I’ll assume is the @joshclayton s and @christoomey s of the world, doing everything in their workflow in Tmux, splitting panes and using that prefix key hundreds of times a day), Tmux avoiders (the @jferris camp, who are fed up with less than ideal copy-paste behavior), and the folks just using Tmux to manage processes that need to be backgrounded as described in the blog post.

When I decided to learn Vim last summer I ended up learning Tmux at the same time, and struggled with it to start (as I’m sure most Tmux novices do), but eventually got more comfortable. The missing workflow feature I wish I could figure out a way to set up test output to a second monitor (maybe using a pipe to another tty) but retaining the ability to scroll back. I love using a second monitor for test output, but then I can’t jump to it using tmux commands since it’s actually a different terminal.

But I remain curious about the breakdown in Tmux use at Thoughtbot.

Hey @geoffharcourt, you are correct in your assumption that I spend all day in Tmux. I haven’t gone all the way to having tmux load whenever I open a new terminal, but I’ll likely update this soon.

As for your issue with test output, I had a thought about using two terminal sessions, one in Terminal.app and one in iTerm to allow Cmd-tabing between them. Each would be connected to a tmux session (different sessions) and they could chat with tmux send-keys. Rough setup:

# In secondary Terminal.app window
tmux new-session -s tests

# In main iTerm window
tmux new-session -s working
tmux send-keys -t tests 'test command' 'C-m' # 'C-m' ~= enter keypress
# test output will now show in Terminal.app window, in tmux w/ srollback

Not sure if that will cover everything you are looking for, but might be a start?

1 Like

I don’t think I know any devs here that aren’t using tmux at least a little. Even @jferris and I converted not long ago.

I use it fairly casually - vim in one window, shells in others. No splits or sending commands. I don’t think anyone uses it less than that, and the average thoughtbotter probably uses it a little more.

Hmmm, I tried that and the result was very… interesting.

@geoffharcourt I resisted for a while but once I noticed the gains in efficiency @joshclayton and @christoomey had, I converted and won’t go back. I’ve had several coworkers, employees, and pairs since then make the switch as well. So obviously my opinion is that it’s well worth it

One of the greatest benefits, for me, has been the ease of (per) project setup and environment bootstrapping. Things like tmuxinator help quite a bit but I’ve found that tmux has this stuff baked in, negating the need for the tmuxinators of the world.

Wynn Netherland has a blog post detailing how he configures his projects that’s very similar to how I do it. I place a script in ./bin/tmuxify per project as a convention and never think about what windows, panes, and processes I need to have up and running.

Example script from our iOS project:

#!/bin/zsh

tmux has-session -t change.ios 2>/dev/null

if [ "$?" -eq 1 ] ; then
  echo "Project not found. Creating and configuring."

  # Set up primary window
  tmux new-session -d -s change.ios
  tmux rename-window "vim"
  tmux send-keys -t 1 'vim .' Enter
  tmux split-window -h -p 25
  tmux select-pane -t 1
else
  echo "Project found. Connecting."
fi

TERM=screen-256color-bce tmux attach-session -t change.ios

Hope this helps!

2 Likes

For running tests in a second monitor check out vim-turbux. I back it with vim-dispatch which is totally awesome in it’s own right. I use this setup to run tests on my iPad via iSSH to get a dual monitor setup you can bring to a coffee shop.

I recently converted to using tmux for a few reasons:

  • Its keyboard support is better. Being able to quickly copy a line from the output is really helpful. Being able to quickly create panes is nice, too.
  • Its integration with Vim is really good. Tools like dispatch.vim and tslime are nicer than the hacks I’ve used for integrating with Terminal.app.
  • I try to use what most people at thoughtbot are using until there’s a strong reason not to. This makes it easier for me to pair with people, get new ideas from others, and share new ideas of my own. Most people at thoughtbot are using tmux.
1 Like

@christoomey, the first time I gave these settings a try I got some weird results that didn’t work, but I returned to them today and they work fantastically well. Thanks very much for the tip, this has allowed me to leverage an almost completely keyboard-driven setup on two monitors with the occasional mouse-browsing when I have a long, messy stacktrace (such as when I’m diagnosing an API response).

@christoomey, you mentioned that you run the second terminal in Terminal.app. I’ve been using witch for a while to accomplish a similar thing while only using iTerm.

witch introduces Option-Tab as a great Command-Tab-like shortcut, except it treats different windows of the same app as separate items you can toggle through.

Hey @geoffharcourt, glad this is working out for you! I actually run with a single iTerm window myself, and I send test runs to a second tmux pane displayed in the same window. My suggestions were particular to the workflow you were outlining, wanting the output on a different monitor.

As for the window switching, you should be able to use Cmd` as well to cycle between windows of the same application.

@geoffharcourt I would say the majority are using a heavy Tmux workflow on most apps. Even I use it for some projects, such as one right now that I work on a few days a week, with the following Tmux windows open:

  • foreman start web for the Rails app, which is used as a standalone API for the work I’m doing
  • rails console
  • tail -f log/development.log
  • vim . within the Rails app
  • vim . within the Backbone app, which is a separate repo

I also have a split iTerm window underneath running foreman start for the Backbone app, which runs a Procfile that has three processes:

dev: node_modules/.bin/coffee server.coffee
watch: make build & wait && node_modules/.bin/gulp watch
karma: node_modules/.bin/karma start test/jasmine/karma.conf.js

All of that is to make a couple of points:

  • Different apps involve different amount of setup and complexity in development, debugging, and testing
  • Different Vim, Tmux, and iTerm workflows work better for different apps

So, it’s not necessarily like “Josh, Chris, etc. are heavy Tmux users and Dan, Greg, etc. are lightweight Tmux users.” Different people might use different workflows on different apps. For an app with a separate JavaScript front-end repo and separate HTTP backend, I find it faster to use a window/pane workflow so I can maintain state a little longer. My “long-running processes” start to include Vim sessions in both apps because I’m switching a lot between those codebase throughout the day.

Hopefully my “Tmux Only For Long-Running Processes” article was clear about the use cases for the long-running workflow, and that it is only one style of Tmux workflow.

I like to start with that workflow, see if it becomes painful, and graduate to a heavier workflow for apps that need it. I end up using that lightweight workflow for more apps than people might expect, which was part of my motivation for writing the article. I think Tmux is great, but I like the philosophy of building up to heavier weight tools and techniques only when necessary.