Overview
Relevant Files
README- Project overview and installation instructionstmux.h- Core header with data structures and constantstmux.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:
- Sessions - Top-level containers that can be detached and reattached. Each session has a name and contains multiple windows.
- Windows - Logical groupings within a session, each with a name and layout. Windows contain panes and can be navigated independently.
- 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.cserver-client.cclient.ctmux-protocol.hproc.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:
- Client connects to socket via
client_connect()(creates server if needed via lock mechanism) - Client sends identification messages: terminal type, TTY name, environment, stdin/stdout file descriptors
- Server responds with
MSG_READYonce client is identified - Client sends commands via
MSG_COMMAND; server executes and sends output back - 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.cwindow.cwindow.hspawn.ctmux.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
winlinkentries (window references) - Current window:
curwpointer to the active window link - Window stack:
lastwtracks 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_panestructures - 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.
Window Link (winlink)
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 parsingcmd-parse.y– Yacc grammar for command syntaxcmd-queue.c– Command queue and execution enginearguments.c– Argument parsing and handlingcmd-*.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
- flags –
CMDQ_FIRED,CMDQ_WAITING - cb – Optional callback for async operations
Loading diagram...
Execution Flow
cmdq_process() iterates through queued items:
- Target Resolution – Resolve
-tand-sflags to actual sessions/windows/panes - Handler Invocation – Call the command's
exec()function - Return Handling – Process return values:
CMD_RETURN_NORMAL– Continue to next commandCMD_RETURN_ERROR– Remove remaining commands in groupCMD_RETURN_WAIT– Pause until external event (e.g., job completion)
- Hook Execution – Run
after-*hooks ifCMD_AFTERHOOKflag 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.cscreen-write.cscreen-redraw.cgrid.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 datastruct grid_cell- Individual cell containing UTF-8 data, attributes (bold, underline), foreground/background colors, and hyperlink infostruct 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:
- Collecting writes - Characters are accumulated in
write_list(per-line buffers) instead of sending immediately - Flushing strategically -
screen_write_collect_flush()sends batched updates when necessary - 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:
- Setting up
screen_redraw_ctxwith client dimensions and layout - Checking redraw flags to determine what needs updating
- Drawing borders, panes, status bar, and overlays
- 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 parserinput-keys.c- Key code translation to terminal sequencestty.c- Terminal I/O and rendering controltty-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:
- Raw Input Capture (
tty_read_callback): Reads from terminal file descriptor intotty->inevbuffer - Key Recognition (
tty_keys_next): Searches ternary tree built from terminfo capabilities and default sequences - Extended Key Parsing (
tty_keys_extended_key): Handles xterm extended key format with modifiers - Mouse Handling (
tty_keys_mouse): Parses standard, UTF-8, and SGR mouse protocols - 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/endprevents flicker during large updates - Backpressure handling:
tty_block_maybediscards 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.coptions.coptions-table.ckey-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:
- Check the specific scope (pane, window, session)
- If not found, traverse up to parent scope
- 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 operationslayout-set.c- Predefined layout algorithms (even, main, tiled)layout-custom.c- Custom layout parsing and serializationwindow-copy.c- Copy mode and view mode implementationsmode-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_LEFTRIGHTorLAYOUT_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:
- even-horizontal - Panes split left-to-right with equal widths
- even-vertical - Panes split top-to-bottom with equal heights
- main-horizontal - One large pane on top, others below
- main-horizontal-mirrored - One large pane on bottom, others above
- main-vertical - One large pane on left, others on right
- main-vertical-mirrored - One large pane on right, others on left
- 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.