Scripting layouts with send-keys

tmux · Advanced · 12 min

A script that rebuilds your project workspace in one command saves minutes every day and documents how to run the project.

Every tmux command can be run from a shell script, which lets you build a whole workspace reproducibly.

The pattern:

  • Create the session detached with new-session -d -s name -n firstwindow -c dir.
  • Add windows with new-window -t name -n other -c dir and panes with split-window -t target.
  • Start programs by typing into panes with send-keys -t target 'command' Enter. Enter (or C-m) is a key name; send -l for literal text.
  • Finish with select-window and attach.

Targets (-t) name what a command acts on: session, session:window (window by index or name), session:window.pane. After split-window, the new pane is the active one, so the next send-keys -t session:window goes to it without needing pane numbers.

Make the script idempotent: if the session already exists, just attach. tmux has-session -t name returns a non-zero exit status when it does not exist.

Alternatives to send-keys: pass the command directly, new-window 'htop', but then the window closes when the program exits (unless remain-on-exit is on). send-keys instead types into a shell, so the shell survives and you can rerun the command. Tools such as tmuxinator and tmuxp generate the same commands from YAML.

Example

#!/usr/bin/env bash
S=dev; DIR=~/code/shop
if tmux has-session -t "$S" 2>/dev/null; then
  exec tmux attach -t "$S"
fi
tmux new-session -d -s "$S" -n editor -c "$DIR"
tmux send-keys   -t "$S:editor" 'vim .' Enter
tmux new-window  -t "$S" -n run -c "$DIR"
tmux send-keys   -t "$S:run" 'npm run dev' Enter
tmux split-window -v -t "$S:run" -c "$DIR"        # new pane becomes active
tmux send-keys   -t "$S:run" 'npm test -- --watch' Enter
tmux select-window -t "$S:editor"
exec tmux attach -t "$S"

Remember

  • new-session -d builds a session without attaching
  • Targets: session:window.pane; windows can be named
  • send-keys 'cmd' Enter types into a pane's shell

Watch out for

  • Forgetting Enter at the end of send-keys, so the command is typed but never run.

Check yourself

  1. Why use `send-keys 'npm run dev' Enter` instead of `new-window 'npm run dev'`?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: man.openbsd.org/tmux.1#COMMANDS