tmux session in Solarized Dark with hand-rolled status bar

tmux — Getting Started & Cheatsheet

Prefix = C-a · Solarized hand-rolled status bar · vim-style pane nav
view full screenshot

Getting started / what's set

At a glance

PrefixC-a (screen-style)
Why not C-Spaceconflicts with macOS input-source switching
Pane navC-a + h/j/k/l
SplitsC-a + | / - (cwd inherited)
Indexingwindows + panes start at 1, auto-renumber
Mouseon (URLs: ⇧⌘ click)
History50,000 lines
Bellssilenced (bell-action/visual-bell/monitor-bell off)
TPM pluginstpm, tmux-sensible, tmux-resurrect, tmux-continuum, tmux-sessionx

Open / quit

tmuxstart a new session
tmux new -s <name>named session
tmux a / tmux a -t <name>attach to last / named session
tmux lslist sessions
C-a ddetach (session keeps running)
C-a rreload ~/.config/tmux/tmux.conf
C-a ttmux-sessionx picker popup (tmux / tmuxinator) — live pane preview for the highlighted session
s [<project>] [<name>]create-or-attach worktree+session — inside tmux 1 arg = worktree name in current project, outside tmux 1 arg = project, 0 args = fzf picker
C-a Tclock-mode (swapped from default t)
C-a Popen current branch's PR in browser via gh pr view --web (silent when no PR — counterpart to the orange status-bar PR pin)
⇧⌘ clickClaude Code file links → routes via macOS file-type defaults (OSC 8 passthrough enabled in tmux.conf via terminal-features hyperlinks)
C-a ?list all keybindings
C-a :command prompt

House rules (per CLAUDE.md)

Sessions / persistent workspaces

From inside tmux

C-a ddetach
C-a ssession picker (tree)
C-a $rename current session
C-a ( / )prev / next session
C-a Lswitch to last session

Closing the last pane of a session (exit, Ctrl-D) switches to the most-recently-used other session via detach-on-destroy off. Detaches only when no other session exists.

From the shell

tmux new -s workcreate "work"
tmux a -t workattach to "work"
tmux kill-session -t workkill "work"
tmux kill-serverkill all sessions

tmux-resurrect + tmux-continuum auto-save sessions every 15 min and auto-restore on a fresh server. See the "Persistence" card below for bindings.

Session picker prefix t

C-at opens tmux-sessionx, a TPM-loaded session picker. Sources: existing tmux sessions plus tmuxinator projects (@sessionx-tmuxinator-mode 'on'). Zoxide is intentionally not a picker source (@sessionx-zoxide-mode 'off'). The current session is hidden from the list (@sessionx-filter-current 'true').

Highlighting an entry shows live pane content in the preview pane (tmux capture-pane -ep on the session's active pane). The plugin claims the binding via @sessionx-bind 't' — no manual bind-key exists for this picker. Geometry is pinned at 70% × 70% (@sessionx-window-width / @sessionx-window-height), the shared anchor with the URL and file pickers.

Sesh stays installed for bin/s (the worktree+session command), which still reads sesh list -c -j as its project registry. The shared .config/sesh/sesh.toml + machine-local ~/.config/sesh/sesh.local.toml split is unchanged. _ZO_EXCLUDE_DIRS excludes (~/, ~/Downloads/*, ~/.config/*, ~/Library/*) remain for z-cd hygiene.

Persistence resurrect + continuum

C-a C-ssave snapshot now (manual)
C-a C-rrestore latest snapshot (manual)
auto-saveevery 15 min (continuum default)
auto-restoreon fresh tmux server start (@continuum-restore 'on')
snapshots in~/.local/share/tmux/resurrect/

Defaults only: no @resurrect-processes (panes get fresh shells in cwd; nvim/ssh are NOT relaunched), no @resurrect-capture-pane-contents (scrollback is not saved). Auto-restore only fires on a brand-new server with zero sessions, so attaching to an already-running server (sesh's normal flow) is unaffected.

Dashboard experimental

dashboard '<pattern>' [--cols N] from the shell. Spawns or rebuilds a dashboard-<derived> session tiling live capture-pane output for every tmux session whose name matches the glob. One tile per match; default layout is tmux's tiled auto-shape. --cols N forces an N-column grid.

C-a Jpage rows down (no-op outside dashboard-*)
C-a Kpage rows up
dashboard --rebuildre-discover sources, refresh tiles (run inside the dashboard)

Re-running dashboard '<pattern>' is idempotent — kills only stale tiles and adds tiles for new matches. Outside tmux the script attaches; inside tmux it switch-clients to the dashboard.

Windows / tabs in a session

Manage

C-a ccreate window — opens at session root (@session_root, set by s) when present, else inherits pane cwd
C-a ,rename window
C-a &kill window (confirm)
C-a wwindow picker (tree)
C-a .move window (renumber)

Switch

C-a n / pnext / prev window
C-a 19window 1–9 by number
C-a llast window (but l is also pane-right here — see "Quirks")
C-a ffind by name (search)

Quirk: we rebind C-al to pane-right (vim style). To go to the previous window, use C-an/p or the picker.

Auto-rename (custom)

Window name follows the active pane's last typed command, set by zsh preexec via @last_cmd. Env-var assignments are stripped first; the first two whitespace-separated tokens are used.

allow-rename off stays — OSC titles from apps (e.g. Claude Code) cannot override.

Panes / splits inside a window

Move & close

C-a h / j / k / lleft / down / up / right
C-a ;last (most-recent) pane
C-a xkill pane (confirm)
C-a qshow pane numbers (then number to jump)
C-a zzoom toggle (full-screen pane)
C-a !break pane → its own window
C-a { / }swap pane left / right in layout

Resize / layout

C-a H / J / K / Lresize 5 cells (when bound by tmux-sensible)
C-a Spacecycle preset layouts
C-a M-1M-5specific layouts (M = Alt; avoid here)
:resize-pane -D 5resize from prompt (D/U/L/R)
:select-layout main-verticalforce a layout by name

Splits / keep cwd, mirror Ghostty

Create

C-a |vertical split (right) — keeps cwd
C-a -horizontal split (below) — keeps cwd

Defaults " and % are unbound — use |/-.

Copy mode & scrollback / vi-style

Enter / exit

C-a [enter copy mode
q / Escexit copy mode
C-a ]paste tmux buffer
C-a =choose buffer to paste

Inside copy mode

h j k lmove cursor
w / bword forward / back
0 / $line start / end
g / Gtop / bottom
/ / ?search forward / back
n / Nnext / prev match
Spacebegin selection
Entercopy selection (to tmux buffer)
v / Vchar / line selection (vi-mode)

Mouse drag also selects. macOS clipboard is wired through tmux's default OSC 52 path; if your terminal supports it (Ghostty does) Enter reaches the system clipboard.

Status bar / hand-rolled Solarized

Layout

Bottom bar, bg=base02 / fg=base0. Three segments:

Solarized palette in use

base03 base02 base01 base0 base2 base3
blue (session) green (active win) yellow (worktree branch) violet (main branch) orange (PR pin) cyan (selection) red

Selection / message style uses cyan-on-base03; pane border switches base01 → blue when active.

Status helpers

~/.config/tmux/bin/tmux-status-rightorchestrator for the right-side status segment — composes PR pin (when present) + git chip flush-right
~/.config/tmux/bin/tmux-pr-detectstale-while-revalidate file cache around gh pr view (TTL 60s) — echoes PR number for current branch or empty
~/.config/tmux/bin/tmux-git-statusgit/worktree status segment, colors as args
~/.config/tmux/bin/claude-tmux-window-namesets/clears @claude_session_name from Claude Code hooks (drives claude[<name>] window title)
~/.config/tmux/bin/tmux-ssh-indicatorwalks each attached client's ps ancestry; prints + space when any ancestor is sshd/sshd-session — prepended inside the session chip
scripts/test-helpers.shsmoke-tests for the helpers
scripts/test-tmux-pr-status.shsmoke tests for tmux-pr-detect + tmux-status-right (uses a PATH-shimmed gh)

Worktree detection uses git rev-parse --git-dir vs --git-common-dir so it works for .claude/worktrees/*, worktrunk paths, and sibling worktrees alike.

Useful command-prompt commands / C-a :

Common

:new-window -c "#{pane_current_path}"new window in same dir
:swap-window -t :+1move window right
:movew -rrenumber windows now
:setw synchronize-panestype to all panes (toggle)
:clear-historyclear scrollback
:source-file ~/.config/tmux/tmux.confreload (also C-ar)
:show -g | grep …inspect global options
:list-keysall bindings

Tmux from outside

tmux send-keys -t mywin "ls" Entertype into a target pane
tmux display-message -p '#S'print current session name
tmux info | grep …debug runtime state
tmux show -p @last_cmdread this pane's last command

Config notes / ~/.config/tmux/tmux.conf

# Prefix
set -g prefix C-a            # C-Space conflicts with macOS input-source switching

# Terminal — truecolor
set -as terminal-features ",xterm-ghostty:RGB"
set -as terminal-features ",xterm-256color:RGB"

# Sane defaults
set -g mouse on
set -g base-index 1
set -g renumber-windows on
set -g history-limit 50000
set -g escape-time 10          # vim-friendly
set -g focus-events on

# Bells silenced everywhere
set -g bell-action  none
set -g visual-bell  off
set -g monitor-bell off

# Window naming: @claude_session_name (Claude hooks) overrides
# @last_cmd (zsh preexec) overrides pane_current_command (fallback)
set -g allow-rename off
set -g automatic-rename on
set -g automatic-rename-format '#{?#{!=:#{@claude_session_name},},claude[#{@claude_session_name}],#{?#{==:#{@last_cmd},},#{pane_current_command},#{@last_cmd}}}'

Reload & verify

C-arreload config inside running tmux
scripts/test-helpers.shsmoke-tests for status helpers
scripts/test-tmux-window-label.zshwindow-label extraction tests (mirror of _tmux_window_label in .zshrc)
scripts/test-claude-tmux-window-name.zshtests for the claude[<name>] window-title helper
scripts/test-tmux-ssh-indicator.shSSH-indicator tests (mocks tmux+ps via PATH shim, asserts globe glyph emission)