Skip to content

Instantly share code, notes, and snippets.

@sindresorhus
Forked from XVilka/TrueColour.md
Created January 17, 2017 11:46
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sindresorhus/bed863fb8bedf023b833c88c322e44f9 to your computer and use it in GitHub Desktop.
Save sindresorhus/bed863fb8bedf023b833c88c322e44f9 to your computer and use it in GitHub Desktop.
True Colour (16 million colours) support in various terminal applications and terminals

Colours in terminal

It's a common confusion about terminal colours... Actually we have this:

  • plain ascii
  • ansi escape codes (16 colour codes with bold/italic and background)
  • 256 colour palette (216 colours + 16 ansi + 24 gray) (colors are 24bit)
  • 24bit true colour ("888" colours (aka 16 milion))
printf "\x1b[${bg};2;${red};${green};${blue}m\n"

The 256 colour palete is configured at start, and it's a 666 cube of colours, each of them defined as a 24bit (888 rgb) colour.

This means that current support can only display 256 different colours in the terminal, while truecolour means that you can display 16 milion different colours at the same time.

Truecolour escape codes doesnt uses a colour palete. It just specifies the colour itself.

Here's a test case:

printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n"
awk 'BEGIN{
    s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
    for (colnum = 0; colnum<77; colnum++) {
        r = 255-(colnum*255/76);
        g = (colnum*510/76);
        b = (colnum*255/76);
        if (g>255) g = 510-g;
        printf "\033[48;2;%d;%d;%dm", r,g,b;
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
        printf "%s\033[0m", substr(s,colnum+1,1);
    }
    printf "\n";
}'

Keep in mind that it is possible to use both ';' and ':' as parameters delimiter.

According to Wikipedia[1], this is only supported by xterm and konsole.

[1] https://en.wikipedia.org/wiki/ANSI_color

Currently, there is no support for the 24-bit colour descriptions in the terminfo/termcap database and utilites. See the discussion thread here: https://lists.gnu.org/archive/html/bug-ncurses/2013-10/msg00007.html

Here are terminals discussions:

Now supporting truecolour

But there are bunch of libvte-based terminals for GTK2 so they are listed in the another section.

Also, while this one is not exactly a terminal, but a terminal replayer, it still worth mentioning:

Parsing ANSI colour sequences, but approximating them to 256 palette

Note about colour differences: a) RGB axes are not orthogonal, so you cannot use sqrt(R^2+G^2+B^2) formula, b) for colour differences there is more correct (but much more complex) CIEDE2000 formula (which may easily blow up performance if used blindly) [2].

[2] neovim/neovim#793 (comment)

Terminal multiplexers

  • tmux - starting from version 2.2 (support since 427b820...)
  • screen - has support in 'master' branch, need to be enabled (see 'truecolor' option)
  • pymux - tmux clone in pure Python (to enable truecolour run pymux with --truecolor option)
  • dvtm - not yet supporting True Colour martanne/dvtm#10

NOT supporting truecolour

[3] You can download patched version here https://github.com/rdebath/PuTTY

[4] You can download patched version here https://github.com/halcy/PuTTY

Here are another console programs discussions:

Supporting True Colour:

Not supporting True Colour:

@margual56
Copy link

margual56 commented Oct 23, 2021

The awk script is not "adaptative" to the width (columns) of the terminal as mentioned in Brodie's video.

This should work tho:

awk -v cols="$(tput cols)" 'BEGIN{
    for (colnum = 0; colnum<cols; colnum++) {
        r = 255-(colnum*255/cols);
        g = (colnum*510/cols);
        b = (colnum*255/cols);
        if (g>255) g = 510-g;
        printf "\033[48;2;%d;%d;%dm", r,g,b;
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
	char=(colnum%2==0)?"/":"\\";
        printf "%s\033[0m", char;
    }
    printf "\n";
}'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment