Project #5: Using tmux Properly

February 4, 2017

Background

I've been using terminal multiplexers for a few years, but never properly.

In the beginning, it was just me and the (plain) terminal. Then I started using Byobu, because it was company-standard at my first job. Later I installed tmux on my personal computer because it seemed more popular. And every time I work on a remote server, I use Screen. Lions and tigers and bears, oh my!

This begs a few of questions. We'll go through them in the next section.

As a quick aside before we dive in—'terminal multiplexer' is an intimidating term. But none of the concepts are complex. Terminal means console and multipexing is just running numerous processes at the same time in one place.

Introduction

What is a terminal multiplexer? A terminal multiplexer is a souped-up terminal. If you used a plain terminal for a few years and then someone said: "What features do you think we should add?", you'd end up with a multiplexer.

Why do people use multiplexers? There are three major features.

visual control: split your screen into different sections, run terminals off-screen that you can easily switch to, etc.

shared sessions: me and you can edit the same file on the same machine at the same time, me using my computer and you using your computer

persistence: leave everything running exactly as it is, without needing to keep the application physically open, so you can come back to it later

We'll dig into these tangentially in more detail later. But these are big features—so if only one is valuable to you, it would be worth learning how to use a multiplexer.

How do the different multiplexers fit together? Screen was first. It's been around a long time (initial release 1987), and comes installed on all *nix operating systems. tmux was next (2007). It's similar to Screen, but has some additional features and is easier to configure. Then came Byobu (2009). Bybobu is actually just a wrapper, and it can wrap either Screen or tmux. Similarly, it has some additional features 1.

What Should I Use? There is no right answer. But I'll tell you what I do. I use tmux on my development machine and Screen on production servers. Byobu adds an additional layer of abstraction without any killer features. Screen has the lightest footprint, so is good on servers. tmux has enough useful features, and I spend a lot of time in the terminal, that make it worth it.

Learning tmux

For years, I was running tmux but never using more then a handful of commands. I'd google all the time, and constantly end up at the same cheatsheet.

I put off learning how to use tmux because I was lazy. And, well, I got around good enough with the 5 commands I knew. Basically, I just didn't want to learn another 'thing'.

However, over the last few weeks I read a book: tmux: Productive Mouse-Free Development. I learned a lot!

My biggest takeaway is that tmux is much smaller in scope than I expected. I don't know why, but I expected it to be like learning Vim or Git (steep learning curve, complex, etc).

This was a great time-to-knowledge investment. I feel foolish for not having done it sooner—after just a few hours I'm an order of magnitude more comfortable with tmux.

I recommend that you read the book; it's short. You can get away with reading just the first 4 chapters, so it's only ~50 pages.

What I Learned

Create Reasonable Settings

There are certain settings that you need to be productive with tmux. That is, it's just not great with the out-of-the box defaults.

On the one hand, I like that tmux is not strongly opinionated. On the other hand, you should probably just set these up.

The configuration file lives at ~/.tmux.conf . These are a few must-haves—

bind j select-pane -D bind k select-pane -U bind h select-pane -L bind l select-pane -R bind | split-window -h bind - split-window -v bind -r J resize-pane -D 5 bind -r K resize-pane -U 5 bind -r H resize-pane -L 5 bind -r L resize-pane -R 5 set -g pane-border-fg white set -g pane-active-border-fg cyan set -g pane-active-border-bg cyan

I used PREFIX o exclusively to move between panes. So if I had 4 panes open, I'd sometimes hit that sequence 3 times to get where I wanted. That was no good at all.

This first group of bindings allows you to navigate the panes with Vim-like movements. If you need to move left, just PREFIX h .

My favorite feature of tmux is splitting a window into different panes. I could never remember the default bindings ( % for horizontal, " for vertical split). These (second block above) are much nicer.

Adjusting the pane size is very difficult without dedicated commands. To avoid using long instructions in Command Mode, these additional Vim-like bindings (third block) are awesome.

Lastly, it is difficult to tell which pane is active with default tmux. I found that adding some color to the border of the active pane (last block) went a long way.

Copy Mode

The goal of life, really, is to keep your fingers on the home-row as much as possible. I still have a few sticking points, and a major one used to be copying text from the terminal.

tmux makes this easy, with Copy Mode. Enter copy mode with PREFIX [ . Jump around the buffer by scrolling or searching ( ? and / ) and grab text with Space and Enter . Then paste with PREFIX ] .

This is another feature I should have been using for years. Plus, you can turn on Vim-like bindings ( setw -g mode-keys vi ) to make moving around the buffer easy.

Repeatable Commands

This is a small win, but I was delighted to learn that you can make commands repeatable. For example, the command to move to the next window is PREFIX n . So if you want to move two windows forward, you'd hit PREFIX n PREFIX n .

However, the -r flag allows commands to be repeatable. If we using the following configuration bind -r n select-window -t :+ now PREFIX n n will move two windows forward (skipping the repeated calls to prefix is now okay). This is great for lots of navigation commands.

More Goodies

A sampling of the some other things I learned—

customizing the status bar is easy to do. I display current session name, window number, and pane number with set -g status-left "session: #S || window: #I || pane: #P"

writing a script to launch tmux with a specific configuration (e.g. 2 windows named 'code' and 'status', 4 panes in one window, 2 panes in the other window, run htop and open Vim) is not difficult at all

pairing with tmux is boss

Wrapping Up

One thing that made learning tmux easier than I expected is that I don't have a need for many of its advanced features. tmux can do much more than I discussed, like moving panes between sessions and integrating more tightly with the operating system. For a comprehensive rundown, consult (as always!) the man page.

and

However, the new things I'm using are a great help. My config file is available on Github There is one semantic wrinkle that makes talking about these different multiplexers a little more challenging: they use different terms for similar thingsuse the same terms for different things. Most noticeably, in Screen a 'window' is a region of a display. That is, you can put numerous windows on your view. In tmux, a 'window' is the full view and can be divided into panes. It gets extra messy, because lots of people use both Screen and tmux and then use the terms wrong—I see lots of people using tmux terms in relation to Screen and vice versa. The best explanation I found is this blog post

Have anything to say? Questions or feedback? Tweet at me @cmmn_nighthawk!