Loading

Digging into Dotfiles: tmux

Paul Esch-Laurent

This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.

Digging into dotfiles:

tmux

Paul Esch-Laurent

(live) slide deck: uly.io/talk/tmux

my dotfiles: uly.io/dotfiles

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'

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

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

Made with Slides.com