Manage Your Terminals With Tmux

If you often need to use several terminals, you probably have already felt the need to be able to manage them more easily.

I really believe that as one of our main tool, configuring the way we use the shell is of great benefits for developers.

This is why, following my post on the z shell, today I want to share with you my setup to be able to transform the pain of launching and using multiple terminals into a much more enjoyable experience.

Why using a terminal multiplexer ?

If you are a developer, the terminal is probably part of your tool belt. Unfortunately, the base terminal is a bit, well ... limited.

Thankfully, there are several software that tackle this problem, allowing us to be able to group our shells, organize them and switch from one to another seamlessly.

These software are divided in two categories, terminal emulators and terminal multiplexers. Let's have a look at the main differences between them.

Mouse based Emulators

These ones are software that will allow you to emulates several terminals in their window.

They are very easy to install and very easy to use. I call them mouse based because they allow to do everything with the mouse, like resizing each window or adding a new tab.

It is a great and easy way to start using multiple terminals. The most famous one is Terminator and is already installed on a lot of linux distros.

Example of a Terminator display Example of a Terminator display

Keyboard based Multiplexer

These ones are not stand alone software but instead are launched in a terminal.

I call them keyboard based because it is the main way to use them, you might have some mouse support but it will be very light. Which mean that they require a bit of learning before being able to use them.

So why should I bother ?

Please don’t leave this post yet! They do have several advantages over terminal emulators, let’s have a look at them and I will let you decide if it can fit to your usage.

As a terminal multiplexer lives in a terminal, it can be used everywhere where you can open a terminal, like for example a remote server on which you log in through ssh.

This is particularly useful as a terminal multiplexer opens a server when you launch it, which will keep your terminal in a session. That allows you to connect to a remote server, enter some long time running commands, disconnect from the server but still be able, when you log back, to reopen this session as it was.

It also means it can be used to share a session with other users, or with yourself if for example you want to have the same terminal displayed on several widows or workspaces on your computer.

Last but not least, you will eventually end up being much more efficient using only your keyboard, and customization capabilities are almost endless and allow you to really shape it to your needs.

The two main terminal multiplexers are screen and tmux, which are very similar. Tmux is a bit more recent and is the one I will talk about in this post.

Example of a tmux display Example of a tmux display

How to install and use tmux ?

Before being able to use tmux, you will need to install it, which you should not be a headhache. On a debian system it is done with the following command.

sudo apt install tmux

Once tmux is installed, you will be able to create a session.

But first let me explain the lingo behind tmux with this schema.

2021-05-03-lingo.png

When you install tmux it will launch a server.

This server will allow you to manage sessions, on one terminal you will be attached to one session.

The command tmux will start a new unnamed session whereas tmux new -s <session-name> allows you to start a new session with the corresponding name. You can also rename it by typing Ctrl-b + $. You can detach from a session by typing Ctrl-b + d, see the sessions started with the command tmux ls and attach to one with the command tmux attach -t <session-name>.

Once you are in a session, you will be able to create several windows in it.

A window is displayed on the whole terminal window (hence the name) and can contains several panes.

Finally, a Pane is what contains a terminal !

You can create a new window with the command Ctrl-b + c, go to the next one with Ctrl-b + n or to the previous one with Ctrl-b + p.

You can then create as many panes you want and arrange them how you want. Shortcuts for the panes are not very convenient (at least that’s my opinion) so I won’t put them here but I will show you how to configure them in the next section.

For all the main commands, you can use a tmux cheat-sheet like the one at tmuxcheatsheet.com.

Customizing tmux to your needs

Tmux offers a lot of customization: you can change all the key bindings, tune its appearance, add scripts, ... To do so you just need edit a configuration file at ~/tmux.config.

Changing the prefix

The first thing you might want to change is the prefix.

You probably noticed that all the shortcuts I gave you so far started with Ctrl-b, which is the default prefix for tmux, needed before any command.

You can change it to another letter (be careful that it doesn't collide with a system shortcut though) with the following lines (to change it to Ctrl-a here).

# remap prefix from Ctrl-b to Ctrl-a
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

Changing the split-window commands

So when I told you that the shortcuts for panes were not very convenient, we have a good example with the split-window’s ones.

Splitting a window vertically is done with prefix + " and horizontally with prefix + %, which is not very easy to remember. A common change for these ones is to use more visual bar keys, like - and |.

# split panes using | and -
bind-key | split-window -h -c "#{pane_current_path}"
bind-key - split-window -v  -c "#{pane_current_path}"
unbind-key '"'
unbind-key %

Notice that I have also added the option -c "#{pane_current_path}". This will use your current path when creating a new pane, instead of your home path.

Adding switch panes shortcuts

For switching from one pane to another, using the prefix can be quite cumbersome as this is something you want to be able to do very seamlessly.

What you can do is to add direct shortcuts, by direct I mean that you won’t need to type the prefix before.

This is done using the option -n for the bind-key command.

Personally I add shortcuts that allow me to easily navigate between my panes using arrows or vim keys while holding the control key.

# switch panes using Ctrl + arrow without prefix
bind-key -n C-Left select-pane -L
bind-key -n C-Right select-pane -R
bind-key -n C-Up select-pane -U
bind-key -n C-Down select-pane -D
# switch panes using Ctrl + vim keys without prefix
bind-key -n C-h select-pane -L
bind-key -n C-l select-pane -R
bind-key -n C-k select-pane -U
bind-key -n C-j select-pane -D
# toggle zoom using Ctrl + z
bind-key -n C-z resize-pane -Z

That's much more efficient, the same can be navigating between windows.

# switch window using Ctrl + p/n without prefix
bind-key -n C-p previous-window
bind-key -n C-n next-window

Copy/Paste with vi commands

Tmux allow you to switch to a copy mode, in which you can scroll up through your terminal display, search for a specific text, copy a part of the text…

To switch to the copy mode, you just have to type prefix + [. You can choose between 2 sets of command to navigate in the copy mode, either using vi or emacs keys.

I am personally used to vi keys (as you might have noticed already!) so this is the one I use. I even enforce some commands to be closer to the vi ones.

# vi copy/paste mode
set-window-option -g mode-keys vi
bind-key -T copy-mode-vi 'v' send-keys -X begin-selection
bind-key -T copy-mode-vi 'y' send-keys -X copy-selection-and-cancel

Once in copy mode, I can navigate the history using vi controls, start a selection with the v key, copy it with y ,and then paste it in your terminal using prefix + ].

Very useful!

Launching a predefined session quickly with tmuxp

Now that we have configured tmux and are starting to be comfortable with all its commands, let me present you a tool that will dramatically reduce the time it takes you to setup your environment for a project.

This tool is a tmux environment manager called tmuxp. Basically, it allows you to define your environments in files and then launch them for you, instead of creating custom new windows every time.

It is a python package and hence is installed using pip.

pip install tmuxp

You can then create tmuxp environment files in yaml and put them in the ~/.tmuxp directory.

Let me show you how to do it with a commented example.

# ~./tmuxp/advanced-react.yaml
session_name: advanced-react # name of the session
windows: # list all windows
  - window_name: backend # name of the window
    layout: even-vertical # how panes are displayed
    shell_command_before: # list of commands that will run in every panes
      - cd ~/Workspace/advanced-react/backend
    panes: # list of panes
      - shell_command: # list of commands for the pane
          - npm run dev
      - shell_command:
          - code .
          - git status
  - window_name: frontend
    layout: even-vertical
    shell_command_before:
      - cd ~/Workspace/advanced-react/frontend
    panes:
      - shell_command:
          - npm run dev
      - shell_command:
          - code .
          - git status

You can then launch this session by typing tmuxp load advanced-react, and you will get in this case a session called advanced-react, with two windows, each containing 2 panes spread vertically, running npm commands, opening vscode and displaying git status.

Of course it is yours, depending on the kind of projects you are working on and how you like to organize things, to define your environments. Possibilities are endless!

Final words

If it is the first time you read about tmux, you might feel overwhelmed right now. In this article, I did my best to stick to what I really use and what saves me time in my everyday programming.

Take your time to understand how it works, and once you are comfortable with the basics, fell free to explore all the things that can be done with tmux.

If you already are a tmux user, I am curious to know what are the main functionalities that you find useful. I would be glad to hear them in the comments.

No Comments Yet