Install

tmux/tmux

tmux - Terminal Multiplexer

Last updated on Dec 18, 2025 (Commit: 54202fc)

Overview

Relevant Files
  • README - Project overview and installation instructions
  • tmux.h - Core header with data structures and constants
  • tmux.c - Main entry point and initialization

tmux is a terminal multiplexer that enables multiple terminals to be created, accessed, and controlled from a single screen. It allows sessions to be detached and reattached, enabling persistent terminal environments that survive disconnections.

Core Architecture

tmux operates on a hierarchical model with three main levels:

  1. Sessions - Top-level containers that can be detached and reattached. Each session has a name and contains multiple windows.
  2. Windows - Logical groupings within a session, each with a name and layout. Windows contain panes and can be navigated independently.
  3. Panes - Individual terminal instances within a window. Multiple panes can be arranged in various layouts (split horizontally, vertically, etc.).

Key Components

Server-Client Architecture: tmux uses a client-server model where a single server process manages all sessions, and clients connect to it. This enables multiple users to attach to the same session and see synchronized updates.

Command System: Commands are parsed and executed through a queue system (cmd.c, cmd-*.c files). Each command has a definition specifying its arguments, flags, and execution logic.

Terminal Handling: The tty.c module manages terminal I/O, including cursor positioning, color handling, and mouse input. Terminal capabilities are queried via termcap/terminfo.

Screen Management: Virtual screens (screen.c) maintain grid-based content with attributes (colors, styles). The grid.c module stores terminal history and cell data efficiently.

Input Processing: The input.c module parses terminal escape sequences and converts them into internal events. Key bindings are matched against user input in key-bindings.c.

Platform Support

tmux runs on OpenBSD, FreeBSD, NetBSD, Linux, macOS, and Solaris. Platform-specific code is isolated in osdep-*.c files for features like PTY handling and process management.

Dependencies

  • libevent 2.x - Event loop library for async I/O
  • ncurses - Terminal capability database and utilities
  • yacc/bison - For parsing command syntax

Build System

The project uses autoconf/automake for configuration and building. Run ./configure && make to build from source.

Loading diagram...

Architecture & Client-Server Model

Relevant Files
  • server.c
  • server-client.c
  • client.c
  • tmux-protocol.h
  • proc.c

Tmux uses a client-server architecture where a single server process manages all sessions, windows, and panes, while multiple clients connect to it via Unix domain sockets. This design allows persistent sessions that survive client disconnections.

Server Architecture

The server is a long-running daemon that manages the entire tmux state. It initializes by creating a Unix domain socket at a configurable path (typically ~/.tmux.sock), then enters an event loop that processes client connections and commands.

Key server components:

  • Socket listener (server_create_socket, server_accept): Accepts incoming client connections on the Unix socket
  • Client management (server_client_create, server_client_lost): Tracks connected clients and their state
  • Session/window/pane hierarchy: Maintains all sessions, windows, and panes in global data structures
  • Event loop (server_loop): Processes command queues, client events, and window updates
  • Signal handling: Responds to SIGTERM, SIGCHLD, SIGUSR1, and SIGUSR2 for graceful shutdown and socket reloading

Client-Server Communication

Communication uses message passing over the Unix socket via the imsg protocol (inter-process messaging). The protocol is defined in tmux-protocol.h with message types ranging from identification to commands to file I/O operations.

Connection lifecycle:

  1. Client connects to socket via client_connect() (creates server if needed via lock mechanism)
  2. Client sends identification messages: terminal type, TTY name, environment, stdin/stdout file descriptors
  3. Server responds with MSG_READY once client is identified
  4. Client sends commands via MSG_COMMAND; server executes and sends output back
  5. Client can detach or exit; server maintains session state

Message categories:

  • Identification (100-112): Terminal info, environment, file descriptors
  • Commands (200-221): Commands, detach, exit, resize, suspend
  • File I/O (300-307): Read/write operations for capture-pane and similar features

Data Structures

The server maintains three core hierarchies:

Session (struct session)
  ├─ Window (struct window)
  │   ├─ Pane (struct window_pane)
  │   │   └─ PTY + screen buffer
  │   └─ Layout
  └─ Options + environment

Client (struct client)
  ├─ Attached session reference
  ├─ TTY state
  ├─ Command queue
  └─ Peer connection

Each pane runs a shell process with its own PTY. The server polls pane output, parses escape sequences, and maintains a virtual screen for each pane. When a client attaches, the server sends the current screen state and updates it as changes occur.

Event-Driven Processing

Both client and server use libevent for asynchronous I/O. The server's main loop processes:

  • Incoming messages from clients
  • Command queue execution
  • Window/pane updates and redraws
  • Child process signals (pane exits)
  • Periodic maintenance (hourly tidying)

Clients similarly use event loops to handle server messages, terminal input, and resize events.

Socket and Access Control

The server socket permissions are dynamically adjusted based on session attachment state. When sessions are attached, execute permissions are added to allow new clients to connect. The server also supports access control lists (ACLs) via server_acl_join() to restrict which users can connect.

Sessions, Windows & Panes

Relevant Files
  • session.c
  • window.c
  • window.h
  • spawn.c
  • tmux.h

tmux organizes terminal sessions into a three-level hierarchy: sessions contain windows, which contain panes. This structure enables flexible terminal management with persistent sessions that can be detached and reattached.

Session Structure

A session (struct session) is the top-level container that persists independently of client connections. Key properties include:

  • Identity: Unique ID and user-assigned name
  • Windows: Red-black tree of winlink entries (window references)
  • Current window: curw pointer to the active window link
  • Window stack: lastw tracks recently visited windows for quick navigation
  • Environment: Session-specific environment variables and options
  • Timing: Creation time, last attached time, and activity tracking

Sessions are created via session_create() and stored in a global red-black tree. When a session is destroyed, all its windows are unlinked and cleaned up.

Window Structure

A window (struct window) is a logical container within a session that holds multiple panes arranged in a layout. Key properties include:

  • Identity: Unique ID and user-assigned name
  • Panes: Doubly-linked list of window_pane structures
  • Active pane: Pointer to the currently focused pane
  • Layout: Root layout cell defining pane arrangement and dimensions
  • Dimensions: Size in cells (sx, sy) and pixels (xpixel, ypixel)
  • References: Count of sessions linking to this window (windows can be shared)

Windows are created via window_create() and stored in a global red-black tree indexed by ID. Multiple sessions can reference the same window through winlink entries.

The winlink structure is a session-specific reference to a window. It acts as a bridge between sessions and windows:

  • Index: Position in the session's window list (e.g., window 0, 1, 2)
  • Session pointer: Reference back to the owning session
  • Window pointer: Reference to the actual window
  • Flags: Alert flags (bell, activity, silence) and visited status

This indirection allows the same window to be linked into multiple sessions with different indices and alert states.

Pane Structure

A pane (struct window_pane) is an individual terminal instance. Key properties include:

  • Identity: Unique ID and active point counter
  • Dimensions: Size in cells and pixel offsets within the window
  • PTY: File descriptor for the pseudo-terminal
  • Screen buffer: Terminal content and attributes
  • Layout cell: Position within the window's layout tree
  • Flags: Redraw, focus, input, exit, and style change indicators

Panes are created via window_add_pane() and stored in a global tree for quick lookup by ID.

Hierarchy Diagram

Loading diagram...

Key Operations

Attaching a window to a session (session_attach()): Creates a new winlink entry in the session's window tree, linking it to an existing or new window.

Detaching a window (session_detach()): Removes the winlink from the session. If the window has no remaining references, it is destroyed.

Spawning a pane (spawn_window() in spawn.c): Creates a new window with an initial pane, or adds a pane to an existing window. Sets up the PTY, shell environment, and screen buffer.

Window sharing: Multiple sessions can reference the same window through separate winlink entries, enabling synchronized multi-user sessions.

Command Processing & Execution

Relevant Files
  • cmd.c – Command registry and parsing
  • cmd-parse.y – Yacc grammar for command syntax
  • cmd-queue.c – Command queue and execution engine
  • arguments.c – Argument parsing and handling
  • cmd-*.c – Individual command implementations

Overview

The command system is the core execution engine for tmux. It handles parsing user input, validating arguments, queuing commands, and executing them in order. Commands flow through three main stages: parsing, queueing, and execution.

Command Registry

All available commands are registered in cmd_table[] in cmd.c. Each command is defined by a cmd_entry structure containing:

  • name – Full command name (e.g., "new-session")
  • alias – Short alias (e.g., "new")
  • args – Argument specification for parsing
  • usage – Help text
  • source/target – Target resolution flags (session, window, pane)
  • flags – Behavior flags (CMD_STARTSERVER, CMD_AFTERHOOK, etc.)
  • exec – Function pointer to execution handler

Example from cmd-new-session.c:

const struct cmd_entry cmd_new_session_entry = {
    .name = "new-session",
    .alias = "new",
    .args = { "Ac:dDe:EF:f:n:Ps:t:x:Xy:", 0, -1, NULL },
    .target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
    .flags = CMD_STARTSERVER,
    .exec = cmd_new_session_exec
};

Parsing Pipeline

1. Syntax Parsing (cmd-parse.y)

The Yacc grammar tokenizes input and builds a parse tree. It handles:

  • Command statements separated by newlines or semicolons
  • Conditional blocks (if/elif/else/endif)
  • Nested command blocks in braces
  • Format strings and variable expansion

2. Command Lookup (cmd_find())

Searches cmd_table[] for a matching command by name or alias. Supports prefix matching (e.g., new-s matches new-session).

3. Argument Parsing (args_parse())

Validates arguments against the command's specification. Handles:

  • Flag options (-a, -t target)
  • Optional and required arguments
  • Custom argument parsers for complex commands

Command Queue & Execution

Commands are queued as cmdq_item structures, each containing:

  • cmd – The parsed command
  • state – Execution context (formats, key event, target)
  • client – Associated client connection
  • flagsCMDQ_FIRED, CMDQ_WAITING
  • cb – Optional callback for async operations
Loading diagram...

Execution Flow

cmdq_process() iterates through queued items:

  1. Target Resolution – Resolve -t and -s flags to actual sessions/windows/panes
  2. Handler Invocation – Call the command's exec() function
  3. Return Handling – Process return values:
    • CMD_RETURN_NORMAL – Continue to next command
    • CMD_RETURN_ERROR – Remove remaining commands in group
    • CMD_RETURN_WAIT – Pause until external event (e.g., job completion)
  4. Hook Execution – Run after-* hooks if CMD_AFTERHOOK flag set

Key Concepts

Command Groups – Multiple commands from one source share a group ID. If one fails, all subsequent commands in the group are removed.

Async Operations – Commands like run-shell return CMD_RETURN_WAIT and set a callback. The queue resumes when the callback clears the CMDQ_WAITING flag.

Target Finding – Commands specify target types (CMD_FIND_SESSION, CMD_FIND_PANE, etc.). The queue resolves these to actual objects before execution.

Terminal Rendering & Screen Management

Relevant Files
  • screen.c
  • screen-write.c
  • screen-redraw.c
  • grid.c

Terminal rendering in tmux follows a three-layer architecture: the grid (data model), the screen writer (buffering and optimization), and the redraw system (terminal output).

Grid: The Data Model

The grid is the fundamental data structure representing terminal content. Each grid contains cells organized into lines, with support for scrollback history. Key structures:

  • struct grid - The entire grid with dimensions (sx, sy), history size (hsize), and line data
  • struct grid_cell - Individual cell containing UTF-8 data, attributes (bold, underline), foreground/background colors, and hyperlink info
  • struct grid_line - A line of cells with compact storage for common cells and extended storage for complex ones

The grid uses a memory-efficient encoding: simple ASCII cells use grid_cell_entry (4 bytes), while complex cells (wide characters, RGB colors, links) use grid_extd_entry (extended storage). History is managed by hsize (current history lines) and hlimit (maximum history).

Screen Writer: Buffering & Optimization

The screen writer (screen_write_ctx) batches updates before sending them to the terminal. This improves performance by:

  1. Collecting writes - Characters are accumulated in write_list (per-line buffers) instead of sending immediately
  2. Flushing strategically - screen_write_collect_flush() sends batched updates when necessary
  3. Synchronized updates - Uses terminal sync mode to prevent flicker during large redraws

Key operations:

screen_write_cell()      // Write a single cell to grid and terminal
screen_write_putc()      // Write a character
screen_write_linefeed()  // Handle line wrapping and scrolling
screen_write_clearscreen() // Clear entire screen

The writer maintains cursor position (cx, cy), scroll region bounds (rupper, rlower), and terminal modes (wrap, insert, etc.).

Redraw System: Terminal Output

The redraw system converts grid data into terminal commands. The flow:

Loading diagram...

screen_redraw_screen() orchestrates full redraws by:

  1. Setting up screen_redraw_ctx with client dimensions and layout
  2. Checking redraw flags to determine what needs updating
  3. Drawing borders, panes, status bar, and overlays
  4. Using tty_draw_line() to render each visible line

The tty_ctx structure bridges screen operations and terminal commands, carrying context like cursor position, cell data, and callbacks for client-specific rendering.

Optimization: Synchronized Updates

Terminal sync mode prevents flicker by batching updates:

tty_sync_start()  // Begin sync block
// ... multiple tty_write() calls ...
tty_reset()       // End sync block

This wraps updates in terminal escape sequences, ensuring the display updates atomically.

Input Processing & Terminal Control

Relevant Files
  • input.c - ANSI/VT100 escape sequence parser
  • input-keys.c - Key code translation to terminal sequences
  • tty.c - Terminal I/O and rendering control
  • tty-keys.c - Terminal key input parsing and handling

Overview

Input processing in tmux follows a bidirectional flow: terminal input (keys, mouse, responses) flows inward through the TTY layer, while application output (escape sequences) flows outward to the terminal. The system uses a state machine parser for ANSI sequences and a ternary tree for efficient key lookup.

Input Flow: Terminal → Application

Loading diagram...

Key stages:

  1. Raw Input Capture (tty_read_callback): Reads from terminal file descriptor into tty->in evbuffer
  2. Key Recognition (tty_keys_next): Searches ternary tree built from terminfo capabilities and default sequences
  3. Extended Key Parsing (tty_keys_extended_key): Handles xterm extended key format with modifiers
  4. Mouse Handling (tty_keys_mouse): Parses standard, UTF-8, and SGR mouse protocols
  5. Device Responses (tty_keys_device_attributes*): Processes terminal capability queries

Output Flow: Application → Terminal

Loading diagram...

ANSI Parser State Machine

The parser in input.c implements a VT100-compatible state machine with states:

  • ground: Normal text output
  • esc_enter: Escape sequence initiated
  • csi_enter/parameter/intermediate: Control Sequence Introducer processing
  • dcs_enter/handler/escape: Device Control String handling
  • osc_string: Operating System Command (titles, clipboard)
  • apc_string: Application Program Command

Each state has transitions triggered by character ranges, executing handlers like input_csi_dispatch_sgr for graphics attributes or input_csi_dispatch_winops for window operations.

Key Translation System

input-keys.c maintains a tree of key sequences mapped to internal key codes. The system supports:

  • Standard VT10x keys: Function keys, arrow keys, keypad
  • Xterm modifiers: Shift, Meta, Ctrl combinations via templates like \033[1;_P
  • Extended keys: UTF-32 codepoints with modifier encoding
  • Mouse protocols: Standard (\033[M), UTF-8, SGR (\033[<)

The input_key_build() function constructs the tree from terminfo capabilities and user-defined keys.

Terminal Control & Synchronization

tty.c manages the terminal state machine:

  • Mode tracking: Cursor visibility, mouse modes, bracketed paste, focus events
  • Synchronized output: tty_sync_start/end prevents flicker during large updates
  • Backpressure handling: tty_block_maybe discards output when buffer exceeds threshold
  • Feature detection: Queries terminal for sixel, margins, clipboard support via DA responses

The TTY layer also handles cursor positioning, color management, and ACS (alternate character set) rendering.

Configuration & Options System

Relevant Files
  • cfg.c
  • options.c
  • options-table.c
  • key-bindings.c

Overview

Tmux's configuration system consists of three interconnected layers: configuration file loading, a hierarchical options system, and key binding management. These components work together to provide flexible runtime customization while maintaining a clean separation between configuration parsing, option storage, and input handling.

Configuration File Loading

Configuration files are loaded during server startup via cfg.c. The system supports multiple configuration files (typically /etc/tmux.conf and ~/.tmux.conf) that are parsed and executed sequentially. Key aspects:

  • Startup Sequence: start_cfg() initializes configuration loading before any client commands execute
  • Command Parsing: Each line in a config file is parsed as a tmux command using the command parser
  • Error Handling: Parse errors and command failures are collected and displayed to the user
  • Blocking Mechanism: The initial client is blocked until all configuration files complete, ensuring commands run after setup

The load_cfg() and load_cfg_from_buffer() functions handle both file-based and in-memory configuration loading, supporting dynamic configuration reloading via the source-file command.

Options System Architecture

The options system (options.c and options-table.c) implements a hierarchical, scope-aware storage mechanism:

Scopes: Options exist at four levels with inheritance:

  • Server: Global settings affecting the entire tmux server
  • Session: Settings for individual sessions (inherit from global session options)
  • Window: Settings for windows (inherit from global window options)
  • Pane: Settings for individual panes

Option Types: Seven distinct types with validation:

  • String, Number, Key, Colour, Flag, Choice, Command

Storage Structure: Red-black trees provide O(log n) lookup for option entries. Array options use a separate tree structure for indexed access.

Key Bindings System

Key bindings (key-bindings.c) map keyboard input to command sequences:

  • Key Tables: Named tables organize bindings (e.g., root, copy-mode, copy-mode-vi)
  • Default Bindings: Preserved separately to support reset operations
  • Binding Metadata: Each binding stores the key code, command list, repeat flag, and optional note
  • Dispatch: key_bindings_dispatch() executes bound commands with proper state management

Integration Flow

Loading diagram...

Option Lookup and Inheritance

When an option is requested, the system searches the hierarchy:

  1. Check the specific scope (pane, window, session)
  2. If not found, traverse up to parent scope
  3. Return value or use default from options table

This enables flexible configuration where users set global defaults and override at specific scopes.

Hooks and Dynamic Updates

Options marked as hooks execute command lists when triggered. When certain options change, options_push_changes() notifies affected components (e.g., redrawing clients when status-related options change).

Layouts & Window Modes

Relevant Files
  • layout.c - Core layout tree management and cell operations
  • layout-set.c - Predefined layout algorithms (even, main, tiled)
  • layout-custom.c - Custom layout parsing and serialization
  • window-copy.c - Copy mode and view mode implementations
  • mode-tree.c - Generic tree-based mode framework

Layout System Architecture

The layout system organizes panes within a window using a tree of cells. Each window has a layout_root pointer to a tree structure where:

  • Container cells (LAYOUT_LEFTRIGHT or LAYOUT_TOPBOTTOM) hold child cells in a queue
  • Leaf cells (LAYOUT_WINDOWPANE) contain a single pane
  • Each cell tracks position (xoff, yoff) and size (sx, sy)

This hierarchical structure allows arbitrary nesting of horizontal and vertical splits.

Predefined Layouts

The layout_sets array in layout-set.c defines seven built-in layouts:

  1. even-horizontal - Panes split left-to-right with equal widths
  2. even-vertical - Panes split top-to-bottom with equal heights
  3. main-horizontal - One large pane on top, others below
  4. main-horizontal-mirrored - One large pane on bottom, others above
  5. main-vertical - One large pane on left, others on right
  6. main-vertical-mirrored - One large pane on right, others on left
  7. tiled - Grid layout with configurable max columns

Each layout function rebuilds the tree by creating cells, distributing panes, and calling layout_spread_cell() to calculate final dimensions.

Custom Layouts

Custom layouts are serialized as strings (e.g., 1234,100x50,0,0{50x50,0,0,1,50x50,50,0,2}) and can be:

  • Dumped via layout_dump() - converts tree to string with checksum
  • Parsed via layout_parse() - reconstructs tree from string, validates checksum

This enables saving and restoring complex pane arrangements.

Window Modes

Window modes provide alternative input/output handlers for panes. The struct window_mode defines callbacks:

struct window_mode {
    const char *name;
    struct screen *(*init)(struct window_mode_entry *, ...);
    void (*free)(struct window_mode_entry *);
    void (*resize)(struct window_mode_entry *, u_int, u_int);
    void (*key)(struct window_mode_entry *, struct client *, ...);
    const char *(*key_table)(struct window_mode_entry *);
    void (*command)(struct window_mode_entry *, ...);
    struct screen *(*get_screen)(struct window_mode_entry *);
};

Each pane maintains a TAILQ_HEAD(modes) stack of active modes. When a mode is entered, a window_mode_entry is pushed; when exited, it's popped.

Built-in Modes

  • copy-mode - Text selection and search (window-copy.c)
  • view-mode - Read-only copy mode variant
  • tree-mode - Hierarchical list browser (mode-tree.c)
  • buffer-mode - Paste buffer management
  • client-mode - Client list browser
  • clock-mode - Analog clock display
  • customize-mode - Option editor

Mode Tree Framework

mode-tree.c provides a generic framework for tree-based modes. It handles:

  • Building hierarchical item lists via callback
  • Rendering with indentation and filtering
  • Keyboard navigation and search
  • Preview panes for selected items
  • Custom menu actions

This powers buffer, client, and session browsers.