Get Started With Tmux


Before getting started with tmux, let us go over some questions to see if tmux is right for you:

  • Do you use a terminal as part of your your development workflow?
  • Do you use multiple terminals in different tabs or windows to navigate files, edit text, compile and run code, tail log files, push code to repository, and run one-time adhoc commands?
  • Do you work on multiple projects at a time, each with its own set of workflow and environment requirements, and often have to switch context?
  • Do you SSH into remote systems?
  • Have you ever got disconnected from a remote SSH session in the middle of a task that you were running and monitoring?

If your answer to any of the questions is an yes, then tmux is for you!

What Is Tmux?

Tmux is a terminal multiplexer. You can run multiple terminal programs inside tmux, all of which can be accessed from the single terminal that is running tmux. This is called a tmux session. You can have multiple such tmux sessions, say one for each project you are working on. You can detach from a tmux session and later reattach to it. When you run programs in a tmux session, the session remains intact and continues running your programs even if you detach from the session. You can start where you left off the previous day, or you can even access the session from a different computer.

If you have worked with remote servers using remote desktop connection, you will be familiar with how the applications that you open in the server are kept as is even when you disconnect. You can then resume the session by reconnecting to it. You can even reconnect to the remote desktop using a different client or a different computer. Tmux helps you to achieve similar results for terminal sessions.

When you run the tmux command, tmux starts a server process if it is not already running, and a tmux session is created. The tmux server runs as a background process in your system and manages all the terminals running inside tmux. You can create additional sessions in the tmux server if needed by using the tmux command. A tmux session is a group of related tmux windows. Think of all the terminal tabs you open to get to your development workflow of a particular project. All these can be grouped together as windows in a tmux session. A tmux window comprises of one or more panes. Each pane is like a terminal by itself. Panes can be organized vertically, horizonatally, or a mix of both. Think of editing, compiling, and executing code on the left pane while tailing a related log file on the right pane as an example. At any given time, there is one active pane where the commands you type are accepted. You can switch between panes, windows, and sessions as needed.

Let us now see how to get started with tmux.

Install Tmux

If you are on a Debian, Ubuntu, or another Debian-based system, enter the following command:

sudo apt-get install tmux

If you are on macOS with Homebrew installed, enter the following command:

brew install tmux

If you are on any other system or environment, see Tmux Wiki: Installing for installation details.

Create, Detach From, and Attach to Sessions

To create a new tmux session, enter the following command:

tmux

Run some program in this session. Maybe tail a log file. This will help with the next steps where you detach and reattach to a session.

To detach your terminal from a tmux session, enter the following command:

tmux detach

Tmux will keep your session intact. All your programs keep running on the server. To attach your terminal as a client back to an existing tmux session, enter the following command:

tmux attach

Note that it is not necessary to type out the tmux commands in full. You can use any unambiguous abbreviation of the commands. For example, tmux det and tmux at are equivalent to tmux detach and tmux attach, respectively.

By default, the new sessions are named 0, 1 and so on. To choose another name for the session, use the following command to start a new session:

tmux new -s <session-name>

Here <session-name> denotes the name of the session you choose. You can also rename an existing session with this command:

tmux rename <new-name>

If you have multiple tmux sessions running and you want to target a specific session to rename, you can use the -t option to specify the session name you want to target, like this:

tmux rename -t <session-name> <new-name>

Without the -t option, it renames the current session.

The -t option is useful for attaching to a specific tmux session too when multiple tmux sessions are running. By default tmux attach attaches to the most recently used session that is not attached. You can attach to a specific session like this:

tmux attach -t <session-name>

Sometimes while attaching to a tmux session, you might want to detach the other clients to connected to it. That can be achieved with the following commands:

tmux attach -d
tmux attach -d -t <session-name>

While you are inside a tmux session, you can also change the name of the attached session by using the key-sequence C-b $ which prompts for a new name for the session. The key-sequence C-b $ is bound to the rename command that we saw above. Similarly, the key-sequence C-b d is bound to the detach command. To understand how tmux key bindings and commands work together, read the next two sections.

Understand Tmux Prefix Keys

Once you attach your terminal as a client to a tmux session, all keystrokes are sent to the program running in the active pane of the current tmux window. By default it is your shell. For key-sequences that control tmux itself, a special key-sequence called the prefix key must be pressed. By default the prefix key is C-b. Here C denotes the Ctrl modifier key, i.e., to enter C-b, press and hold the Ctrl key, then press and release the b key, and finally release the Ctrl key. When the prefix key is entered like this, tmux waits for another keystroke or key-sequence to determine which tmux command needs to be executed. For example, when we enter C-b $ to rename the current session, C-b is the prefix key that tells tmux that we are going to invoke a tmux command and then the $ keystroke tells tmux that we want to invoke the tmux rename command.

Key Bindings, Commands, and Command Prompt

The key-sequence C-b ? shows the list of key bindings along with short descriptions about what they do. The output is shown in the view mode in the active pane. The pane in view mode has its own key bindings which don't need the prefix key. By default the view mode has Emacs key bindings that you can use to navigate the output. However, it can be configured to use vi key bindings too.

Any time key bindings are used, they run the underlying tmux commands. For example C-b c runs the neww command that creates a new window. Commands can be run directly from the shell as we saw when we created new session using the tmux new command. Just like any other Unix commands, tmux commands have zero or more command line options that may or may not accept arguments. For example, the attach command that we saw earlier accepts the -d option to detach any other clients that are attached to the session. This option does not require an argument. The attach command also accepts another option -t that requires an argument to specify the name of the target session you want to attach to.

You might mostly want to use the key bindings to manipulate tmux because they are convenient. However, the tmux commands can be useful especially when you want to perform a task that is supported only by an option. The tmux commands are also useful if you want to write a script to manipulate tmux.

Tmux commands can be run from the shell as we have seen so far. There is also an interactive command prompt available within tmux that you can open using C-b :. This prompt accepts tmux commands. For example, C-b :neww creates a new window in the attached session. Some of the tmux commands run in this manner show the output in the view mode in the active pane. For example, C-b :ls shows the list of all available sessions.

Create New Windows in a Session and Switch Between Them

You can create new window in a session by using C-b c or C-b :neww. Each window is numbered starting from 0. Every new window is created at the first available index. This means that if there are gaps in the list of window numbers, a new window occupies the first available number in the gaps. The new window thus created becomes the current window of the session. The current window is identified by the * suffix in its name and the previous window is identified by the - suffix in its name.

If you want to create a new window but not make it the current window, you can do so with the -d option like this: C-b :neww -d. You can also create a window at a specific index by using the -t option like this: C-b :neww -t 9.

C-b 0 takes you to window 0, C-b 1 takes you to window 1, and so on until C-b 9. C-b ' prompts for an index to switch to that window. This can be useful if you want to go to windows with indices greater than 9. C-b p takes you to the previous window and C-b n takes you to the next window in the window list by index. C-b l takes you to the last window that was active before the current one. This is very useful for alternating between two windows again and again.

To rename the current window, you can use C-b :renamew <new-name> or C-b , which prompts for the new name for the window.

I find it convenient not to exceed 10 windows (indices 0-9) in a session, so that I can switch between them using C-b <number>.

Create New Panes in a Window and Switch Between Them

You can create a new pane by splitting a pane in a window. C-b % splits the current pane into left and right panes. C-b " splits the current pane into top and bottom panes. These new panes can be split again and again recursively.

C-b o takes you to the next pane by number. You can use C-b <Up>, C-b <Down>, C-b <Left>, or C-b <Right> to go to the pane above, below, left, or right, respectively, of the active pane. These keys wrap around the window, so to get to the left most pane from the right most pane, you can press C-b <Right>.

List Sessions and Switch Between Them

You can see a list of available sessions by executing the following command on the shell:

tmux ls

You can then attach to the session you are interested in. Another way to do this is inside tmux using the tree mode. You can use the key sequence C-b s or enter C-b :ls to go to the tree mode that shows the list of sessions with the attached session selected. Keys to control tree mode do not need prefix keys. The list of sessions can be navigated using the <Up> and <Down> keys. The Emacs key bindings C-p and C-n work too. If vi key bindings are configured then j and k work too. Press the space bar to expand or collapse the list of windows under each session. Press the enter key to go to a session or window.

Configure Tmux

You can configure tmux by defining the configuration in a file called .tmux.conf in your home directory. This configuration comes into effect when the tmux server is first started. When you modify this configuration, be sure to restart your tmux server. A graceful way to do so is to quit all windows and sessions, and then start a new tmux session. A quick and dirty way to do so is with the following commands:

tmux kill-server tmux

Let us see some of the useful lines of configuration that can go into ~/.tmux.conf.

  • Set C-j as the secondary prefix key.

    set -g prefix2 C-j

    This allows you to control tmux with C-j in addition to C-b. I find C-j to be a more convenient prefix key because the j key exists in the home row of the keyboard right under the index finger.

  • Send the secondary prefix key to a window, i.e., send C-j when C-j C-j is pressed.

    bind-key C-j send-prefix -2

    This allows you to send C-j to a program running within tmux.

  • Customize kill key-sequences such that they do not ask for confirmation.

    bind-key & kill-window
    bind-key x kill-pane
    

    The key binding C-b & kills the current window and the key binding C-b x kills the current pane. However, without the configuration specified above, you will be prompted to confirm the operation with a y or n. For example: C-b x in pane number 2, will prompt you with kill-pane 2? (y/n). It is convenient to be able to kill a window or a pane without having to go through a confirmation prompt.

  • Open a new pane or window with the current directory of the current pane, not the directory in which the first tmux session was started.

    bind '"' split-window -c "#{pane_current_path}"
    bind % split-window -h -c "#{pane_current_path}"
    bind c new-window -c "#{pane_current_path}"
    

    Here the -c option is used to specify the start directory for the new pane. The current path is represented with the replacement variable pane_current_path in the commands above. The -h option specifies that the window should be split into left and right panes.

  • Use 256 colors in tmux.

    set -g default-terminal screen-256color

    By default tmux sets the TERM environment variable to screen. With this setting, most programs will support 8 colors only. For example, Vim syntax highlighting will use 8 colors only. To configure tmux to set the terminal to use 256 colors, set the TERM environment variable to screen-256color.

    With this configuration, programs that use colors can make use of all 256 colors. Here is a quick shell command to test how the 256 look in the terminal:

    for i in {0..255}; do tput setaf $i; printf "$i "; done
    
  • Use vi key bindings in tmux.

    set -g mode-keys vi

    By default, tmux uses Emacs key bindings in various modes, e.g., view-mode, tree-mode, etc. If you use Vim instead of Emacs, it is convenient to set vi key bindings.

I have made my tmux configuration available at https://github.com/sunainapai/dotfiles/blob/master/tmux.conf.

References