+
AMDG
Goodman Coat of Arms

Goodman's Oak

Miscellaneous Thoughts, Projects, and Ruminations on Life, the Universe, and Everything

The Best Terminal Emulator: st, the suckless terminal

Donald P. Goodman III 26 Dec 1200 (30 Dec 2016) — updated 0X Oct 1206 (10 Oct 2022)

st, the suckless terminal, is the best terminal emulator. Done.

No, it doesn't do fancy-schmancy transparency like rxvt; it doesn't natively support multiple tabs like konsole or gnome-terminal; and it doesn't support every obscure tty format that's existed since 1971 like xterm. But for the vast majority of use cases, this is what we should be using.

See, st is a beautiful thing; it does exactly one thing, and it does it well. Really well. It minimizes its own necessary screen real estate (provided you don’t use a gigantic font, of course), it doesn’t eat up your resources with eye-candy nonsense; and it allows you to employ whatever fonts and symbols you want without taking over the whole issue itself. It’s light as a feather, starting in an instant and using up barely enough memory to be noticed. Yes, it even supports Unicode!

Internally, st is an amazing thing. It is miniscule. I cloned the repository to build it; this was a single git clone command. The code is only 2.9 megabytes; and 2.4 megabytes of that is the actual git repository itself, meaning that the whole comprehensive terminal emulator is only half a megabyte of code. Furthermore, the program built with nothing more than the usual (POSIX-compliant!) make, not requiring any cmake craziness or non-standard Python-based build systems at all. It was literally a pleasure, and literally impossible to mess up.

Simple, direct; no bulky libraries, no crazy option-setting. Do one thing and do it well.

But what about tabs, I immediately hear the protests? I want multiple tabs on my terminal! Well, so do I; I use multiple tabs all the time. I'm using multiple tabs right now. But tabbing is not a terminal emulator's job; it's a terminal multiplexer's job. There are really two choices here, GNU screen or tmux; I choose to use tmux.

See, tabs are a sine qua non for me with terminal emulators. I often run many terminal windows at a time, and having all of these all over my desktop, even with virtual desktops, is clunky and annoying. So for a while I thought I was stuck with some fancy graphical terminal like konsole, since I was having trouble with rxvt’s tab function. (It crashed. Repeatedly. While opening predictable man pages. And extensive Googling turned up no solutions.) But I didn’t realize that a good terminal emulator didn’t have to support tabs, because that job is done by another program. A good Unix program does one thing and does it well; I was expecting a good Unix program to do two things, and that was unjust. God be praised, however; I discovered tmux.

tmux is a great tool which has functions far beyond what I use it for. However, it has the ability to split a terminal window (or a real console, if that’s your pleasure) into multiple instances, each of which can be addressed individually and perform different functions. One can name and manipulate each instance as one wishes. Switching between them is easy; escape yourself from your program with CTRL-b, then hit “n” for the next screen or “p” for the previous one. To create a new screen, hit CTRL-b, then c. It’s great.

You can even have these screens named, and listed on the bottom of your screen precisely as if they were literal tabs in a single program. This requires some interesting wizardry in your .tmux.conf file, but it’s fun for all the girls and boys anyway. Here, for example, is my .tmux.conf:

# +AMDG
# get vi-like key bindings (obviously)
set -g mode-keys vi
# change C-b to C-a, which is Objectively Better
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# bindings
bind r source-file ~/.tmux.conf	# reload config
bind k confirm kill-window			# kill window
# status bar config
set -g status-justify left
set -g status-bg black
set -g status-fg blue
set -g status-right '#(dozdate)'
set -g status-left ''
set -g window-status-current-style bg=blue,fg=black
set -g window-status-format "#I:#{=10:window_name}#F"
# macros for the good stuff
bind m new-window -n "Mutt" 'mutt'
bind s new-window -n "Newsboat" 'newsboat'
bind t new-window -n "Tin" 'tin -A -geternalsept'
bind u new-window -n "Music" 'cmus'

(I change CTRL-b to CTRL-a as a personal preference, from my years of using a different multiplexer, GNU screen; you can set it to whatever you want, and feel free to ignore this part of the config.)

Those “status bar config” lines make the magic happen; the tmux man page will tell you much, much more. But here’s the result: my current st window:

Current st window, using tmux

See those tabs? The highlighted one is the active one.

Sure, but isn’t it annoying to have to start st, then run tmux to get your tabs? No; like most terminal emulators, st allows you to run another program in it upon opening the terminal. For example, I have fvwm open an st for me upon startup, which is running tmux, with the following command line (unnecessary bits, like geometry requirements, removed):

st -e screen

And that’s it. Really not a problem, is it?

So all hail the mighty st: small, sleek, streamlined, doing one job and doing it well. And all hail tmux, which helps st to be all it can be.

Praise be to Christ the King!