Project–specific tmux sessions
The Problem
If you use a terminal multiplexer tmux, you might find yourself re–creating the same pane layout every time you want to start working on project. There are some tools that allows you to configure tmux sessions, like tmuxinator, but they never felt natural to me – why would I want to use YAML config file, when tmux has it’s own config syntax?
The Solution
Let’s put tmux.conf
files in project directories.
-
Set up Git globally to ignore
tmux.conf
files in the root of repository.Add this to
~/.config/git/ignore
(create the directory and the file if it doesn’t exist):/tmux.conf
-
Load
tmux.conf
from current directory, when starting a new tmux session.Add this to your
~/.config/tmux/tmux.conf
(or~/.tmux.conf
, if you prefer):if-shell -b '[ -e ./tmux.conf ]' { set-hook -g after-new-session 'source-file -q ./tmux.conf' }
-
If you have tmux, running, re–read the config file:
tmux source-file ~/.config/tmux/tmux.conf
Et voilà!
Examples
The one I use most often:
rename-session 'project-foo'
# Create short pane at the top of the window
split-window -vbdl 6
# Run npm install and `dev` npm script on the top pane
send -t "{previous}" "npm install && npm run --if-present dev" Enter
# Fetch latest changes in the main pane
send "git fetch" Enter
Here’s a much more involved example with multiple panes on top of the screen:
rename-session 'project-bar'
# | watch+build | serve | api |
# |-------------|-------|-----|
# | main |
split-window -vbl10 ; send 'npm install && nodemon -e "npm run build"' Enter
split-window -h ; send 'npm run serve' Enter
split-window -h ; send 'cd ../api && npm install && npm run dev' Enter
select-layout -E
select-pane -t'{next}'
send 'git fetch' Enter
Or even more complex one that waits for npm install
to finish before
running things in other panes:
rename-session 'project-zar'
set-environment -g SOME_IP_ENV_VAR '10.13.32.3'
# | dev | storybook | api |
# |-----------------------|
# | main |
# dev
split-window -vbl10
# storybook
split-window -h
send -t 0 '\
npm install; \
tmux send -t0 "npm run dev " Enter; \
tmux send -t1 "npm run storybook --no-open" Enter; \
' Enter
# api
split-window -h
select-pane -t'{next}'
send 'cd ../api' Enter
send 'git fetch' Enter
send 'npm install && npm run dev' Enter
select-layout -E
# main working area
select-pane -t'{next}'
send 'git fetch' Enter
Default configuration
You can go very complex, but most of the time you will probably want to
use the same config for most of your projects. But why copy the same
tmux.conf
to each directory?
Let’s expand our after-new-sesssion
hook in tmux.conf
. If
./tmux.conf
is not found, it will detect if project is using npm
or
yarn
and run run dev
npm script in the top pane. While we are here,
let’s use current directory name as a session name.
set-hook -g after-new-session '\
run-shell "tmux rename-session \"$( basename \"#{pane_current_path}\" \)\""; \
\
if-shell -b "[ -e ./tmux.conf ]" { \
source-file ./tmux.conf; \
} { \
if-shell -b "[ -e ./yarn.lock ]" { \
split-window -vbdl 6; \
send -t "{previous}" "yarn install && yarn run --if-present dev" Enter; \
send "git fetch" Enter; \
} { \
if-shell -b "[ -e ./package.json ]" { \
split-window -vbdl 6; \
send -t "{previous}" "npm install && npm run --if-present dev" Enter; \
send "git fetch" Enter; \
}; \
}; \
}; \
'