Automatic windowed terminal setup with tmux
This is about writing a script to automate your development environment.
A common problem: you want multiple programs to run concurrently, e.g. simultaneously running your unit tests and bundling your frontend, both in watch mode.
One straightforward solution: the concurrently
package on NPM.
But this solution has a notable limit: the programs are no longer interactive, i.e. they cannot respond to key presses. For example, you wouldn’t be able to use Jest’s interactive snapshot mode.
How do you overcome this? Nominally, you would resort to manually launching each program in a separate terminal window, pane, or tab, but this can be automated with tmux
the terminal multiplexer!
This post assumes familiarity with tmux
. Check out my blog post on tmux basics
.
Demo
Code
#!/usr/bin/env bash
# The next set of commands creates 6 panes
tmux split-window -h # `-h` for horizontal split
tmux split-window -v -l '33%' # `-v` for vertical split, `-l '33%'` for
tmux select-pane -t 1 # switch the active pane (use command `tmux display-panes` for debugging)
tmux split-window -v
tmux select-pane -t 0
tmux split-window -v
tmux split-window -v
tmux select-pane -t 0
tmux split-window -v
# The following code block issues commands to the 6 panes
tmux send-keys -t 1 'npm run dev' Enter
tmux send-keys -t 2 'npm run test' Enter
tmux send-keys -t 3 'npm run lint' Enter
tmux send-keys -t 4 'npm run psql' Enter
tmux send-keys -t 5 'npm run tailwind' Enter
tmux send-keys -t 6 'npm run storybook' Enter
Use the command tmux display-panes
(or the equivalent shortcut C-b q
) to show the pane numbers for prototyping.
Usage
First, run tmux
. Then, from inside tmux
, run the script: . ./scripts/dev.sh
.
Another helpful tip…
Automatically restart long-running processes every x minutes to remedy resource leaks
Example:
while true; do timeout 10m npm run tsc --watch; done
The timeout 10m <command>
wrapper kills the process if it runs for more than 10 minutes.
The infinite while loop restarts the process when it exits or crashes.
I originally developed this technique because Tailwind CSS would occasionally slow down my computer.