Tmux is a Terminal MUltipleXer, which is a fancy way of saying its a tabbing system for terminals. Unlike native GUI terminals, it curses based. While this may initially sound like a disadvantage, it actually allows for some interesting features. The biggest of these is you can “detach” from your current tab session, resume it at a later time and everything is as you left it.

Why I like it#

My original reasons for choosing tmux were that it supported both vertical and horizontal splits whereas GNU Screen only supported one of the two (which of them, I forget). It also had a more permissive BSD license, which I like more than GPL.

Pair Programming#

Another reason I like tmux is its use for pair programming. At Seajure, we all SSH into a single box and watch as one person edits code. This is much nicer than crowding around someone’s laptop, which isn’t feasible given the seating arrangements at play.

Long running sessions#

The other main use I have for tmux is long running processes on random servers. I have a virtualbox VM with an ArchLinux install for various UNIX-y things that my mac isn’t terribly suited for (such as writing this post). In it, I have a tmux session which helps provide me context from one editing session to another. Tmux is also a boon when dealing with a flaky wifi connection. Being able to resume the in-progress terminal screen is nice, so you don’t have orphaned processes when your connection dies.

How I configure it#

Allow switching the currently focused pane by mouse click.

setw -g mouse on

Set the terminal type for proper color and feature support, and reduce the escape delay (important for vim/neovim users).

set -g default-terminal "tmux-256color"
set -sg escape-time 10

Enable OSC 8 hyperlink passthrough (tmux 3.4+) so clickable links work in terminals like Ghostty. Pass focus events through to applications like vim and emacs so they can detect window focus changes.

set -g allow-passthrough on
set -as terminal-features ",xterm-256color:hyperlinks"
set -g focus-events on

Use zsh as my default shell when opening new panes.

set-option -g default-shell /bin/zsh

Set the title of the current window to something descriptive for the entire tmux session. This results in the current window being called “~1. neon-vm:0.0.0 emacsclient justinlilly@neon-vm:~~”

set-option -g set-titles on
set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name, active(or not)

I prefer having my C-z as my default prefix. While it means I need to double-tap C-z for backgrounding a process, its much more accessible to my caps lock based ctrl key than B and doesn’t interfere with emacs likes C-a does. Nested session? C-z z (the send-prefix command below) will send the inner session the prefix identifier.

set-option -g prefix C-z
unbind-key C-b
bind-key z send-prefix

Zero based indexing is awesome… in programming languages. I’d rather have tmux start at 1, as it preserves simple left-based ordering for windows. Renumber windows automatically when one is closed so there are no gaps.

set -g base-index 1
set -g renumber-windows on

When a smaller terminal connects to a tmux client, it shrinks to fit it. The clients attached with bigger displays see this constrained view. aggressive-resize makes it such that the window is only resized if the smaller client is actively looking at it.

setw -g aggressive-resize on

Next are a bunch of options related to my status line. The left side of the status line displays the hostname and the session number like “neon-vm:0 |”. The right side shows a simple date and time. The center status line is centered such that it’s distinct from the left and right.

set -g status-style "bg=black,fg=green"
set -g status-left-length 15
set -g status-left ' #[fg=cyan,bright]#10H#[fg=green]:#[fg=white]#S#[fg=green] | #[default]'
set -g status-right '| #[fg=yellow]%y-%m-%d %H:%M '
set -g status-justify centre

By default, windows only keep 2000 lines of history. Let’s increase that to 100k. Nothing worse than something important being JUST off of screen.

set -g history-limit 100000

Some nifty key bindings I’ve picked up here and there. I like the | and - variants which do window splits, which I picked up from . The S command will prompt for a hostname

bind-key r source-file ~/.tmux.conf \; display-message "Reloaded!"
bind-key S command-prompt -p ssh: "new-window -n %1 'ssh %1'"
bind-key | split-window -h
bind-key - split-window -v

Window navigation with arrow keys disrupts my “keep your keys on/near the homerow” flow. Use vim-style and emacs-style navigation.

bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

bind -n C-M-h select-pane -L
bind -n C-M-j select-pane -D
bind -n C-M-k select-pane -U
bind -n C-M-l select-pane -R

Resources#