tmux

tmux

tmux is a terminal multiplexer: persistent sessions, plus windows and split panes inside a single terminal. The snippets below are verified on tmux 3.2a. The prefix key is assumed to be the default C-b unless stated otherwise.

Cookbook

Create or attach a session (idempotent)

tmux new -A -s name

-A makes new-session behave like attach-session when the session already exists, so there is no “duplicate session” error. That makes it the right command for scripts and shell startup files. Add -d to create it detached; note that -d only applies to creation, so when the session already exists the command attaches anyway (and fails without a terminal). For a strict create-if-missing: tmux has-session -t name 2>/dev/null || tmux new -d -s name.

Tip article: How to create or attach to a tmux session in one command?

Start a named session with a window name and directory

tmux new -d -s projet -n edit -c ~/code/projet

Creates the session projet, names its first window edit, and starts it in ~/code/projet. -d keeps it detached so the command is scriptable; attach later with tmux attach -t projet.

Tip article: How to start a named tmux session with a window name and a directory?

Detach, list, and re-attach a session

tmux ls                 # list running sessions
tmux attach -t projet   # re-attach (short: tmux a -t projet)

Press prefix d to detach: the session keeps running in the background. tmux ls shows what is alive, and tmux attach -t name jumps back in. prefix s runs choose-tree -Zs, an interactive session picker zoomed to full screen.

Tip article: How to detach, list, and re-attach a tmux session?

Rename a session or a window

tmux rename-session -t old new   # rename a session
tmux rename-window new           # rename the current window

From the keyboard, prefix $ renames the current session and prefix , renames the current window, both through a prompt. Renaming a window by hand also turns off its automatic rename, so the name you typed sticks.

Tip article: How to rename a tmux session or window?

Manage clients: list, kick out, disconnect

tmux list-clients -t projet     # who is attached (short: lsc)
tmux attach -d -t projet        # attach here and detach every other client
tmux detach-client -a           # detach all clients except the current one
tmux detach-client -t <client>  # detach one specific client

When several terminals are attached to the same session, attach -d grabs it back to where you are and kicks the others off. prefix D runs choose-client -Z, an interactive client picker. attach -x also sends SIGHUP to the parent process of the client it detaches, which closes, for example, the SSH session that started it.

Tip article: How to manage tmux clients (list, kick out, disconnect)?

Switch between sessions without detaching

tmux switch-client -t other   # move the attached client to session 'other'

No need to detach and re-attach: switch-client moves the current client straight to another session, staying inside tmux. From the keyboard, prefix ( and prefix ) walk to the previous and next session, and prefix L toggles back to the last used session. prefix s opens choose-tree -Zs for an interactive picker.

Tip article: How to switch between tmux sessions without detaching?

Kill a session, or the whole server

tmux kill-session -t name      # kill one session
tmux kill-session -a -t keep   # kill ALL sessions except 'keep'
tmux kill-server               # kill everything: all sessions, the server itself

Killing a session terminates every process in it, unlike detaching which keeps it running. The -a flag inverts the target: everything except the named session dies. kill-server takes the whole server down; the next tmux new starts a fresh one.

Tip article: How to kill a tmux session, or the whole server?

Control a nested tmux: send the prefix inward

# ~/.tmux.conf, when your prefix is C-a
bind C-a send-prefix   # double C-a then targets the inner tmux

With two tmux stacked (a local one and another over SSH, for example), the outer tmux catches the prefix. To reach the inner one, you forward the prefix to it (this sends the outer prefix key, so it assumes both levels use the same prefix). By default prefix C-b runs send-prefix, so with the stock C-b prefix you press it twice. Once your prefix is C-a, add bind C-a send-prefix and a double C-a C-a is sent through to the inner session. The simplest alternative is to give the inner tmux a different prefix so the two never collide.

Tip article: How to control a nested tmux session (send the prefix to the inner one)?

Split a window into panes

tmux split-window -h   # panes side by side (left / right)
tmux split-window -v   # panes stacked (top / bottom)

split-window cuts the active pane in two and starts a new shell in the freed half. The flag names are the usual tmux trap: -h (“horizontal”) gives a vertical divider, so the panes sit side by side, while -v stacks them top and bottom. The flag describes the axis of the cut, not the visual layout. From the keyboard, prefix % does split-window -h and prefix " does the vertical split. Add -c "#{pane_current_path}" to open in the current directory, -b to insert before instead of after, and -l 30% to set the new pane’s size.

The -h/-v names are easy to forget, so it is worth rebinding the splits to keys that match the result, | for side by side and - for stacked (see the sample config below).

Tip article: How to split a tmux window into panes?

tmux next-window       # go to the next window
tmux previous-window   # go to the previous window
tmux last-window       # toggle with the previously active window

From the keyboard, prefix n and prefix p step to the next and previous window, and they wrap around the ends. prefix l (lowercase L) is the useful one: it toggles back and forth between the current window and the one you were on before, so jumping to a window and back is two keystrokes. It is the window-level twin of prefix ;, which toggles the last active pane.

Tip article: How to navigate between tmux windows?

Reorder windows

tmux swap-window -s 2 -t 4   # exchange windows 2 and 4
tmux move-window -s 2 -t 4   # move window 2 to index 4 (target must be free)

swap-window exchanges two windows, trading only their index numbers, so neither slot needs to be free. On 3.2a the focus stays on the current index (you end up on the swapped-in window); add -d to make it follow the moved window instead, and beware that -d has flipped meaning between tmux versions. move-window slides one window to a new index, but that index must be empty, otherwise tmux refuses with index in use and changes nothing. From the keyboard, prefix . opens a prompt running move-window -t on the current window. To repack the list and remove the gaps left behind, use renumber-windows.

Tip article: How to reorder tmux windows?

Renumber windows to close the gaps

tmux move-window -r          # repack now: indexes become 0, 1, 2, ...
set -g renumber-windows on   # ~/.tmux.conf: repack on every window close

Closing a window in the middle of the list leaves its index empty, so the windows drift to something like 0 3 7. move-window -r renumbers every window in the current session at once to a contiguous range starting at base-index. Setting renumber-windows on in ~/.tmux.conf does the same thing automatically each time a window closes, so the list never grows gaps and prefix 1, prefix 2, … keep landing where you expect.

Tip article: How to renumber tmux windows and close the gaps?

Stop windows from renaming themselves

setw -g automatic-rename off   # ~/.tmux.conf: keep the names you set

By default tmux runs with automatic-rename on, so each window is named after the program in its active pane and the title keeps shifting from sh to vim to node as you work. Renaming a window by hand turns automatic-rename off for that window alone, so the name sticks; setting it off globally does the same for every window. A separate option, allow-rename (off by default on 3.2a), controls whether a program can push its own title through a terminal escape sequence.

Tip article: How to stop tmux from renaming your windows?

Get notified of activity or silence in a window

setw -g monitor-activity on    # ~/.tmux.conf: flag the window on any output
setw -g monitor-silence 30     # flag it after 30 s with no output (0 = off)
set  -g visual-activity on     # also print a status message
set  -g visual-silence on      # same, for the silence monitor

Run a long job in one window, switch away, and tmux highlights that window when something happens. monitor-activity reacts to new output; monitor-silence reacts to output stopping for N seconds, which is the better “the job finished” signal. With visual-activity on tmux also prints a status message instead of only flagging the window; visual-silence is the silence counterpart. A related option, monitor-bell, flags a window when a program rings the terminal bell and is on by default. Defaults on 3.2a: monitor-activity off, monitor-silence 0, visual-activity off, visual-silence off, monitor-bell on.

Tip article: How to get notified of activity or silence in a tmux window?

Move between panes

tmux select-pane -L     # focus the pane to the left (-R right, -U up, -D down)
tmux select-pane -t :.+ # focus the next pane in order, wrapping around

From the keyboard, prefix then an arrow key moves the focus in that direction. The arrow binds are repeatable, so within the repeat timeout you can keep tapping arrows without pressing the prefix again. prefix o cycles to the next pane in order and wraps back to the first. prefix q runs display-panes, which overlays a large number on each pane; type that number to jump straight to it. The overlay stays up for display-panes-time, 1000 ms by default. To bounce back to where you were, prefix ; toggles the last active pane.

Tip article: How to move between tmux panes?

Jump back to the last active pane

tmux last-pane     # toggle focus back to the previously active pane
tmux select-pane -l   # same toggle from the CLI

prefix ; runs last-pane: it toggles focus between the current pane and the one you were on just before, so bouncing to a pane and back costs one prefix ; each way. It is the pane-level twin of prefix l for windows. select-pane -l (lowercase L) does the same thing, and last-pane -Z keeps a zoomed pane zoomed across the toggle.

Tip article: How to jump back to the last active tmux pane?

Zoom a pane to fullscreen

tmux resize-pane -Z   # toggle the active pane to fullscreen and back

prefix z runs resize-pane -Z: the active pane expands to fill the whole window, and prefix z again restores the previous layout. The other panes are only hidden, not closed, and every process keeps running, so this is a temporary “give me room to read this” toggle, not a rearrangement. While a pane is zoomed, window_zoomed_flag is 1 and the status line shows a Z next to the window name. Splitting, swapping panes, or anything that changes the layout unzooms it automatically; switching windows does not, the pane is still zoomed when you come back.

Tip article: How to zoom a tmux pane to fullscreen?

Resize a pane: relative and absolute

tmux resize-pane -L 10        # push the active pane's border 10 columns to the left
tmux resize-pane -R 10        # ... to the right; -U / -D for up / down
tmux resize-pane -x 80 -y 24  # absolute size: 80 columns, 24 rows

Zoom (resize-pane -Z) is the all-or-nothing version; this is the fine-grained one. -L/-R/-U/-D [N] moves the border in that direction by N cells (default 1), and -x/-y set an exact size. A resize only does something when there is a neighbour on that axis to give or take space: two panes side by side cannot change each other’s height, only their width.

From the keyboard, both sets of binds are repeatable (-r), so you can hold the modifier and tap the arrow keys:

prefix C-Up / C-Down / C-Left / C-Right   resize-pane -U/-D/-L/-R   (step 1)
prefix M-Up / M-Down / M-Left / M-Right   resize-pane -U/-D/-L/-R 5 (step 5, Alt)

To rearrange every pane at once instead of nudging one border, change the layout (see below).

Tip article: How to resize a tmux pane?

Select and copy with the mouse

set -g mouse on   # ~/.tmux.conf: off by default

The mouse is off by default. With mouse on, a left-drag enters copy mode and copies the selection into the tmux paste buffer on release; paste it back with prefix ]. That buffer is tmux’s own, not the system clipboard, so another application sees nothing unless you pipe copy mode to a clipboard tool (pbcopy, xclip, wl-copy). To use the terminal’s native selection and clipboard instead, hold Shift while dragging, which bypasses tmux entirely. Turning the mouse on also enables click-to-focus a pane, click a window name to switch, scroll into the scrollback, and drag a border to resize; a right-click on a pane opens a context menu.

Tip article: How to select and copy text with the mouse in tmux?

Number windows and panes from 1

set  -g base-index 1        # ~/.tmux.conf: windows start at 1
setw -g pane-base-index 1   # panes start at 1
set  -g renumber-windows on # keep the list contiguous on close

By default tmux numbers windows and panes from 0, so the first window is prefix 0, at the far end of the number row. base-index (a session option) and pane-base-index (a window option, hence setw) shift the first index to 1, so prefix 1 selects the first window. Both apply only to windows and panes created afterwards, which is why they belong in ~/.tmux.conf. Pair them with renumber-windows on so closing a window repacks the list instead of leaving a gap. One side effect: the first pane becoming 1 changes how a bare number reads as a pane target, so prefer a pane id (%3) or a window.pane form when a target must be unambiguous.

Tip article: How to make tmux number windows and panes from 1?

Target a pane by number: the N vs N.M trap

tmux swap-pane -s 3      # ambiguous: pane 3 of THIS window, or window 3?
tmux swap-pane -s 3.1    # unambiguous: window 3, pane 1
tmux swap-pane -s %7     # unambiguous: pane id, never reinterpreted

Commands that take a pane target, like swap-pane and join-pane, read a bare number with one rule: it is a pane of the current window when a pane with that index exists, and otherwise a window (tmux then acts on that window’s active pane). So -s 3 points at pane 3 of the current window when it has that many panes, but flips to window 3 the moment it does not, and the switch is silent. Qualify the target to stay deterministic: a window.pane form (3.1), a pane id (%7, shown in #{pane_id} and by list-panes), or a window name (build.1). A pane id is the strongest choice because it is stable for the life of the pane and is never re-read as a window.

Tip article: How to target the right tmux pane by number?

Target windows with special tokens

tmux select-window -t '{end}'              # jump to the highest-numbered window
tmux select-window -t '!'                  # toggle back to the previously active window
tmux swap-window -s '{start}' -t '{end}'   # tokens work anywhere a window target does

Besides plain indexes and names, a window target accepts special tokens: {start} and {end} are the lowest and highest numbered windows, {last} is the previously active one, and {next} and {previous} are the neighbours by number. Each has a one-character alias: ^, $, !, + and -, and the last two accept an offset (+2, -2). Quote them in a shell: {, $ and ! all mean something to it. Tokens keep scripts independent of actual index numbers, so they keep working with base-index 1 or after a renumbering. They are the window-level counterpart of the pane targets above; pane-relative tokens like {left-of} come with the pane-moving commands.

Tip article: How to target tmux windows with special tokens?

Mark a pane and target it from anywhere

tmux select-pane -m            # mark the active pane (prefix m)
tmux swap-pane -s '{marked}'   # swap the active pane with the marked one
tmux join-pane -s '{marked}'   # bring the marked pane into this window

prefix m marks the active pane, and the target {marked} then resolves to it from any window or session. That removes the index juggling from join and swap: mark the pane where it lives, go where you want it, run the command. The marked pane is also the default source for join-pane, move-pane, swap-pane and swap-window, so once something is marked a bare tmux swap-pane swaps it with the active pane. prefix M clears the mark, marking another pane moves it, and moving the marked pane with swap or join clears it too, so mark again before the next move. With no mark set, {marked} fails with no marked target instead of silently picking a pane, which is exactly what a bare-number target does not give you (see the N vs N.M trap above).

Tip article: How to mark a tmux pane and target it from anywhere?

Pull a pane from another window into this one

tmux join-pane -h -s 3.1       # pane 1 of window 3 -> split to the RIGHT of the active pane
tmux join-pane -v -s build.0   # stacked below instead; add -b to insert before (left / above)

join-pane detaches one pane from wherever it lives and re-attaches it as a new split in the current window. -s is the source pane, -t the destination (default: the active pane); -h puts them side by side, -v stacks them, and -b inserts before instead of after. Qualify the source (3.1, a pane id, or the marked pane above) rather than a bare number, which is ambiguous (see the N vs N.M trap). Once a window loses its last pane it closes itself, so emptying a window with joins needs no cleanup. To gather every pane of a window at once, loop and then fix the layout:

src=3
for p in $(tmux list-panes -t "$src" -F '#{pane_id}'); do
  tmux join-pane -h -s "$p"    # into the current window
done
tmux select-layout tiled       # clean up the layout afterwards

The processes keep running through the move: join-pane re-parents the pane, it does not restart anything. The exact opposite is break-pane (prefix !), which sends the active pane off to a new window of its own.

Tip article: How to move a pane from one tmux window to another?

Move a pane with relative targets

tmux join-pane -h -s '{down-of}'   # pane below the active one -> re-attached to its right

One command reshapes a stacked pair into a side-by-side one: {down-of} names the pane below the active pane, and join-pane -h breaks it out of its slot and re-attaches it as a split to the right. Add -b to insert it on the left instead. Relative targets remove the index lookup entirely: {up-of}, {down-of}, {left-of} and {right-of} are the neighbours of the active pane, {top}, {bottom}, {left} and {right} are the panes at the window edges, {next} and {previous} walk the panes in index order, and {last} is the previously active pane. They work anywhere a pane target does: select-pane, swap-pane, resize-pane, join-pane. Quote them, braces mean something to the shell. Two behaviours to know: directional targets wrap around the window edge, so the bottom pane’s {down-of} is the top pane again, and when no pane lies in that direction at all the command fails with can't find pane instead of guessing.

Tip article: How to move a tmux pane with relative targets?

Pull a pane or a window from another session

tmux join-pane -s scratch            # active pane of session 'scratch' -> split here
tmux join-pane -h -s scratch:2.1     # a precise pane of another session
tmux move-window -s scratch:1 -t :   # or the whole window -> new window in this session

join-pane and move-window accept a source in another session of the same server, and the process running in the pane is re-parented, not restarted: a server launched in a throwaway session lands in the main workspace without going down. A source session that loses its last pane closes itself. Different servers (other sockets, tmux -L/-S) cannot exchange panes. The targeting rules above apply unchanged: qualify the source, prefer pane ids.

Tip article: How to move a tmux pane to another session without restarting its process?

Swap two panes without changing the layout

tmux swap-pane -s '{left}' -t '{right}'   # exchange the leftmost and rightmost panes
tmux swap-pane -U                         # swap the active pane with the previous one (prefix {)
tmux swap-pane -D                         # ... with the next one (prefix })

swap-pane exchanges two panes without touching the layout: the cells keep their position and size, the panes trade places. join-pane breaks a pane out and recreates a split; swap-pane leaves the grid alone, which makes it the right tool to flip an uneven split. prefix { and prefix } walk the active pane through the panes in index order, so the visual effect depends on the layout. Focus: without -d the destination pane ends up focused, which is why prefix { carries your pane and your focus together, but also why a scripted swap between two other panes steals the focus; add -d to leave a third-party focus untouched.

Tip article: How to swap two tmux panes?

Reorganize the whole layout at once

tmux select-layout tiled            # apply the tiled (grid) layout now
tmux select-layout main-vertical    # one large pane left, the rest stacked right

tmux ships five preset layouts. prefix Space (next-layout) cycles through them in order: even-horizontal (equal columns), even-vertical (equal rows), main-horizontal (one large pane on top, the rest in a row below), main-vertical (one large pane on the left, the rest in a column on the right), and tiled (an even grid). select-layout <name> jumps straight to one without cycling, which is the tool you want after pulling several panes into a window (see “Pull a pane from another window”) and ending up with a lopsided split: select-layout tiled re-tiles everything evenly. Each layout also has a direct key: prefix M-1 even-horizontal, M-2 even-vertical, M-3 main-horizontal, M-4 main-vertical, M-5 tiled.

Tip article: How to reorganize a tmux layout?

Run a tmux command from inside a session

# press: prefix :   then type a command without the leading "tmux"
split-window -h
resize-pane -D 10
source-file ~/.tmux.conf

prefix : opens the command prompt (command-prompt), a one-line input at the bottom of the screen where you type any tmux command without the leading tmux word. It is the interactive twin of the shell CLI: same commands, same flags, run against the server you are attached to. Reach for it to try a command once before committing it to ~/.tmux.conf or binding it to a key, or to run a command that has no default binding. A template can even prompt for input first: command-prompt -p "new name:" "rename-window '%%'" shows the prompt, then substitutes what you type for %% (use %1, %2… to match several -p prompts).

Tip article: How to run a tmux command from inside a session?

Discover and search key bindings

# press: prefix ?   lists every key binding, with a short note, scrollable
tmux list-keys                    # same list, from the shell
tmux list-keys -N                 # only bindings that carry a note (the readable overview)
tmux list-keys -T copy-mode-vi    # one specific key table
tmux list-commands                # syntax and flags of every tmux command

prefix ? runs list-keys -N, a scrollable list of every key binding with a one-line note. It is the fastest way to answer “what does this key do?” without leaving tmux. From the shell, list-keys prints the same table, and -T <table> limits it to one key table (prefix, root, copy-mode-vi, copy-mode), which is how you inspect copy-mode keys or your own binds. list-commands is the companion for the CLI: it prints the full syntax and flags of every command, so it is the reference to reach for when you forget whether resize is -L or -x. These three commands are how every other snippet on this page was checked.

Tip article: How to discover and search tmux key bindings?

A starter ~/.tmux.conf

Config worth keeping in ~/.tmux.conf. This grows along with the cookbook. Reload it without restarting tmux with tmux source-file ~/.tmux.conf, or from inside a session with prefix : then source-file ~/.tmux.conf.

Use C-a as the prefix

unbind C-b
set -g prefix C-a
bind C-a send-prefix   # press C-a twice to drive a nested tmux

C-a matches GNU screen’s prefix and a is easier to reach than b, which is why many setups switch to it. The bind C-a send-prefix line keeps nested sessions usable: a double C-a C-a forwards the prefix to a tmux running inside this one.

Splits on memorable keys

bind | split-window -h   # | is the vertical divider: panes side by side
bind - split-window -v   # - is the horizontal divider: panes stacked

The default prefix % and prefix " still work; these just add keys that match the resulting layout. Append -c "#{pane_current_path}" to either bind to open the new pane in the current pane’s directory.

Reload the config with a key

bind r source-file ~/.tmux.conf \; display-message "config reloaded"

source-file re-reads a config file into the running server, so a changed setting takes effect without killing and restarting tmux. Binding it to a key gives you prefix r after every edit; the \; chains a second command on the same key, here display-message to confirm the reload in the status line. The two commands are separate: \; is a tmux command separator, not shell syntax, so it works the same from the CLI (tmux source-file ~/.tmux.conf \; display-message ok) as inside the config. Without a binding you can always reload by hand with tmux source-file ~/.tmux.conf, or from inside a session with prefix : then source-file ~/.tmux.conf.

Reloading only adds or overrides what the file sets; it does not reset options a removed line used to set, and it re-runs commands like new-window, so keep a config file idempotent (settings and binds, not one-off actions).

Verified on tmux 3.2a.

Tip article: How to reload your tmux config without restarting?

Related