Digging into dotfiles:
tmux
Paul Esch-Laurent
(live) slide deck: uly.io/talk/tmux
my dotfiles: uly.io/dotfiles
me: p@uly.io
What?
terminal multiplexer
allows multiple terminal sessions to be accessed simultaneously in a single window
here's a screenshot

Matrix effect: uly.io/aq
common commands
listing, creating, using, and killing sessions
-
tmux ls # list
-
tmux new -s <name> # create
-
tmux attach -t <name> # attach
-
tmux kill-session -t <name> # kill
tip: "attach" is aliased as "a", omit "-t" to attach to last session
Bindings: the basics
tmux is based on the <prefix>, which defaults to
ctrl + b
-
<prefix> c # create new window
-
<prefix> d # detach from session
-
<prefix> x # kill current pane
-
<prefix> & # kill current window
-
<prefix> [0..9] # switch to window [0..9]
windows (arranged in tabs) contain panes which are partitions within the current window
your tmux config
the config lives in ~/.tmux.conf
touch ~/.tmux.conf
let's change the <prefix> bind
... and allow for easy config reloading
# Rebind prefix to 'C-a'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# Easy config reload (<prefix> r)
bind r source-file ~/.tmux.conf \; display "Reloaded!"
N.B. ctrl + a is popular, I personally use ctrl + \ (swapped ctrl & caps-lock on keyboard)
splitting panes
you'll probably want to be able to split panes
-
<prefix> " # split vertically
-
<prefix> % # split horizontally
# Use | and - to split panes
unbind '"'
unbind %
bind | split-window -h
bind - split-window -v
that's unintuitive to use, let's change it
growing panes: moving & resizing
by default, you can move between panes with
-
<prefix> <U|D|L|R> # arrow keys
# Move between panes with M- h, j, k, l (no prefix)
bind -n M-h select-pane -L
bind -n M-j select-pane -D
bind -n M-k select-pane -U
bind -n M-l select-pane -R
# Resize panes with H, J, K, L (with prefix, repeatable)
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
I prefer to keep my fingers on the home-row, let's use the vim-style h, j, k, l bindings
(for resizing panes, too)
N.B. "M" is the <Meta> key, typically Alt/Option
hook, line, & sync'r
let's say you want to do something across all your panes in a window (in sync)...
# Toggle synchronize-panes (no prefix)
bind -n M-I setw synchronize-panes
- `source` your shell profile in all panes
- `export` an env variable in all panes
- `cd` to the same directory in all panes
let's talk about windows
let's make windows a bit better
# Start window index at 1 (match keyboard order)
set -g base-index 1
# ... and the same for panes
set -g pane-base-index 1
# Re-number windows sequentially after closing them
set -g renumber-windows on
# Prevent shell from remaining windows after setting it once
set -g allow-rename off
- start window index (windex 😉) at 1
- re-order them if you kill one
- prevent the shell from renaming
but i wanna use my mouse?!
scrolling, selecting, resizing, whatever; can do
# Increase scrollback
set -g history-limit 10000
# Enable mouse support
# < 2.1
if-shell -b '[ "$(echo "$(tmux -V | cut -c 6-) < 2.1" | bc)" = 1 ]' \
" \
set -g mode-mouse on; \
set -g mouse-resize-pane on; \
set -g mouse-select-pane on; \
set -g mouse-select-window on; \
"
# >= 2.1
if-shell -b '[ "$(echo "$(tmux -V | cut -c 6-) >= 2.1" | bc)" = 1 ]' \
" \
set -g mouse on; \
bind -n WheelUpPane if-shell -F -t = \"#{mouse_any_flag}\" \"send-keys -M\" \"if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t=; copy-mode -e; send-keys -M'\"; \
bind -n WheelDownPane select-pane -t= \\; send-keys -M; \
"
N.B. with mouse mode, you need to hold Shift (Option on macOS) to select text
persisting sessions
save & restore sessions, even across reboots
# TPM Plugins
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
# Init TPM (at the bottom of your config)
run '~/.tmux/plugins/tpm/tpm'
- tmux plugin manager (TPM)
- tmux-resurrect (save & load)
- tmux-continuum (... automatically)
like vim, lots of plugins (& a plugin manager)
repeating history
it depends on your local environment
(what shell & how you handle history)
for example, my strategy using bash is
- append to my history
- (ignoring dupes is nice)
- write to the history file after every command
new shells automagically get the latest history
`history -n` will also update on a per-shell basis
tidbits & misc.
itty bitty goodies
-
<prefix> z # zooms a pane
-
<prefix> t # shows a clock
-
<prefix> ? # list binds
-
<prefix> ! # pane -> window
# Prevent shell from remaining windows after setting it once
set -g allow-rename off
# Set the terminal title
set-option -g set-titles on
set-option -g set-titles-string "#S / #W"
basic, minimal config
an (opinionated) functional config
# Rebind prefix to 'C-a'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# Easy config reload (<prefix> r)
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# Start window index at 1 (match keyboard order)
set -g base-index 1
# Use | and - to split panes
unbind '"'
unbind %
bind | split-window -h
bind - split-window -v
- rebind the <prefix>
- better splitting binds
- EZPZ config reload
- deal with windexing
questions?
¯\_(ツ)_/¯
links
tabs that persisted throughout creating this
Digging into Dotfiles: tmux
By Paul Esch-Laurent
Digging into Dotfiles: tmux
Get up and running with a ~/.tmux.conf.
- 595