Skip to content

tmux⚓︎

tmux is a terminal multiplexer. It splits one terminal into windows and panes, and keeps sessions running after you close the terminal or lose an SSH connection. It replaced byobu here: byobu is a wrapper around tmux, and plain tmux with one config does the same job with fewer layers.

The same config runs on my laptop and my home server. It keeps tmux's default bindings (prefix Ctrl+B), so any tmux tutorial applies as-is, and adds:

  • a searchable cheatsheet on Ctrl+B ?
  • Claude Code awareness: an agent sidebar and status-bar icons for panes waiting on you
  • comfortable nesting over SSH (F12), auto-attach on SSH login, and a different accent colour per machine
  • sessions that survive reboots

Installation⚓︎

sudo pacman -S tmux fzf git
paru -S sesh-bin          # optional: project/session picker on Ctrl-b S (uses zoxide)

Coming from byobu

tmux is installed as a dependency of byobu. Mark it explicit before removing byobu, or pacman -Rns takes tmux with it:

sudo pacman -D --asexplicit tmux
sudo pacman -Rns byobu
rm -rf ~/.config/byobu

Then install the config from this repository and install the plugins:

./dotfiles/install-tmux.sh --dry-run   # preview
./dotfiles/install-tmux.sh             # copies config, cheatsheet and fish snippets (backs up old files)
tmux kill-server                       # only if an old (e.g. byobu) server is running; ends its sessions
tmux new -s main                       # first start clones TPM
# inside tmux: Ctrl-b I                # installs plugins; fingers and the sidebar run an install wizard

Finally, wire the agent sidebar into Claude Code (once per machine):

/plugin marketplace add ~/.tmux/plugins/tmux-agent-sidebar
/plugin install tmux-agent-sidebar@hiroppy
/reload-plugins

Files⚓︎

File Installed to Purpose
dotfiles/tmux/tmux.conf ~/.config/tmux/ The config
dotfiles/tmux/cheatsheet.tsv ~/.config/tmux/ Curated cheatsheet entries, including plugin keys
dotfiles/tmux/cheatsheet.sh ~/.config/tmux/ fzf viewer for the cheatsheet plus live bindings
dotfiles/tmux/bin/xclip ~/.config/tmux/bin/ xclip shim so pasting images over SSH keeps working after a reconnect (see below)
dotfiles/fish/conf.d/clip-shim.fish ~/.config/fish/conf.d/ Puts that shim first in PATH
dotfiles/fish/conf.d/tmux-ssh-attach.fish ~/.config/fish/conf.d/ Auto-attach on interactive SSH login
dotfiles/fish/functions/tmux-help.fish ~/.config/fish/functions/ tmux-help opens the cheatsheet outside tmux
(not in the repo) local.conf ~/.config/tmux/ Per-machine overrides, see below

Per-machine settings⚓︎

tmux.conf sources ~/.config/tmux/local.conf if it exists. Use it for anything that differs between machines, for example:

set -g @accent "#82aaff"                       # status-bar accent
set -g pane-active-border-style "fg=#82aaff"
set -g popup-border-style "fg=#82aaff"
set -g @sidebar_notifications 'on'             # desktop notifications (needs a notify daemon)

Plugins live in ~/.tmux/plugins/, managed by TPM.

Learning the keys⚓︎

Ctrl+B ? opens a searchable cheatsheet in a popup. It shows tmux's defaults, the extras below, every plugin's keys (including keys inside the sidebar and hint mode, which tmux itself doesn't know about), and the live bindings of the running server. Type to filter, e.g. split, sidebar, copy. Outside tmux, run tmux-help.

The extras on top of the defaults:

Keys Action
Ctrl+B ? Cheatsheet (search)
Ctrl+B R Reload tmux.conf
Ctrl+B | / - Split left/right / top/bottom in the current directory
Ctrl+B Shift+S Session and project picker (sesh, or plain fzf without it)
Ctrl+B Shift+P Toggle a scratch terminal popup that keeps its state
Ctrl+B A / Shift+A Agent sidebar in this window / all windows
Ctrl+B Shift+F Hint-copy paths, URLs, hashes and IPs (tmux-fingers)
Ctrl+B Ctrl+S / Ctrl+R Save / restore sessions now (tmux-resurrect)
F12 Laptop only: turn the outer tmux off for a nested remote tmux

tmux 3.8 also has native floating panes: Ctrl+B ++asterisk++ opens one, Ctrl+B ++at++ toggles a pane between floating and tiled, Ctrl+B G moves it.

Claude Code⚓︎

  • Status-bar icons. Each window shows ● when Claude is waiting on you, ⏳ while it works and ✗ on error. The icons come from the pane options that tmux-agent-sidebar's hooks set, so they need the Claude Code plugin step above.
  • Agent sidebar. Ctrl+B A shows every Claude pane across all sessions with its latest prompt, tool calls and subagents. Enter jumps to a pane, and N spawns a new git worktree with Claude in it. It is hidden by default to save width. Desktop notifications are off by default; turn them on in local.conf on machines with a notification daemon.
  • Keys. extended-keys passes Shift+Enter through to Claude Code, including in a nested tmux over SSH.

SSH and nesting⚓︎

  • Auto-attach. Interactive SSH logins run tmux new -A -s main. Non-interactive ssh host cmd, scp and scripts are left alone. To skip it: ssh -t host 'NOTMUX=1 fish'. Detaching (Ctrl+B D) drops you to a normal shell on the host.
  • Nesting. On the laptop, F12 turns the local tmux off: its status bar shows OFF and every key, including Ctrl+B, goes to the remote tmux. F12 again turns it back on. Only a locally started tmux binds F12, so you can't switch off both layers by accident.
  • Which host am I on? The host name is in the status bar, in that machine's accent colour (set in local.conf).
  • Clipboard. Copying in copy mode (or from Claude Code) on the remote goes through OSC 52 to kitty, and lands in the local clipboard.

  • Pasting images into Claude Code over SSH. OSC 52 only carries text. To paste an image, Claude Code runs xclip on the host it is running on, so the remote host needs your local clipboard through X11 forwarding:

    • Client ~/.ssh/config, in the server's Host block: ForwardX11 yes and ForwardX11Trusted yes. Trusted forwarding is required because Xwayland (KDE and GNOME on Wayland) has no SECURITY extension. Only do this for hosts you trust, since they get full access to your X display.
    • Server: X11Forwarding yes in sshd, plus xorg-xauth and xclip installed.
    • The xclip shim takes DISPLAY from the tmux session, which tmux updates on every attach. So a Claude Code session started under an earlier SSH connection still pastes from the current one. If the same session is attached both locally and over SSH, whichever attached last decides whose clipboard is read.
    • Check it: copy an image locally, then on the remote, inside tmux, run xclip -selection clipboard -t TARGETS -o. The output should include image/png.

Mosh

Mosh can't pass extended keys or kitty graphics. Over mosh, use Ctrl+J instead of Shift+Enter in Claude Code, and yazi shows no image previews. Mosh doesn't do X11 forwarding either, so image paste doesn't work over it. Plain ssh (or kitten ssh) supports all three.

Usage⚓︎

tmux new -A -s work       # attach to "work", creating it if missing
tmux ls                   # list sessions
tmux kill-session -t work
tmux new -d -s upgrade 'paru -Syu' && tmux attach -t upgrade   # background job