TTT Part 39 of n – Advanced TMUX

This entry is part 39 of 39 in the series Taming the Terminal

In the previous instalment we learned how to use the tmux as a replacement for the screen command which has been deprecated on RedHat Enterprise Linux (and hence CentOS too). In this instalment we’ll take TMUX to the next level, making use of the fact that a single TMUX session can contain arbitrarily many windows, each consisting of arbitrarily many panes.

As a reminder from last time — in the TMUX-universe, sessions contain windows contain panes. By default a session contains one window which contains one full-width and full-height pane. Windows can be thought of as stacking behind each other, like tabs in a browser, and panes are arrayed next to each other within a window.

Listen Along: CCATP Episode 583
https://media.blubrry.com/nosillacast/traffic.libsyn.com/nosillacast/CCATP_2020_07_25.mp3

Working with Windows

Let’s start by opening a completely vanilla default tmux session:

tmux new

This session has one window, very imaginatively named 0. So that we can recognise it later, let’s just enter a command:

echo 'The first window!'

Before we start creating and navigating between windows, I’d like to draw your attention to the left-part of the status bar. In this entirely default single-window-single-pane session is should look like this:

[0] 0:zsh*

As we create and manipulate windows it will change, and I expect the meaning will become intuitively obvious as we go. If not, don’t worry, we’ll circle back to it later.

Creating Windows

Let’s start by creating a new window within our simple session. We do this be entering control mode with ctrl+b, and then pressing c for create window. We immediately jump to a fresh window. If you look down at the status bar you’ll see that the left-most part has changed to:

[0] 0:zsh- 1:zsh*

Let’s now start a process in this new window so we can easily recognise it in future:

top

Notice that starting the top command in the second window change the status bar again:

[0] 0:zsh- 1:top*

Let’s create a third one by entering command mode again with ctrl+b and pressing c. So we can recognise it, let’s run a command so it has some content:

less /etc/profile

Again, notice the status bar change:

[0] 0:zsh- 1:top 2:less*

Finally, before we look at navigating between windows, let’s create one more window by again entering command mode again with ctrl+b and pressing c. Notice the state of the status bar is now:

[0] 0:zsh 1:top 2:less- 3:zsh*

Navigating Between Windows

We can move between windows by entering control mode with ctrl+b and then pressing p for previous window, or n for next window. Remember, think of windows like tabs in a browser, they have an order based on the order they were created in, the first window to be opened becomes the left-most tab, and subsequent windows line up to the right. With this mental model in place, we can get into the habit of thinking of previous as the one directly to my left, and next as the one directly to my right. One last thing to note is that both next and previous wrap around, so if you go next/right from the right-most window you end up on the left-most window, and vice-versa.

Use those keystrokes to move about as you wish, and as you do, watch the status bar changing.

The more windows you have, the more useful it becomes to be able to jump directly to a specific window, and we have two options for doing that. Firstly, the first ten windows are available by entering command mode with ctrl+b and hitting the numbers 0 to 9. And secondly, like ctrl+b s gives us a session picker (as we saw in the previous instalment), ctrl+b w gives us a window picker.

Using the method of your choice, jump to the second window, and then, directly to the fourth (ctrl+b 1 followed by ctrl+b 3 will do it).

Understanding the Status Bar

The status bar should now look like this:

[0] 0:zsh 1:top- 2:less 3:zsh*

So what does it mean?

The left-most item is the name of the session in square brackets. Because we opened a completely default session without naming it, it has defaulted to the very unimaginative 0! Let’s prove that it really is the session name by entering control mode with ctrl+b and hitting $ to rename the session. I’m going to call mine BB Sess. My status bar now looks like this:

[BB Sess] 0:zsh 1:top- 2:less 3:zsh*

Next to the session name in square brackets are items for each of our windows in order. Like sessions, windows have names, but unlike sessions, the default names are useful! By default a window is named for its currently running process. As you start and stop commands, the name of the window changes. The status bar item for each window consists of the windows’s number in the list and its name, separated by a colon, so 0:zsh is the first window and it’s named zsh because we didn’t give it an explicit name, and it is currently running zsh shell. Similarly, 2:less is the third window and is currently running the less command.

But what about the - and * tagged on to the ends of the items for the second and fourth windows? As you were moving around between windows you may have noticed that * is appended to the current window, and - to the last-viewed window before the current one. Because we jumped straight from the second to the fourth window, the last-viewed window is not adjacent to the current window.

Toggling Between Last-viewed Windows

Why would TMUX dedicate valuable status-bar space to an indicate for the last viewed window? Simple — because you can jump directly to that window by entering command mode with ctrl+b and hitting l (lower-case L for last).

Renaming Windows

Just like you can rename sessions, you can rename windows. Note that when you explicitly set a window’s name it will not change as you run different processes. A lot of the time, the default name is more than sufficient, but that breaks down in situations where you’re running the same command in different windows similtaneously — perhaps you’re editing two files with vi, or watching two log files with tail.

Switch to the fourth window using what ever means you like, then change into the system log folder:

cd /var/log

You can rename the current window by entering command mode with ctrl+b and pressing ,.

I’m going to name the window logs, and after I do my status bar now looks like this:

[BB Sess] 0:zsh 1:top- 2:less 3:logs*

Closing Windows

You can close a window by ending the shell process running within it, e.g. with the exit command. Try this in the 4th window. You should now be in the third window with the top process we started near the beginning of this instalment still running.

You can also close a window by pressing ctrl+b to enter command mode and hitting &. Try it on the third and second windows. Notice that TMUX is polite enough to ask you if you’re sure ðŸ ‚

Working with Panes

Panes are created by splitting an existing pane horizontally or vertically. Remember that by default, every TMUX window contains one pane, so there is always a pane to split.

To split a pane enter command mode with ctrl+b, then press " to split it horizontally, or % to split it vertically. Let’s do both of those in order in our session. You should now have three panes, a big one across the top, and two small ones across the bottom. The current pane is highlighted with a green border.

Moving Between Panes

You can move between panes is by pressing ctrl+b to enter command mode and then pressing an arrow key. Additionally you can cycle through your panes by entering command mode with ctrl+b and pressing o to move to the next pane in the sequence.

You can also jump directly to a specific pane by number. To see the numbers assigned to each pane enter command mode with ctrl+b and press q. To jump directly to a pane by number enter command mode with ctrl+b, press q, then the desired number (you need to be quite quick — you have to press the number before the labels vanish!).

You can also jump to the most recently active pane by entering command mode with ctrl+b and pressing ;.

Expanding Panes with Zoom Mode

The whole point in having panes is to be able to easily see the outputs from multiple commands at once, but that doesn’t mean there are not times you’ll want to focus in on a single pane for a while. TMUX supports this with a toggleable zoom mode. When you enter zoom mode the current pane takes up the full window until you toggle zoom mode off again. You can toggle zoom mode by entering command mode with ctrl+b and pressing z. Note that zoom mode is applied at the window level, not the session level, so if you have multiple windows you can zoom some of them but not others. Finally, TMUX will not allow you to enter zoom mode on windows with just a single pane.

Try entering zoom mode and watch the status bar. Notice that zoomed windows get a Z appended to them in the status bar.

Closing Panes

You can close the current pane by exiting the shell running within it, for example with the exit command. Also, you can close a pane by entering command mode with ctrl+b and pressing x.

Final Thoughts

As you might remember from the previous instalment, the name TMUX is a portmanteau of Terminal Multiplexer, in this instalment we’ve really put the multi into multiplexer by adding multiple windows to our sessions, and then splitting those windows into multiple panes.

These complex TMUX layouts can be very useful, but it takes a lot of keystrokes to create them. Wouldn’t it be nice to be able to build an entire layout in a single command and somehow save that for future use? I certainly find that ability very useful, so that’s what we’ll be doing in the next instalment.