tmux is an [[ISC]] licensed [[Terminal Multiplexer]] written in [[3. Reference/Software/Programming Languages/C|C]]. - [Website](https://tmux.github.io/) (seems to no longer have a dedicated website) - [GitHub](https://github.com/tmux/tmux) - [Documentation](https://github.com/tmux/tmux/wiki) - [Arch Wiki](https://wiki.archlinux.org/title/Tmux) > **tmux** is an [open-source](https://en.wikipedia.org/wiki/Open-source "Open-source") [terminal multiplexer](https://en.wikipedia.org/wiki/Terminal_multiplexer "Terminal multiplexer") for [Unix-like](https://en.wikipedia.org/wiki/Unix-like "Unix-like") [operating systems](https://en.wikipedia.org/wiki/Operating_system "Operating system"). It allows multiple [terminal](https://en.wikipedia.org/wiki/Computer_terminal "Computer terminal") sessions to be accessed simultaneously in a single window. It is useful for running more than one [command-line](https://en.wikipedia.org/wiki/Command-line_interface "Command-line interface") program at the same time. It can also be used to detach [processes](https://en.wikipedia.org/wiki/Process_(computing) "Process (computing)") from their controlling terminals, allowing remote sessions to remain active without being visible. \- via [Wikipedia](https://en.wikipedia.org/wiki/Tmux) # Notability I switched to `tmux` from [[GNU Screen]] probably before 2010. As of [[2025-10-01]] it is still the [[Review - Multiplexers|multiplexer]] that fits my needs. ## Derivatives - Tmux-Sixel - A family of forks of Tmux to improve graphics support - It has been forked and continued by different people again and again over the years, the network graph is wild - https://github.com/JayZhouzzj/tmux - https://github.com/csdvrx/sixel-tmux - https://github.com/jdssl/tmux/tree/sixel-passthrough - https://github.com/j352lin/tmux # Philosophy ## Breaking Changes The `tmux` core team is very sensitive to complaints about breaking changes. And will often respond harshly to users who bring them up. Sometimes they do properly deprecate and announce they're removing things in advance. But usually they make breaking changes and the only way to know it was deprecated was to have read a footnote in a changelog from sometimes years (or *decades*) before you even started using the program. Like yeah it's great that they (sometimes) give people a long time to transition ... but that time is not helpful if no one knows about it. It is like Arthur Dent's house (and Earth) being demolished - "the plans were on display" ... "in the basement". The primary developer claims to believe that every time *any* piece of software is updated, that users should read the update notes and possibly even the source code. This is obviously absurd. Every 2 weeks hundreds of packages might be updated. And each of those is going to be in a different style, granularity, and programming language. It might be feasible for someone who only codes and uses a very minimal operating system, but for most users, it unfortunately isn't. ## Slow Adoption of Standards - Config Search Path (resolved) - Since at least 2015 there were requests to check for its config files in `~/.config` but the core team discussed it previously on the mailing list and rejected the idea. - Dec 2019 it was finally [added](https://github.com/tmux/tmux/commit/15d7e564ddab575dd3ac803989cc99ac13b57198) in the development branch - Feb 2020 it was finally part of an [official](https://raw.githubusercontent.com/tmux/tmux/3.1/CHANGES) release - Apr 2020 it was [fixed](https://github.com/tmux/tmux/commit/f87be8d0521436c47151233f781794dee94fc1df#diff-c949f93d03f44a4217d7a138f9e2e54aR16) to properly read the environment variable instead of being hard coded The user directory has become a dumping ground for every poorly configured application. This isn't `tmux`'s fault. But for me, separating important from junk files in my user folder got frustrating years ago. I use and test a lot of different software and this contributes to why it became more important for me. # Platform Support - Linux - macOS - FreeBSD - NetBSD - OpenBSD[^3] The BSDs are not included as build artifacts but are explicitly supported in the source and available as ports. # Features # Tips See also: [[tmux, a BSD alternative to GNU Screen _ Niall's Weblog]] ## Send Control Codes to Terminal Emulator (passthrough) >it can be forced to pass an escape sequence through by wrapping it in a special form of the DCS sequence with the content prefixed by tmux;. Any \033 characters in the wrapped sequence must be doubled > As of tmux 3.3, the `allow-passthrough` option must be set to `on` or `all` for the passthrough sequence to work. \- tmux FAQ > If set to `on`, passthrough sequences will be allowed only if the pane is visible. If set to `all`, they will be allowed even if the pane is invisible. \- tmux man page ```sh tmux set allow-passthrough on ``` ```sh echo -e "\ePtmux;CONTROL_CODES\e\\" ``` ## Italics For whatever reason `tmux` still defaults to using `screen`'s `$TERM` identifier, which causes some functionality to not work properly. This includes italic font styles. To tell `tmux` to set its own TermInfo add this to your configuration: ```sh set -g default-terminal "tmux-256color" ``` The above will probably be sufficient for most situations but there are a variety of other tricks people have tried: - [True Color (24-bit) and italics with alacritty + tmux + vim (neovim)](https://gist.github.com/andersevenrud/015e61af2fd264371032763d4ed965b6) - [Bold + Italic Font in TMUX](https://chrislabarge.com/posts/bold-italic-tmux/) - [Vim documentation: term](https://vimdoc.sourceforge.net/htmldoc/term.html#t_ZH) See also [[Wezterm#Update Terminfo]] ## Popup Windows Tmux supports popping up centered panes from the `display-popup` command. These popups are closed by pressing the `esc` key or by passing `-E` to the command so that it auto-closes when the inner command exits. ## Get Connected Terminal Emulator Info Similar to `$TERM`, except it returns the value from the terminal emulator connected to tmux, and provides a more detailed and accurate answer. ```sh display-message -d 0 '#{client_termtype}' ``` Using the above [[#Send Control Codes to Terminal Emulator (passthrough)|control code passthrough]] we can query the outer terminal emulator directly using the [[ANSI - Terminals#Terminal Type Query|ANSI DCS terminal info sequence]]: ```sh echo -e "\ePtmux;\e\e[>q\e\\" ``` ## Change Pane Layout Swaps the available panes through multiple layout presets including: even-horizontal, even-vertical, main-horizontal, main-vertical, or tiled. These can also be changed to directly with `ALT-n` where `n` is the number in the order starting at 1. ```sh <prefix> space ``` ## Rotate Pane Contents Rotate the contents of all panes through the existing layout. ```sh <prefix> ctrl+o ``` ## Swap Pane Contents Move the active pane's content to another pane to the right or left. ```sh <prefix> { <prefix> } ``` ## Change Tab Name ### Name tmux distinguishes between names and titles. Windows and sessions have *names*, which may be used to specify them in targets and are displayed in the status line and various lists: the *name* is the tmux identifier for a window or session. A window's *name* is set with one of: 1. A command argument (such as `-n` for `new-window` or `new-session`). 2. An escape sequence (if the `allow-rename` option is turned on): ```sh $ printf '\033kWINDOW_NAME\033\\' ``` 3. Automatic renaming, which sets the *name* to the active command in the window's active pane. See the `automatic-rename` option. ### Titles Only panes have **titles**. A pane's **title** is typically set by the program running inside the pane using an escape sequence (like it would set the xterm(1) window title in X(7)). Windows themselves do not have **titles** - a window's **title** is the **title** of its active pane. tmux itself may set the **title** of the terminal in which the client is running, see the set-titles option. When a pane is first created, its **title** is the hostname. A pane's **title** can be set via the title setting escape sequence, for example: ```sh $ printf '\033]2;My Title\033\\' ``` It can also be modified with the `select-pane -T` command. ## Limit Length of Window Title - https://superuser.com/questions/1395976/how-to-limit-the-maximum-length-of-a-tmux-window-name > A limit may be placed on the length of the resultant string by prefixing it by an =, a number and a colon. Positive numbers count from the start of the string and negative from the end, so `#{=5:pane_title}` will include at most the first 5 characters of the pane title, or `#{=-5:pane_title}` the last 5 characters. ## Print Tmux String to STDOUT Instead of showing the output briefly in the status line, send it to the terminal as a normal command would. This lets you inspect the value of templating variables. ```sh tmux display -p '#T' ``` ## Scrollback To scroll[^1] through a pane's history, press the prefix key (`ctrl-b` by default, but often mapped to `ctrl-a`) and then press one of the following keys: | Command | | | ------- | ---------------------------------------- | | `[` | Enter `copy` mode | | PgUp | Enter `copy` mode and scroll one page up | ### Custom Keybindings There are some keybindings that I use in my own configuration. I only have these enabled in `vi` mode. | Command | | | | ------- | --------------------------------------------- | ----------------------------------------------------------- | | Esc | Enter `copy` mode | This is what [[screen]] uses | | `v` | Start selection | Same as [[Vim]], overwrites existing command | | Enter | Copy to system clipboard and exit `copy` mode | This mapping supports every terminal which `tmux` cannot do | | `y` | Copy selection (without exiting) | [[Vim]] uses `y` to "yank" or copy | ### Copy Mode Vi-like Commands The `copy` mode's [[Vim]]-like command keys, composed mostly of lone keystrokes without modifiers. Enable with: ```sh setw -g mode-keys vi ``` | Command | | | ------- | --------------------------------------------------------------- | | `q` | Exit `copy` mode | | `v` | Toggle visual selection in rectangle mode (*not working right*) | | Space | Start selection | | `V` | Select whole line | | Escape | Cancel/clear selection | | Enter | Copy selection and exit `copy` mode | | `X` | Mark current line | | `A` | Append selection to the top paste buffer and exit `copy` mode | | `r` | Refresh pane contents | | `/` | Search forward | | `?` | Search backwards | | `n` | Search repeat | | `N` | Search repeat opposite direction | ### Copy Mode Vi-like Cursor Movement The `copy` mode's [[Vim]]-like cursor movement keys, composed mostly of lone keystrokes without modifiers. | Command | | | --------------- | -------------------------------------------------------------- | | `h`,`j`,`k`,`l` | Move the cursor by one line or column | | `0` | Go to start of line | | `^` | Go to first-non-space character on line | | `
| Go to end of line | | `g` | Go to first line of the buffer | | `G` | Go to last line of the buffer | | `:` + N | Go to specified line in the buffer, starting from the *bottom* | | `H` | Go to the top line on the page ("home") | | `M` | Go to the middle line on the page | | `L` | Go to the last line on the page | | `ctrl+b` | Scroll up one page | | `ctrl+f` | Scroll down one page | | `ctrl+u` | Scroll up one half page | | `ctrl+d` | Scroll down one half page | | `ctrl+e` | Scroll down 1 line | | `ctrl-y` | Scroll up 1 line | | `{` | Go to the previous paragraph | | `}` | Go to the next paragraph | | `w` | Go to start of next word | | `e` | Go to end of word | | `b` | Go back to start of word | | `W` | Go to start of next non-space | | `E` | Go to end of non-space | | `B` | Go back to start of non-space | | ??? | Go to the previous matching bracket | | `%` | Go to the next matching bracket | | `o` | Go to the other end of the selection | | `;` | Repeat last jump | | `,` | Repeat last jump in the opposite direction | | `M-x` | Jump to the last mark | The "Example" column shows roughly where the cursor would move to. The cursor would actually be *on* a character, not next to one. The concept of a "word" basically treats all alphanumeric characters as part of one class, other non-space characters as another, and whitespace as a third. Each one is grouped together, for instance the following compares different cursor positions after subsequent keystroke. | Command | Example | | | ------- | ---------------------------- | ----------------------------- | | `w` | `→foo‸--‸bar ‸(‸baz) ‸qux` | Go to start of next word | | `e` | `→foo‸--‸bar‸ (‸baz‸)‸ qux‸` | Go to end of word | | `b` | `‸foo‸--‸bar ‸(‸baz‸) ‸qux←` | Go back to start of word | | `W` | `→foo--bar ‸(baz) ‸qux` | Go to start of next non-space | | `E` | `→foo--bar‸ (baz)‸ qux‸` | Go to end of non-space | | `B` | `‸foo--bar ‸(baz) ‸qux←` | Go back to start of non-space | It looks weird but it is really intuitive in practice. This is (pretty much) the same way that [[Vim]] (in `normal` mode) and most [[Unix Shell]]s behave (in `vi` mode). ### Copy Mode Emacs-like Commands | Command | | | ------------- | --------------------------------------------------------------- | | Escape | **Exit `copy` mode** | | `R` | Toggle visual selection in rectangle mode (*not working right*) | | Control+Space | Start selection | | | Select whole line | | `C-g` | Cancel/clear selection | | `M-w` | Copy selection and exit `copy` mode | | `X` | Mark current line | | | Append selection to the top paste buffer and exit `copy` mode | | `r` | Refresh pane contents | | | Search forward | | | Search backwards | | `n` | Search repeat | | `N` | Search repeat opposite direction | Commands in **bold** can be used in Vim movement mode too. ### Copy Mode Emacs-like Cursor Movement See [[#Copy Mode Vim-like Cursor Movement]] for examples. | Command | | | ---------- | --------------------------------------------------------------- | | arrow keys | **Move the cursor by one line or column** | | `C-a` | **Go to start of line** | | `M-m` | Go to first-non-space character on line | | `C-e` | **Go to end of line** | | `M-<` | Go to first line of the buffer | | `M->` | Go to last line of the buffer | | `g` | Go to specified line in the buffer (starting from the *bottom*) | | `M-R` | Go to the top line on the page ("home") | | `M-r` | Go to the middle line on the page | | PgUp | **Scroll up one page** | | PgDown | **Scroll down one page** | | `M-Up` | Scroll up one half page | | `M-Down` | Scroll down one half page | | | Scroll down 1 line | | | Scroll up 1 line | | `M-{` | Go to the previous paragraph | | `M-}` | Go to the next paragraph | | | Go to start of next word | | `M-f` | Go to end of word | | `M-b` | Go back to start of word | | | Go to start of next non-space | | | Go to end of non-space | | | Go back to start of non-space | | `M-C-b` | Go to the previous matching bracket | | `M-C-f` | Go to the next matching bracket | | | Go to the other end of the selection | | `;` | Repeat last jump | | `,` | Repeat last jump in the opposite direction | | `M-x` | Jump to the last mark | Commands in **bold** can be used in Vim movement mode too. ## Mouse Scrolling You can also enable mouse control[^2] to scroll through the output buffer, though this will be taken over by applications like [[Vim]] and others which hook these same escape sequences. ## Escaping Curly Braces in Expressions Inside of `#{` expressions the escape character is *not* backslash, it is `#`! Given this regex: ```ruby last_two_chars = /(.{2})$/ ``` To convert it into one that works inside of a `tmux` expression, the closing repetition curly brace needs to be prefixed with a `#`. Complete example of use: ```sh tmux display -p '#{s/(.{2#})$/x\1/:uid}' ``` # Resources - https://hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/ - https://that.guru/blog/automatically-set-tmux-window-name/ - http://lukaszwrobel.pl/blog/tmux-tutorial-split-terminal-windows-easily - https://qmacro.org/blog/posts/2021/08/06/tmux-output-formatting/ - https://superuser.com/questions/1425920/different-between-set-g-and-setw-g-and-set - https://superuser.com/questions/758843/difference-between-global-server-session-and-window-options ## Cheatsheets - https://tmuxcheatsheet.com/ ## Lists - https://github.com/rothgar/awesome-tmux # References [^1]: http://superuser.com/questions/209437/how-do-i-scroll-in-tmux [^2]: http://superuser.com/questions/210125/scroll-shell-output-with-mouse-in-tmux [^3]: https://man.openbsd.org/tmux.1