Taskwarrior supports color in the terminal, and does this by implementing a color model, which is a nice abstraction for handling colorized text. The model allows us to specify color such as “red”, instead of using…
Terminal Escape Sequences
Terminal programs such as XTerm display the data received from an application in the window or on the screen. But not all of it. If the data contains an escape sequence, which is a known sequence of data, usually indicated by some leading unprintable character, then XTerm does not display it. Not directly at least, because it must first decode what is being sent, and act accordingly. There are hundreds of different XTerm escape sequences, but just a few of them handle color.
It can help to think of HTML as an analogy. To display a word in boldface, you might use this HTML:
regular <b>bold</b> regular
Here the word ‘bold’ is surrounded by a Bold tag. XTerm color works in a similar fashion, but is a lot less readable.
Typically a program such as Taskwarrior will look at the $TERM environment variable, use that value to look up the supported escape sequences in termcap for the given terminal, and use only the supported subset.
Support For Different Terminals
Does Taskwarrior look at $TERM? No. Does Taskwarrior use termcap at all? No. Does it use NCurses to manage all this? No. It simply uses Xterm escape sequences, ignores other terminal types, and so far (going on seven years now) no one has asked for any other terminal support. There just doesn’t appear to be a need.
How Are Escape Sequences Used?
Here is an example of the escape sequence for the foreground color red, used directly in the terminal:
The echo command simply sends the data to the terminal, and the first example contains only the word ‘Hello’. The second example inserts the escape sequence ^[[31m to turn on the red foreground, and ^[[0m to turn off all color. In order to enter the second example “red” sequence in the terminal, using Bash, type the following keys in sequence:
Ctrl-V <Escape> [ 3 1 m
To be specific, type Ctrl-V (both ‘Control’ and ‘V’ at the same time), then hit the ‘Escape’ key, then ‘[‘, then ‘3’, then ‘1’ then ‘m’. Note that when you enter a literal escape character (with Ctrl-V, Escape) it shows up as ^[. This is expected, as escape sequences do strange things to your terminal. Also note that if you do this, and mess up the terminal (it’s possible), all you need to do is close and reopen the terminal window.
It should be noted that the second example echoes 14 characters, but only 5 are displayed. The others are interpreted as color codes and consumed by the terminal. The important aspect of this is the ’31’, which is the code for foreground color red.
There are also escape sequences for bold, underline, inverse. The special escape sequence ^[[0m resets all the color, so that makes it possible to combined colored and non-colored text, like this:
Here the ‘4’ means underline. In addition to foreground color, there is a background color, and these may be combined like this:
See how the ’31’ (foreground red) is combined (using ‘;’) with ’44’ (background blue) to specify both foreground and background color. Using what we have seen so far, colorful “graphics” (they are not really graphics, just colored text cells), can be produced, for example this text:
Does not display any text, just spaces on colored backgrounds ’44’ (blue) and ’47’ (white), and it looks like this:
Taking this further, it becomes possible to construct complex sequences of color codes to produce, for example, a monthly burndown chart for the Taskwarrior 2.3.0 project:
All this is simply text, spaces and escape sequences. Here is another example of the Taskwarrior calendar, using a purple theme, combining text and escape sequences:
The Taskwarrior color model has three responsibilities, which are:
 Naming Convention
This is simply a way to map the XTerm escape sequences into some more readable and usable set of names for colors. There are four ways to specify colors, the first is by simple name:
red, blue, black, green, cyan, magenta, yellow, white
These are the simple 8-color names. Then there is an RGB model:
rgb000 – rgb555
This ranges from black (rgb000) to white (rgb555) through a color cube, where the red, green and blue components each have six possible values (0, 1, 2, 3, 4, 5). The model maps these coordinates to the right escape sequence, which, as one would hope, follows an orderly convention.
There there are the 24 grey colors:
gray0 – gray23
These follow a monochrome scale, and are used in the demo “task logo” command (go ahead, try it).
Finally there is a direct specification of all 256 colors using:
color0 – color255
This sequences ranges from the 8 standard colors, the brighter equivalents, through the color cube, to the gray-scale.
The color model provides a small language to allow composition. For example, there is the trivial case of just specifying a foreground color:
But to distinguish foreground from background, the syntax used the word “on”:
red on blue
This can include other attributes, such as:
bold red underline on bright blue
Any of the naming conventions can be used here.
This is really a stretch, given the simplistic nature of the terminal color, but there is support for combined two colors into one. It is rudimentary and can only blend easily combined attributes, such as foreground with background, color with underline. Future improvements will allow combinations like red + blue –> magenta.
Here are all the color combinations supported by Taskwarrior, as seen in the command “task color”:
You might ask “Why does ‘on bright green’ look like two kinds of grey?”. This is because the terminal used to generate these screenshots is using a modified Solarized theme, which remapped color8 – color14.
The standard 8 colors cannot be combined with the 256-color equivalents. When this is attempted (red on gray15), the red is upgraded to color1. Similarly, ‘bold red’ is upgraded to color9. Similarly, ‘on bright red’ is upgraded into the 256-color system. This is handled automatically.
There is a missing advanced feature – optimization. Sometimes it is possible to examine colorized text and remove some redundant color codes. Consider this pseudo-HTML:
This could be reduced to:
Although this optimization is not implemented, the redundancy does exist, and should be addressed, because it can greatly reduce the I/O of Taskwarrior.