Do you want a powerful, flexible, and automated terminal experience?

Let me introduce you to tmux. It’s one of the most important tool for my development environment.

If you never heard about tmux, fear not, this article will explain the core ideas:

What is tmux, and what benefits it can bring you.

How to configure tmux, step by step.

What are the best tmux plugins you can use.

How to automate the creation of tmux sessions.

While reading, I strongly advise you to have tmux open on the side to play along with it.

I advise you as well to create your own cheatsheet with the commands you’ll learn today. They will be easier to memorize if you write them, and you’ll have a personalized reference when your memory will fail you.

A last thing: it can be useful if you know already the basics of Vim, since the configuration we will build together mimic some Vim keystrokes. It’s however not mandatory.

What’s tmux?

Installing tmux

Before I can show you what’s tmux, we surprisingly need to install it. If you use a Unix/Linux based system, you can find it via your usual package manager:

Arch linux: sudo pacman -S tmux

Ubuntu / Debian: sudo apt-get install tmux

Fedora / CentOS: sudo dnf install tmux

Mac OS: brew install tmux

What Is tmux?

tmux in action

tmux is a terminal multiplexer. You can create multiple tmux sessions totally independent of your terminal emulator.

If you already know GNU-screen (another terminal multiplexer), tmux is similar but more powerful and easier to config.

To understand the concept, let’s try to create a tmux session . Open a terminal and type tmux . A new session will be created and attached to a client, your terminal.

You can list every session currently running by typing tmux list-sessions . Normally, you’ll only have one session , with the number 0 as name.

Now, let’s run this in your terminal:

while :; do echo 'This will never end, except if you hit CTRL+C'; sleep 1; done

This loop will run forever if you don’t stop it! Now, close the terminal. Did the loop stopped? Not at all! It continues to run in the background, because the tmux session itself is still alive!

You don’t believe me? You’re right; you need to experiment by yourself.

Again, open a new terminal and type tmux list-sessions . You will see the session_name displayed before a colon ( : ). Normally, it’s 0 . Reattach the session to your freshly opened terminal by typing tmux attach-session <session name> .

Your infinite loop is back, and you can see that it was still running in the background! Let’s really kill it this time, by pressing ctrl+c .

“That’s nice and all your zombie stories, but what’s the point?” could ask many readers. Well, let’s find out.

Why Using tmux?

Background Operations

As we saw above, you can detach a tmux session from a client (the terminal) and you can attach it back. It means that you can run whatever you want in the background, even if you have no terminal open.

Let’s imagine that you need to run a very long script on your remote server. You could:

Connect to your remote server via SSH. Launch tmux on the remote server. Run a script which takes hours. Close the SSH connection. The script will still run on the remote server, thanks to tmux! Switch off your own computer and go home.

More Terminals! Everywhere!

Tmux allows you to create multiple terminals on a single screen. This is the functionality I use the most.

You might think: “Well, great, many terminal emulators can do the same, like terminator”.

That’s true, but tmux is more powerful and consume less resources. You can configure it easily and precisely, according to your specific needs.

It works very well with Vim too, which makes it mandatory if you want to create a mouseless development environment.

Note If you want to know how to build a complete Mouseless Development Environment, it’s the subject of the book I’m writing

Protection Against Terminal Crashes

Since your tmux session is independent of your terminal, you don’t need to worry anymore if you close it or even if it crashes. You can always reattach your session afterward, in a new and shiny terminal!

Saving tmux Sessions

It’s possible to save tmux sessions in a file and reopen them later, even after switching off your computer.

Remote Pair Programming

A tmux session can be attached to many clients (terminals), even via SSH. Which means that you can do pair programming with another developer using tmux and Vim, by sharing the same session !

How to use tmux?

General Organization

Let’s see in more details how to use tmux. This part should answer many potential questions you might have, at that point.

Here’s an example what kind of hierarchy you can with tmux:

When you launch tmux, it will create a tmux-server , a session , a window and a pane .

tmux Server

The tmux server manage every single tmux session . If you kill it, you kill every session as well. You can try it by yourself with the command tmux kill-server .

Sessions

We spoke about sessions before. You can detach them from a client (and let them run in the background) and attach them back.

Windows

In tmux, a window represent an entire screen. You can have multiple windows open in one session . You can access each window via a tab in the tmux status bar, at the bottom.

Panes

You can split your windows in panes to have multiple terminals on one screen. These panes are independent by default, but you can synchronize them too.

tmux Workflow

tmux Keystrokes

Let’s speak about the workflow itself. It’s very easy to use tmux with the keyboard only: that’s why it’s part of my mouseless development environment. Another great strength!

However, tmux needs a way to separate its own shortcuts with the CLIs’s shortcuts running in the different panes . Imagine, for example, that you have Vim running in tmux: the keystrokes you use in Vim should be different from the ones you use in tmux.

If they overlap, you might accomplish different actions in tmux and in Vim, at the same time. This is sometimes what we want, but most of the time it’s confusing.

That’s why most of the keystrokes in tmux need to be done after entering a prefix key. This prefix key is ctrl+b by default.

Let’s try it: go back to a tmux session and press ctrl+b , then hit " . Congratulation! You just opened a new pane . You can close it by simply typing exit .

If you think that the keystrokes are awkward and difficult to remember, no worries: we will change them later.

I will represent, in this article, the keystrokes which must be hit after the prefix keyas follow: prefix key -> " . In this example, it means that you need to hit the prefix key, then the key " .

Command Prompt

You can execute special tmux commands via a command prompt:

Type the prefix key ctrl+b Type : Welcome to the command prompt! Now, type split-window You just created another pane !

You can execute many commands in tmux via some keystrokes or via this command prompt.

tmux prompt

Managing tmux Sessions

Here are the most useful tmux commands to manage your sessions :

tmux list-sessions - List tmux sessions

- List tmux tmux new-session -s hello - Create a new session named “hello”

- Create a new named “hello” tmux kill-session -t hello - Kill the session named “hello”

- Kill the named “hello” tmux kill-server - Kill the tmux server and, as a result, every session

If you use a tool to automate the creation of your sessions , like tmuxp , you will barely need to use these commands. More on that later!

Configuring tmux

Let’s now create our own configuration to make tmux keystrokes more user-friendly. This configuration is not the best-configuration-in-the-universe-and-beyond, but adding step by step what you might need and playing with tmux at the same time will teach you how tmux works.

I encourage you to personalize this configuration following your own needs.

It’s time to configure tmux. Create the configuration file ~/.tmux.conf . Again, you should have tmux open too, to see what the configuration is doing.

Changing The Default Prefix Key

The default prefix key ctrl+b ( C-b in tmux) is not very easy to remember or even type on a keyboard.

I prefer using ctrl+space ( C-space ). It’s easy to type and I can remember it easily since my Vim’s leader key is space . It brings some consistency in my workflow.

Let’s modify the prefix key by adding the following in the configuration file:

unbind C-b set -g prefix C-Space

Here, the -g flag means global: the prefix key will be set for every session , window and pane in tmux. You could set the option only for a precise window for example, directly in the command prompt using set -w prefix C-Space .

It can be useful if you want to try multiple prefix key on the fly.

Reloading tmux Config File

Each time you change your config file, you need to reload it in tmux to apply the changes.

Let’s set a keystroke to reload the config file easily:

unbind r bind r source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf"

Here, we have two commands combined into one, on the second line:

We bind the key r to reload the config file. We display a message when we hit prefix -> r .

Let’s stop tmux by typing exit . Then, run tmux again and, if you hit prefix key -> r , you’ll normally see the message Reloaded ~/.tmux.conf displayed at the bottom of your tmux session .

From now on, each time you want to see the effect of your configuration changes, you need to reload the config file.

Mouse Mode

What? A mouse in a mouseless environment?

Well, using the mouse is sometimes practical, especially since you might use it in other software, like your browser.

Enabling the mouse allows you to use it for:

Selecting panes

Selecting windows (via the status line)

(via the status line) Resizing panes

Scrolling windows

Copying text

Let’s add it in the configuration:

set -g mouse on

You can do everything with your keyboard too, and I encourage you to do so.

Splitting Panes

A tmux window split in two panes

One of the most common operation you’ll do in tmux is splitting a window into multiple panes . Let’s add some useful keystrokes in our config:

# v and h are not binded by default, but we never know in the next versions... unbind v unbind h unbind % # Split vertically unbind '"' # Split horizontally bind v split-window -h -c "#{pane_current_path}" bind h split-window -v -c "#{pane_current_path}"

You might think that something is reversed here, between my keystroke v (for vertical) and the tmux flag -h (for horizontal). Well, yes and no.

The flag -c execute a shell command, and #{pane_current_path} simply bring you back where you were in the filesystem.

Resizing Panes

You can resize the panes with your mouse or by typing prefix key -> alt + arrow key .

Navigating Panes

To navigate from pane to pane , you can use prefix key -> arrow key by default. However, this action is so common I like to use the following:

bind -n C-h select-pane -L bind -n C-j select-pane -D bind -n C-k select-pane -U bind -n C-l select-pane -R

The flag -n means that these binding don’t use the prefix key.

Why using ctrl+hjkl ? Well, as I explained in my article Vim for beginners, it’s always better to keep your fingers on the home row keys. Using the arrow keys force you to move your hands. If you stop doing it, you’ll understand how comfortable it is.

More History! MORE!

One of the functionality I love in tmux is being able to have thousands of lines from the terminal outputs. You need to add the following to your config file:

set -g history-limit 100000

You can then perform some search on the past output very easily, especially if you use the search plugins I describe below.

Windows

a tmux session with two windows

We know how to split the current pane , but we don’t know yet how to create new windows and how to navigate between them.

Let’s add some more keystrokes to our config file:

unbind n #DEFAULT KEY: Move to next window unbind w #DEFAULT KEY: change current window interactively bind n command-prompt "rename-window '%%'" bind w new-window -c "#{pane_current_path}"

The keystroke prefix key -> w will create a new window , and prefix key -> n will allow you to rename the current window .

You can see some tabs in the status line, at the bottom left of your tmux session . Each tab represents one window .

When you have more than one window , you can then select them with prefix key -> <number> . <number> is the window number you want to display.

You can see that a little star in the window 's tab indicate what window is currently displayed in your terminal. If you think that it’s not really readable, no worries: we will improve the status bar later.

You can notice as well that the windows ’ numbers begin by 0. However, I find it more practical to set the first window to 1 instead.

To stay consistent, let’s do the same with the panes by adding in the config:

set -g base-index 1 set-window-option -g pane-base-index 1

You might think it’s annoying to do prefix key -> <number> , since you’ll navigate between windows often. I like to use alt+k to go to the next window , and alt+j to go to the previous one, without using the prefix key:

bind -n M-j previous-window bind -n M-k next-window

Copy Mode

tmux in copy mode

Let’s speak briefly about tmux modes. There are two of them:

The default mode

The copy mode

We actually use the default mode of tmux. You can think of it as the equivalent of the Insert Mode in Vim. It allows you to type whatever you want in the different panes .

When you are in copy mode, you have the possibility to navigate in your terminal, using Emacs or Vi key bindings. Since I’m in love with Vi/Vim, let’s add in the config:

set-window-option -g mode-keys vi

Now, let’s try the copy mode! Hit prefix key -> [ . You can come back to the default mode by hitting q .

You can see that you’re in copy mode thanks to the two numbers on the top right corner of your pane . They represent the total number of lines which are below the visible output (on the left) and the ones which are above (on the right).

From there, you can use the vanilla Vim keystrokes to navigate your current terminal output. Again, I wrote about the basic Vim keystrokes in this article.

You can use, for example:

Ctrl-u - Scroll up

- Scroll up Ctrl-d - Scroll down

- Scroll down / - Search

Exactly like in Vim!

Unsurprisingly, you will use copy mode mainly to copy content.

I you tried to copy terminal outputs already from tmux with your mouse, you might be confused: it doesn’t really work.

Indeed, tmux by default doesn’t copy anything in your system clipboard, but in one of its paste buffer . However, for convenience, I prefer using the system clipboard each time I copy something.

Let’s configure that now:

unbind -T copy-mode-vi Space; #Default for begin-selection unbind -T copy-mode-vi Enter; #Default for copy-selection bind -T copy-mode-vi v send-keys -X begin-selection bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel --clipboard"

To stay consistent with Vim’s default keybinding, we did the following:

Changing the keystroke to select text from space to v . Changing the keystroke to copy text from enter to y .

Then, we pipe the action to xsel , to copy the selection to the system clipboard. If you don’t have xsel installed or if you prefer using xclip , you can replace the last line in your configuration with this one:

bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -i -f -selection primary | xclip -i -selection clipboard"`

xsel or xclip will work well on Linux systems. For mac, you can apparently use pbcopy.

Be aware as well that you can past what’s in the tmux past buffer , by using prefix key -> ] , if you don’t want to use the system clipboard.

And voila! Now, copy pasting in tmux will normally work like a charm. You can as well copy using the mouse: select what you want and enter y without releasing the mouse button. If you release it, the selection will disappear before you had the chance to copy it.

Integrate Your tmux With Vim

There are some more configuration you need in order for tmux to work seemingly with Vim. If you don’t use Vim, you can pass this section.

First, if you use Neovim in tmux, you might experience a cursor problem: it doesn’t change from rectangle to pipe when you go from Normal Mode to Insert Mode.

Adding this line in your configuration might help:

set -g -a terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'

Another improvement you might want: navigating between tmux panes and Vim windows using the same keystrokes, ctrl+hjkl .

This config will do exactly that:

# Smart pane switching with awareness of Vim splits. # See: https://github.com/christoomey/vim-tmux-navigator is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L" bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D" bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U" bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R" bind -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

Now you have a personalized tmux configuration you can modify to fit your precise needs. There are a lot of tmux configuration available out there, if you need some inspiration.

You might think that it will take you forever to remember these keystrokes, but I believe they are overall pretty logical. Moreover, if you have written your own cheatsheet, I bet you know most of them already.

tmux Colors

the status bar looks finally better

Right now, the status bar of tmux is quite ugly: you can’t really see properly the windows displayed and it’s very… green. Boring!

You can personalize the status bar of tmux extensively.

Changing tmux colors can help to bring clarity in the status bar. One popular theme you can try is solarized . You can copy past this file in your config.

You can look at my own personalized design too as well, for inspiration.

Enhancing tmux With Plugins

Even if we have now a very powerful tool, we can improve tmux even more by adding some useful plugins.

tmux Plugins Manager

To manage our tmux plugins, we need the tmux Plugin Manager.

To install it, follow these steps:

Clone the project into your home directory: git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm Add this line in the configuration: set -g @plugin 'tmux-plugins/tpm' Add this at the end of tmux’s configuration: run -b '~/.tmux/plugins/tpm/tpm'

You can add any plugin you want in your config and install them with prefix key -> I , after reloading the config.

A Better Search With CopyCat

As we saw, tmux copy mode allow you to search in the output of the current pane . However, if you want advanced search capabilities, you can try tmux copycat.

What are the cool benefits, you might ask?

You don’t need to be in copy mode to search something.

You can search using regex or plain strings.

You have access to keystrokes to select filepaths, git status output, urls and IP addresses to copy them easily.

Your search is automatically selected. You can copy it using yank (the y key we configured earlier) directly.

Like in Vim, you can use n and N to jump to the next or previous result, respectively.

To install copycat, copy this line to your config:

set -g @plugin 'tmux-plugins/tmux-copycat'`

Then, you need to reload your tmux config and hit prefix key -> I to install copycat.

Fuzzy Search With fzf And Extrakto

You’ll need fzf touse this plugin. If you don’t have it already, I advise you to install it: it’s a very powerful tool which will enhance your terminal experience even more!

In order to install extrakto, add the following to your config file:

set -g @plugin 'laktak/extrakto'

Then, reload it and hit prefix key -> I to install the new plugin.

You can now fuzzy search the output of your terminal using prefix key -> tab . Pressing enter will copy the search in your clipboard.

Automating The Creation of tmux Sessions

The power of tmux doesn’t stop here. There are many tools out there which allow you to automate tmux session creation via YAML (or JSON) config files.

You can automate everything, from the number of windows and panes you want to, to the command lines to execute in which pane .

The two most known tools to create sessions from config files are tmuxinator and tmuxp.

Here’s a simple example of a tmuxp config file:

session_name: dotfiles start_directory: $HOME/.dotfiles windows: - window_name: nvim dotfiles layout: tiled panes: - nvim +FZF - window_name: terms layout: tiled panes: - - window_name: example layout: tiled panes: - shell_command: - ls - ls -lah

This configuration set up a session with 3 windows containing one pane each. In the first window , nvim will be executed. In the third window , two commands will run, one after the other: ls and ls -lah .

You need to create every tmuxp config file in the directory ~/.tmuxp . You can then load them using tmuxp load <session_name> .

This configuration is simple, but you can personalize your tmux sessions way, way more.

Welcome To tmux World

Now that you’ve played around with tmux, you can use it to its maximum. Don’t hesitate to try new configurations or new plugins. Experimentation is key, for you to find what fits the best.

What did we learn in this article?

The shell is a powerful tool we should leverage to improve our development workflow.

A tmux server manage all your tmux sessions. These sessions include windows and panes.

You can configure tmux depending on your own workflow, needs and personality.

Every keystrokes include the prefix key. It’s easier to remember and doesn’t conflict with other programs.

You can enhance tmux even further with useful plugins.

To dig more into tmux, I would definitely recommend you to look at the well written manual ( man tmux ).