Terminal Colors
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 true color: "888" colors (aka 16 milion)
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 "true color" 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 itself.
This is a good 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 Control Sequence
Introducer delimiters.
According to Wikipedia[1], this behavior is only supported by xterm and konsole.
[1] https://en.wikipedia.org/wiki/ANSI_color
Since
ncurses-6.0-20180121,
terminfo began to support the 24-bit True Color capability under the name of
"RGB". You need to use the "setaf" and "setab" commands to set the foreground
and background respectively.
True Color Detection
There will be no reliable way to detect the "RGB" flag until the new release of
terminfo/ncurses. S-Lang author added a check for $COLORTERM containing either
"truecolor" or "24bit" (case sensitive). In addition,
VTE,
Konsole and
iTerm2 set this variable to
"truecolor". It has been in VTE for a while and but is relatively new, being
still git-only in Konsole and iTerm2).
This is obviously not a reliable method, and is not forwarded via sudo, SSH etc.
However, whenever it errs, it errs on the safe side. It does not advertise
support when it is actually unsupported. App developers can freely choose to
check for this same 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. Checking $COLORTERM is recommended though since it will
lead to a more seamless desktop experience where only one variable needs to be
set. This would be system-wide so that the user would not need to set it
separately for each app.
Querying The Terminal
A more reliable method in an interactive program which can read terminal
responses, and one that is transparent to things like sudo, SSH, etc.. is to
simply try setting a truecolor value and then query the terminal to ask what
color it currently has. If the response replies the same color that was set
then it indicates truecolor is supported.
$ (echo -e '\e[48:2:1:2:3m\eP$qm\e\\' ; xxd)
^[P1$r48:2:1:2:3m^[\
00000000: 1b50 3124 7234 383a 323a 313a 323a 336d .P1$r48:2:1:2:3m
Here we ask to 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: 1b50 3124 7234 306d 1b5c 0a .P1$r40m.\.
This terminal replied the color is 40 - it has not accepted our request to
set 48:2:1:2:3.
^[P0$r^[\
00000000: 1b50 3024 721b 5c0a .P0$r.\.
This terminal did not even understand the DECRQSS request - its response was
0$r. We do not learn if it managed to set the color, but since it doesn't
understand how to reply to our request it is unlikely to support truecolor
either.
Terminals + True Color
Now Supporting True Color
- st (from suckless) [delimeter: semicolon] -
http://lists.suckless.org/dev/1307/16688.html
- xst - fork of st
- konsole [delimeter: colon,
semicolon] - https://bugs.kde.org/show_bug.cgi?id=107487
- iTerm2 [delimeter: colon, semicolon] - since v3
version
- Therm [delimeter: colon, semicolon] - fork
of iTerm2
- qterminal [delimeter: semicolon] - > 0.14.1 versions (issue #78)
- alacritty [delimeter: semicolon] -
written in Rust
- kitty [delimeter: colon,semicolon] -
uses OpenGL
- cool-retro-term [delimeter:
semicolon]
- mosh (Mobile SHell) [delimeter: semicolon] - since commit 6cfa4aef598146cfbde7f7a4a83438c3769a2835
- pangoterm [delimeter:
colon, semicolon]
- Termux [delimeter: semicolon] - Android platform
- ConnectBot - Android platform - since 3bcc75ccedaf2136b04c5932c81a5155f29dc3b5 commit.
- Black Screen [delimeter:
semicolon] - crossplatform, HTML/CSS/JS-based
- hterm -
HTML/CSS/JS-based (ChromeOS)
- PuTTY -
landed
in git (patched version [3] {xterm-like approximation to 256 colors} and [4]
{real true colors} available) - Windows platform
- Tera Term [delimeter: colon,
semicolon] - Windows platform
- ConEmu [delimeter: semicolon] -
Windows platform
- Windows
Powershell
[delimeter: semicolon] - aka Powershell 5.x and below Windows 10
- Powershell Core [delimeter:
semicolon] aka Powershell 6+ Windows 10
- cmd.exe [delimeter:
semicolon] Builtin Windows shell that is mostly unchanged since DOS Windows 10
- FinalTerm [delimeter: semicolon] -
abandoned, iTerm2
borrowing it's ideas and features.
- MacTerm [delimeter: semicolon] - Mac
OS X platform
- mintty [delimeter: 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)
- ZOC Windows/OS X platform - closed
source since
7.19.0 version
- upterm Windows/Macos/Linux Electron -
A terminal emulator for the 21st century.
- Windows 10 bash console, since
Windows Insiders build 14931
- All libvte based terminals
(since 0.36 version) [delimeter: colon, semicolon] -
https://bugzilla.gnome.org/show_bug.cgi?id=704449
- All xterm.js based terminals (since v3.13, v4.3 for webgl) [delimeter: semicolon]
- VS Code's integrated terminal
- Terminus: highly configurable terminal emulator for Windows, macOS and Linux
There are a bunch of libvte-based terminals for GTK2, so they are listed in the
another section.
Also, while this one is not a terminal, but a terminal replayer, it is
still worth mentioning:
Improper Support for True Color
Terminals that parse ANSI color sequences, but approximate them to 256 palette
Note about color differences:
a) RGB axes are not orthogonal, so you cannot use
sqrt(R^2+G^2+B^2) formula
b) for color 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
NOT Supporting True Color
Console Programs + True Color
Console Programs Supporting True Color
Console Programs Not Supporting True Color
See the repository https://github.com/termstandard/colors
Or the gist and discussion here: https://gist.github.com/XVilka/8346728
Terminal Colors
There exists common confusion about terminal colors. This is what we have right now:
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 "true color" 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 itself.
This is a good test case:
https://raw.githubusercontent.com/JohnMorales/dotfiles/master/colors/24-bit-color.sh
Keep in mind that it is possible to use both ';' and ':' as Control Sequence
Introducer delimiters.
According to Wikipedia[1], this behavior is only supported by xterm and konsole.
[1] https://en.wikipedia.org/wiki/ANSI_color
Since
ncurses-6.0-20180121,
terminfo began to support the 24-bit True Color capability under the name of
"RGB". You need to use the "setaf" and "setab" commands to set the foreground
and background respectively.
True Color Detection
There will be no reliable way to detect the "RGB" flag until the new release of
terminfo/ncurses. S-Lang author added a check for $COLORTERM containing either
"truecolor" or "24bit" (case sensitive). In addition,
VTE,
Konsole and
iTerm2 set this variable to
"truecolor". It has been in VTE for a while and but is relatively new, being
still git-only in Konsole and iTerm2).
This is obviously not a reliable method, and is not forwarded via sudo, SSH etc.
However, whenever it errs, it errs on the safe side. It does not advertise
support when it is actually unsupported. App developers can freely choose to
check for this same 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. Checking $COLORTERM is recommended though since it will
lead to a more seamless desktop experience where only one variable needs to be
set. This would be system-wide so that the user would not need to set it
separately for each app.
Querying The Terminal
A more reliable method in an interactive program which can read terminal
responses, and one that is transparent to things like sudo, SSH, etc.. is to
simply try setting a truecolor value and then query the terminal to ask what
color it currently has. If the response replies the same color that was set
then it indicates truecolor is supported.
Here we ask to set the background color to
RGB(1,2,3)- an unlikely defaultchoice - and request the value that we just set. The response comes back that
the request was understood (
1), and that the color is indeed48: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
This terminal replied the color is
40- it has not accepted our request toset
48:2:1:2:3.This terminal did not even understand the DECRQSS request - its response was
0$r. We do not learn if it managed to set the color, but since it doesn'tunderstand how to reply to our request it is unlikely to support truecolor
either.
Terminals + True Color
Now Supporting True Color
http://lists.suckless.org/dev/1307/16688.html
semicolon] - https://bugs.kde.org/show_bug.cgi?id=107487
version
of iTerm2
written in Rust
uses OpenGL
semicolon]
colon, semicolon]
semicolon] - crossplatform, HTML/CSS/JS-based
HTML/CSS/JS-based (ChromeOS)
landed
in git (patched version [3] {xterm-like approximation to 256 colors} and [4]
{real true colors} available) - Windows platform
semicolon] - Windows platform
Windows platform
Powershell
[delimeter: semicolon] - aka Powershell 5.x and below Windows 10
semicolon] aka Powershell 6+ Windows 10
semicolon] Builtin Windows shell that is mostly unchanged since DOS Windows 10
abandoned, iTerm2
borrowing it's ideas and features.
OS X platform
MSYS/MSYS2 since commit 43f0ed8a46c6549cb9a3ea27abc057b5abe13bdb
(2.0.1 release) - Windows platform
source (run
lscolorsto see a truecolor test)source since
7.19.0 version
A terminal emulator for the 21st century.
Windows Insiders build 14931
(since 0.36 version) [delimeter: colon, semicolon] -
https://bugzilla.gnome.org/show_bug.cgi?id=704449
Gnome Terminal
xfce4-terminal - since
0.6.90
release, if compiled with GTK+3
Terminator -
since 1.90 release
Similar user interface as for Terminator.
version from git https://github.com/caleb-/evilvte
Pantheon Terminal
--enable-gtk3 configure flag.
There are a bunch of libvte-based terminals for GTK2, so they are listed in the
another section.
Also, while this one is not a terminal, but a terminal replayer, it is
still worth mentioning:
https://github.com/asciinema/asciinema-player
Improper Support for True Color
configure flag. Approximates colors to 512 embedded palette
(https://sourceforge.net/p/mlterm/bugs/74/)
Terminals that parse ANSI color sequences, but approximate them to 256 palette
with a usual false assumption about orthogonal axes")
since
Revision 1.570
http://lists.schmorp.de/pipermail/rxvt-unicode/2016q2/002261.html (Note there
is a restriction of colors count still)
Note about color differences:
a) RGB axes are not orthogonal, so you cannot use
sqrt(R^2+G^2+B^2) formula
b) for color 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
427b820...)
'master' branch, need to be enabled (see 'truecolor' option)
(to enable truecolor run pymux with
--truecoloroption)Add support for true color martanne/dvtm#10
NOT Supporting True Color
(Enlightenment) - https://phab.enlightenment.org/T746
based on ConEmu.
https://sourceforge.net/p/materm/feature-requests/41/
https://sourceforge.net/p/aterm/feature-requests/23/
closed source
(sent them a request)
closed source (sent them an email)
Console Programs + True Color
Console Programs Supporting True Color
library - (since pre2.3.1-35, for 64bit systems)
reconnecting shell
682a5....
See also ticket #3724 for
truecolor themes.
PR #48
8dd415e887923f99ab5daaeba9f0303e173dd1aa;
need to set
termguicolors to
enable true color.
termguicolors
to enable true color.
4.5
version)
26.1 release
configure.in:1410
(./configure --enable-true-color)
multi-band imagery directly in terminal
viewer
lsprogram that supports iconsconsole-only output (since 0.22 version)
since 0.9.6 version.
Console Programs Not Supporting True Color
See the repository https://github.com/termstandard/colors
Or the gist and discussion here: https://gist.github.com/XVilka/8346728