As a daily user of the terminal, I find coloring my terminal very useful and aesthetically pleasing compared to the usual black and white default theme. Personally, I’ve been using the default dark base16 theme. In particular, I’m using scripts from the base16-shell repo because I can simply add the setup to my rc file and make it work for whatever machine I’m using. I never really bothered to understand how the coloring works, it’s been pure magic to me. A few days ago, however, I’m having some coloring issue with MobaXterm and I decided to actually take a look at how the script colors my terminal. There are a few things to understand to build the whole picture.
Type of terminal
We have to understand that “terminal” is just a term to describe a device that entering data into and displaying data from a computer. There were many implementations in the past and they work differently and have different capabilities. For example, we have
xterm-256color. To write programs/libraries (e.g. ncurses) that works on many different terminals, there are libraries like
terminfo which provides a device independent software API. Besides these libraries, there is another way to communicate with the terminal, which is called “ANSI escape sequence”.
ANSI escape sequence
According to Wikipedia,
ANSI escape sequences are a standard for in-band signaling to control the cursor location, color, and other options on video text terminals and terminal emulators.
Basically, it works by embedding non-printing byte sequences to the text that you print on the terminal. Therefore, you can send commands to the terminal by simplying doing
printf in your shell. You may have already seen it if you wrote scripts that print colored text. These escape sequences usually start with
Esc which can be access by
\x1B in the shell. For example, you can do the following to print red text (try it yourself!).
$ printf "\033[31mI'm RED\033\n[0m"
Here is a full list of escape sequences that you can send. For this post, let’s focus on the ones that control the colors.
Changing the color
In the link above, under “Operating System Controls”, we find what we are looking for. There is a
4;c;name option which says change color
name. The full syntax is
\033]4;<color>;<name> (you can read up on the syntax from the above link). The
name here follows the XParseColor syntax, e.g.
rgb:18/18/18. In the terminal we usually have 16 or 256 colors and this sequence allows us to change the mapping from color IDs to actual RGB values. Suppose we set color 01 (which represent red) to a blue-ish
rgb:7c/af/c2, your terminal will actually print blue text when you run the above
printf command! Looking at the source code of
base16-shell, that’s exactly what the scripts are doing. They run
printf to change color 00 to 21 to form a 22 color palette based on the exact theme you chose. Cool, now I understands how my terminal is colored!
In this post, I talked about how a terminal is colored with what’s called ANSI escape sequences. For me, it was quite fun researching about all these information. I didn’t expect it to be this simple, I thought it was some complicated magic to make it work. I hope you find my post a fun to read and helpful for understanding a bit of the history in computing! Cheers!
- What’s the difference between various $TERM variables? - Unix & Linux
- Computer terminal - Wikipedia
- ANSI escape code - Wikipedia
- rtfm/Xterm/Escape Sequences
- xparsecolor(3) - Linux man page