My personal tmux configuration — Catppuccin Mocha theme, vim-style navigation, session persistence, and QoL tweaks.
C-Space (rebound from C-b)
set-option -sa terminal-overrides ",xterm*:Tc"
set -g mouse on
unbind C-b
set -g prefix C-Space
bind C-Space send-prefix
# Vim style pane selection
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Start windows and panes at 1, not 0
set -g base-index 1
set -g pane-base-index 1
set-window-option -g pane-base-index 1
set-option -g renumber-windows on
# Use Alt-arrow keys without prefix key to switch panes
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
# Shift arrow to switch windows
bind -n S-Left previous-window
bind -n S-Right next-window
# Shift Alt vim keys to switch windows
bind -n M-H previous-window
bind -n M-L next-window
set -g @catppuccin_flavour 'mocha'
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'christoomey/vim-tmux-navigator'
set -g @plugin 'dreamsofcode-io/catppuccin-tmux'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
# Resurrect: restore development services with their arguments
set -g @resurrect-processes '\
lazygit \
claude \
"~pnpm->pnpm *" \
"~stripe->stripe *" \
"~codex->codex *" \
"~gemini" \
'
# Continuum: automatically restore last session when tmux starts
set -g @continuum-restore 'on'
run '~/.tmux/plugins/tpm/tpm'
# set vi-mode
set-window-option -g mode-keys vi
# keybindings
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
##### QoL toggles & speed #############################################
# Reload config + notify
bind r source-file ~/.tmux.conf \; display-message 'tmux.conf reloaded'
# Toggle mouse quickly (you start with mouse on)
bind m set -g mouse \; display-message "mouse: #{?mouse,ON,OFF}"
# Toggle synchronized typing across panes (for clustered commands)
bind S setw synchronize-panes \; display-message "sync-panes: #{?synchronize-panes,ON,OFF}"
# Make Esc feel snappy but keep function keys reliable
set -sg escape-time 10
# Bigger scrollback
set -g history-limit 200000
# Focus events help editors/REPLs react to focus changes
set -g focus-events on
# Quick tree switcher (browse sessions/windows/panes; Enter to jump, x to kill)
bind Space choose-tree -Zw
# Rapid pane resize with prefix + H/J/K/L (hold to repeat)
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
# Last pane fast toggle
bind Tab last-pane
##### Colors & Clipboard ##############################################
# Prefer tmux's own terminfo when available
set -g default-terminal "tmux-256color"
# Advertise truecolor to tmux (RGB == Tc)
set -ag terminal-overrides ",*:RGB"
# Integrate with terminal/system clipboard (OSC-52 / external clipboards)
set -s set-clipboard external
##### Sensible window behavior ########################################
set -g renumber-windows on
# Resist apps auto-renaming windows
setw -g allow-rename off
##### Pane Titles #####################################################
# Show pane titles in the border (top of each pane)
set -g pane-border-status top
set -g pane-border-format " #{pane_index}: #{pane_title} "
# Set pane title: prefix + t
unbind -T prefix t
bind -T prefix t command-prompt -p "Pane title:" 'select-pane -T "%%"'| Plugin | Purpose |
|---|---|
| tpm | Plugin manager — prefix + I to install, prefix + U to update |
| tmux-sensible | Universal sane defaults |
| vim-tmux-navigator | Seamless C-h/j/k/l between vim and tmux panes |
| catppuccin-tmux | Catppuccin Mocha status bar theme |
| tmux-yank | System clipboard integration in copy mode |
| tmux-resurrect | Save/restore sessions across restarts (prefix + C-s / prefix + C-r) |
| tmux-continuum | Auto-save every 15min + auto-restore on tmux start |
# Install tpm
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Then inside tmux:
# prefix + I (install plugins)
# prefix + U (update plugins)
# prefix + alt + u (uninstall removed plugins)| Keys | Action |
|---|---|
Alt + ←/→/↑/↓ |
Switch panes |
Shift + ←/→ |
Previous/next window |
Alt + H/L |
Previous/next window (vim-style) |
C-h/j/k/l |
Navigate across vim + tmux panes (vim-tmux-navigator) |
| Keys | Action |
|---|---|
h/j/k/l |
Select pane (vim-style) |
H/J/K/L |
Resize pane by 5 (repeatable) |
Tab |
Toggle last pane |
Space |
Tree switcher (sessions/windows/panes) |
" |
Split vertical (keeps cwd) |
% |
Split horizontal (keeps cwd) |
t |
Set pane title |
r |
Reload tmux.conf |
m |
Toggle mouse on/off |
S |
Toggle synchronized panes |
v |
Begin selection (copy mode) |
C-v |
Rectangle toggle (copy mode) |
y |
Yank selection (copy mode) |
C-s |
Save session (resurrect) |
C-r |
Restore session (resurrect) |
I |
Install plugins (tpm) |
U |
Update plugins (tpm) |
tmux # new session
tmux new -s myname # new named session
tmux a -t myname # attach to named
tmux ls # list sessions
tmux kill-session -t myname # kill sessionThe @resurrect-processes setting preserves long-running dev processes across restarts:
lazygit,claude,gemini— restored as-is"~pnpm->pnpm *"— restores anypnpmcommand with its original arguments (dev servers, watchers, etc.)- Same pattern for
stripe(webhooks) andcodex
Combined with @continuum-restore 'on', tmux auto-restores your last session layout + processes on start.
prefix + S toggles typing into all panes simultaneously — useful for running the same command across multiple servers or directories.
prefix + t lets you label panes (shown in the border). Helpful when running multiple agents/services to keep track of what's where.
Enter copy mode with prefix + [, then:
vto start selection,C-vfor block selectionyto yank (copies to system clipboard via tmux-yank + OSC-52)/to search forward,?to search backwardqto exit
history-limit is set to 200,000 lines — generous enough to scroll through long build logs without losing output.
prefix + Space opens a zoomable tree view of all sessions, windows, and panes. Press Enter to jump, x to kill.
# Move window 2 into a pane in the current window
:joinp -s :2
# Move the current pane into window 1
:joinp -t :1
# Swap windows
:swap-window -s 3 -t 1