Awesome
Terminal Colors
(Previously published and discussed at https://gist.github.com/XVilka/8346728.)
There exists common confusion about terminal colors. This is what we have right now:
- Plain ASCII
- ANSI escape codes: 16 color codes with bold/italic and background
- 256 color palette: 216 colors + 16 ANSI + 24 gray (colors are 24-bit)
- 24-bit truecolor: "888" colors (aka 16 million)
printf "\x1b[${bg};2;${red};${green};${blue}m\n"
The 256-color palette is configured at start and is a 666-cube of colors, each of them defined as a 24-bit (888 RGB) color.
This means that current support can only display 256 different colors in the terminal while "truecolor" means that you can display 16 million different colors at the same time.
Truecolor escape codes do not use a color palette. They just specify the color directly.
For a quick check of your terminal, run:
printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n"
which will print <span style="color:#ff6400">TRUECOLOR</span> in brown if it understands Xterm-style true-color escapes.
For a more thorough test, run:
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";
}'
Some other tests:
- gist/lilydjwg/colors.py
- https://github.com/robertknight/konsole/tree/master/tests/color-spaces.pl
- https://github.com/JohnMorales/dotfiles/blob/master/colors/24-bit-color.sh
- https://git.gnome.org/browse/vte/tree/perf/img.sh
# make a sandbox
mkdir tmp$$
cd tmp$$
# downloads scripts
wget https://github.com/robertknight/konsole/raw/master/tests/color-spaces.pl \
https://gist.github.com/lilydjwg/fdeaf79e921c2f413f44b6f613f6ad53/raw/94d8b2be62657e96488038b0e547e3009ed87d40/colors.py \
https://github.com/JohnMorales/dotfiles/raw/master/colors/24-bit-color.sh \
https://gitlab.gnome.org/GNOME/vte/-/raw/master/perf/img.sh
# read the scripts with your editor
$EDITOR *
<span style="color:#c00">Stop!</span> Only if you're satisfied that the scripts are trustworthy should you proceed:
# if you trust them, run them
perl color-spaces.pl
python colors.py
bash 24-bit-color.sh
bash img.sh
</div>
Keep in mind that it is possible to use both ';' and ':' as Control Sequence delimiters.
According to Wikipedia[1], this behavior is only supported by xterm and konsole.
[1] https://en.wikipedia.org/wiki/ANSI_color
Truecolor Detection
Checking for COLORTERM
VTE,
Konsole and
iTerm2 all advertise
truecolor support by placing COLORTERM=truecolor
in the environment of the
shell user's shell. This has been in VTE for a while, but is relatively new in
Konsole and iTerm2 and has to be enabled at compile time (most packages do not,
so you have to compile them yourself from the git source repo).
The S-Lang library has a check that $COLORTERM
contains either "truecolor" or
"24bit" (case sensitive).
Terminfo has supported the 24-bit TrueColor capability since ncurses-6.0-20180121, under the name "RGB". You need to use the "setaf" and "setab" commands to set the foreground and background respectively.
Having an extra environment variable (separate from TERM
) is not ideal: by
default it is not forwarded via sudo, ssh, etc, and so it may still be
unreliable even where support is available in programs. (It does however err on
the side of safety: it does not advertise support when it is not actually
supported, and the programs should fall back to using 8-bit color.)
These issues can be ameliorated by adding COLORTERM
to:
- the
SendEnv
list in/etc/ssh/ssh_config
on ssh clients; - the
AcceptEnv
list in/etc/ssh/sshd_config
on ssh servers; and - the
env_keep
list in/etc/sudoers
.
Despite these problems, it's currently the best option, so checking
$COLORTERM
is recommended since it will lead to a more seamless desktop
experience where only one variable needs to be set.
App developers can freely choose to check for this variable, or introduce their own method (e.g. an option in their config file). They should use whichever method best matches the overall design of their app.
Ideally any terminal that really supports truecolor would set this variable;
but as a work-around you might need to put a check in /etc/profile
to set
COLORTERM=truecolor
when $TERM
matches any terminal type known to have
working truecolor.
case $TERM in
iterm |\
linux-truecolor |\
screen-truecolor |\
tmux-truecolor |\
xterm-truecolor ) export COLORTERM=truecolor ;;
vte*)
esac
Querying The Terminal
In an interactive program that can read terminal responses, a more reliable method is available, that is transparent to sudo & ssh.
Simply try sending a truecolor value to the terminal, followed by a query to ask what color it currently has. If the response indicates the same color as was just set, then truecolor is supported.
If the response indicates an 8-bit color, or does not indicate a color, or if no response is forthcoming within a few centiseconds, then assume that truecolor is not supported.
$ ( printf '\e[48:2:1:2:3m\eP$qm\e\\' ; xxd -g1 )
^[P1$r48:2:1:2:3m^[\
00000000: 1b 50 31 24 72 34 38 3a 32 3a 31 3a 32 3a 33 6d .P1$r48:2:1:2:3m
Here we set the background color to RGB(1,2,3)
- an unlikely default
choice - and request the value that we just set. The response comes back that
the request was understood (1
), and that the color is indeed 48:2:1:2:3
.
This tells us also that the terminal supports the colon delimiter. If instead,
the terminal did not support truecolor we might see a response like
^[P1$r40m^[\
00000000: 1b 50 31 24 72 34 30 6d 1b 5c 0a .P1$r40m.\.
This terminal replied that the color is 40
- it has not accepted our request
to set 48:2:1:2:3
.
^[P0$r^[\
00000000: 1b 50 30 24 72 1b 5c 0a .P0$r.\.
This terminal did not even understand the DECRQSS
request - its response was
CSI
+0$r
. This does not indicate whether it set the color, but since it
doesn't understand how to reply to our request it is unlikely to support
truecolor either.
Truecolor Support in Output Devices
Fully Supporting
Terminal Emulators
- alacritty [delimiter: colon, semicolon] - written in Rust
- Black Screen [delimiter: semicolon] - cross-platform, HTML/CSS/JS-based
- cmd.exe [delimiter: semicolon] Built-in Windows shell that is mostly unchanged since DOS Windows 10
- ConEmu [delimiter: semicolon] - Windows platform
- ConHost [delimiter: semicolon] Built-in Windows console (usually hosting cmd.exe) that is mostly unchanged since DOS Windows 10
- ConnectBot - Android platform - since 3bcc75ccedaf2136b04c5932c81a5155f29dc3b5 commit.
- Contour [delimiter: semicolon] - written in C++17, uses OpenGL
- cool-retro-term [delimiter: semicolon]
- FinalTerm [delimiter: semicolon] - abandoned, iTerm2 borrowing it's ideas and features.
- foot [delimiter: colon, semicolon] - Wayland terminal
- hterm - HTML/CSS/JS-based (ChromeOS)
- iTerm2 [delimiter: colon, semicolon] - since v3 version
- kitty [delimiter: colon,semicolon] - uses OpenGL
- konsole [delimiter: colon, semicolon] - https://bugs.kde.org/show_bug.cgi?id=107487
- MacTerm [delimiter: semicolon] - Mac OS X platform
- mintty [delimiter: semicolon] Cygwin and MSYS/MSYS2 since commit 43f0ed8a46c6549cb9a3ea27abc057b5abe13bdb (2.0.1 release) - Windows platform
- MobaXterm Windows platform - closed source (run
lscolors
to see a truecolor test) - mosh (Mobile SHell) [delimiter: semicolon] - since commit 6cfa4aef598146cfbde7f7a4a83438c3769a2835
- Netsarang XShell - Xshell7/ Xshell6 >= Build 0181 (You must set Tools-Options.. -Advanced, check the Use true color* and reopen the software)
- pangoterm [delimiter: colon, semicolon]
- PowerShell Core [delimiter: semicolon] aka PowerShell 6+ Windows 10
- PuTTY - landed in git (patched version [3] {approximation to 256 colors} and [4] {real truecolors} available) - Windows platform
- qterminal [delimiter: semicolon] - after version 0.14.1 (issue #78)
- st (from suckless) [delimiter: semicolon] - https://lists.suckless.org/dev/1307/16688.html
- Tera Term [delimiter: colon, semicolon] - Windows platform
- Termux [delimiter: semicolon] - Android platform
- Therm [delimiter: colon, semicolon] - fork of iTerm2
- upterm Windows/MacOS/Linux Electron - A terminal emulator for the 21st century.
- Warp - MacOS X platform written in Rust
- wezterm [delimeter: colon] - written in Rust
- Windows 10 bash console, since Windows Insiders build 14931
- Windows Powershell [delimiter: semicolon] - aka PowerShell 5.x and below Windows 10
- xst - fork of st
- xterm - (from 331 (change 330j)
- All libvte based terminals (since 0.36 version) [delimiter: colon, semicolon] - https://bugzilla.gnome.org/show_bug.cgi?id=704449
- libvte-based evilvte - no release yet, version from git https://github.com/caleb-/evilvte
- libvte-based Gnome Terminal
- libvte-based guake - A top-down terminal for GNOME
- libvte-based Lilyterm - since commit 72536e7ba448ad9ef1126ce45fbde3a3407a271b
- libvte-based lxterminal - with --enable-gtk3 configure flag.
- libvte-based Pantheon Terminal
- libvte-based ROXTerm
- libvte-based sakura
- libvte-based Terminator - since 1.90 release
- libvte-based Termit
- libvte-based Termite (NOT MAINTAINED)
- libvte-based Tilda
- libvte-based Tilix - written in D. Similar user interface as for Terminator.
- libvte-based tinyterm
- libvte-based xfce4-terminal - since 0.6.90 release, if compiled with GTK+3
- All xterm.js based terminals (since v3.13, v4.3 for webgl) [delimiter: semicolon]
- ZOC Windows/OS X platform - closed source since 7.19.0 version
There are a bunch of libvte-based terminals for GTK2, so they are listed in the another section.
Multiplexers
- dvtm - not yet supporting truecolor https://github.com/martanne/dvtm/issues/10
- pymux - tmux clone in pure Python (to enable truecolor run pymux with
--truecolor
option) - screen - has support in 'master' branch, need to be enabled (see 'truecolor' option)
- tmux - starting from version 2.2 (support since 427b820...)
Re-players
Partial Support
These terminal emulators parse ANSI color sequences, but approximate the true color using a palette or limit number of true colors that can be used at the same time. A 256-color (8-bit) palette is used unless specified.
- Linux console (fbcon), since v3.16 - https://bugzilla.kernel.org/show_bug.cgi?id=79551 (downgraded to 16 foregrounds and 8 backgrounds)
- mlterm - built with --with-gtk=3.0 configure flag. Approximates colors using a 512-color embedded palette (https://sourceforge.net/p/mlterm/bugs/74/)
- urxvt aka rxvt-unicode - since revision 1.570. Limits maximum number of colors: http://lists.schmorp.de/pipermail/rxvt-unicode/2016q2/002261.html
Note about color differences
Human eyes are sensitive to the primary colors in such a way that the simple Gaussian distance √(R²+G²+B²) gives poor results when trying to find the "nearest" available color as perceived by most humans.
The CIEDE2000 formula provides much better perceptual matching, but it is considerably more complex and may perform very slowly if used blindly [2].
[2] https://github.com/neovim/neovim/issues/793#issuecomment-48106948
Not Supporting Truecolor
- aterm (looks abandoned) - https://sourceforge.net/p/aterm/feature-requests/23/
- Cmder: Portable console emulator for Windows, based on ConEmu.
- fbcon (prior to Linux 3.16) - https://bugzilla.kernel.org/show_bug.cgi?id=79551
- FreeBSD console
- Hyper.app [delimiter: semicolon] - cross-platform, HTML/CSS/JS-based (Electron) https://github.com/zeit/hyper/issues/2294
- JuiceSSH - Android platform, closed source
- KiTTY - Windows platform
- mRemoteNG - Windows platform - issue #717
- mrxvt (looks abandoned) - https://sourceforge.net/p/materm/feature-requests/41/
- MTPuTTY - Windows platform
- SmarTTY - Windows platform - closed source (sent them a request)
- Terminal.app: MacOS Terminal built-in
- Terminology (Enlightenment) - https://phab.enlightenment.org/T746
- Terminus: highly configurable terminal emulator for Windows, MacOS and Linux
- Termius - Linux, Windows, OS X platforms, closed source
- yaft framebuffer terminal - issue #12
- libvte and GTK2 - based:
Console Programs + Truecolor
Console Programs Supporting Truecolor
- dte text editor - (since version 1.8)
- elinks - configure.in:1410 (./configure --enable-true-color)
- emacs - since 26.1 release
- Eternal Terminal - automatically reconnecting shell
- explosion - terminal image viewer
- irssi - since PR #48
- joe - (from 4.5 version)
- ls-icons - fork of coreutils with
ls
program that supports icons - mc - since 682a5.... See also ticket #3724 for truecolor themes.
- micro editor
- mpv - video player with support of console-only output (since 0.22 version)
- ncurses library - since 6.1 version
- neovim - since commit 8dd415e887923f99ab5daaeba9f0303e173dd1aa; need to set termguicolors to enable truecolor.
- Notcurses library - all releases
- radare2 - reverse engineering framework; since 0.9.6 version.
- rizin - reverse engineering framework; since the inception (a fork of radare2).
- s-lang library - (since pre2.3.1-35, for 64bit systems)
- tcell library for Go language
- termimage - terminal image viewer
- termpaint low level library (C) - all releases
- timg - Terminal Image Viewer
- Tui Widgets library (C++/QtCore) - all releases
- tv - tool to quickly view high-resolution multi-band imagery directly in terminal
- vifm file manager - since 0.12 version
- vim - (from 7.4.1770); need to set termguicolors to enable truecolor.
Console Programs Not Supporting Truecolor
- cmus (music player) - issue #799
- gui.cs Terminal UI toolkit for .NET (curses-like) - issue #48
- mcabber (jabber client) - issue #126
- mutt (email client) - http://dev.mutt.org/trac/ticket/3674
- neomutt (email client) - issue #58
- scim (spreadsheet program) - issue #306
- termbox library - issue #37 (there is a fork termbox_next with the support
- tig (git TUI) - issue #227
- weechat (chat client) - issue #1364