The problem#
By default, terminals on Linux only use 8 colors (or 16 if setup to
use bright
variants instead of bold text). Everything else on a
modern computer uses 24-bit color, allowing for millions of colors. More
colors in the terminal would allow for better syntax highlighting and
color output of various commands to be more readable.
In practice, while a few terminals support full 24-bit RGB color (at least Konsole does), it is not widespread enough to be used much. On the other hand, most terminals support 256 colors, which is significantly better than just 8.
Setting up 256 color terminals#
Testing 256 color support#
First, check if your terminal already supports 256 colors. You will
probably want to rerun this check for confirming that you get 256 colors
when connecting to another computer over ssh
and/or inside a
screen
or tmux
session if you use those programs.
tput
gives various information about the terminal, including
how many colors it supports:
$ tput colors
256
The script 256colors2.pl
linked from
this guide on setting up 256 color terminals will
attempt to display all of the colors, making it clear if your setup is
actually displaying the colors correctly. For a pure shell solution which
also displays the numbers, use
#!/bin/sh
for i in $(seq 0 255)
do
printf '\033[1;38;5;%dmcolor %d\n' "$i" "$i"
done
Basic support#
As your terminal program almost certainly supports 256 colors and is
merely not telling the terminal about it, the fix is to correctly set
the $TERM
variable to announce 256 color support to the commands
running in your terminal.
I did so in a very simple way by adding the following to by ~/.bashrc
:
if [ -n "$DISPLAY" -a "$TERM" == "xterm" ]; then
export TERM=xterm-256color
fi
The Fedora project's page on 256 color terminals includes a more comprehensive script that supports more terminal programs.
Those pages suggest that Debian/Ubuntu need the ncurses-term
package
in order for 256 color terminals to work properly, but that information
is apparently out of date as I do not have that package installed.
When using ssh
, the TERM
variable of the client is visible to
the server, so this should also make 256 color terminals work over
ssh
as long as the computers you are connecting to have the
xterm-256color
terminfo.
GNU Screen and Tmux#
As GNU Screen and Tmux act like terminal emulators, they
also need to be configured to support 256 colors. In my ~/.screenrc
,
simply added the following from here:
# enable 256 color support
term screen-256color
That makes screen
always claim to its clients that it can display
256 colors. If it can't actually do so, it will map the colors down to
the standard 8 color space. This does have the side effect of making
the colors look a bit worse when using 8 color terminals due to color
schemes for 256 colors being designed for closer colors being okay,
but that's a minor problem because it's rare you will run across such
a terminal (FingerTerm on my Nokia N9 is the only one I
use).
In order to get GNU Screen to work properly, we had it claim to be GNU Screen with 256 color support. To get Tmux to work properly, we also have it claim to be GNU Screen with 256 color support.
Vim and CSApprox#
At this point, all of your terminals should have 256 color support,
including when nesting ssh
and screen
/tmux
, but
we haven't actually accomplished anything unless you really like looking
at the color patterns output by 256colors2.pl
.
To check if vim
supports 256 colors, install
xterm-color-table.vim
(using Vundle)
which adds the :XtermColorTable
command to vim
(it also works in
gvim
; make sure you are actually running console vim
). I did
not have to do anything special, but if it does not work for you, look
into these workarounds.
You probably have color schemes that specify colors for GUI Vim in
24-bit color. Since our terminal is 256 colors, not 24-bit color, those
cannot be used directly. The solution is CSApprox. CSApprox
approximates 24-bit color with your terminal's available 256 colors,
making console vim
look almost as good as gvim
.
How does it work?#
Normally, terminals display whatever text is sent to them directly to the user. Not all characters are actually displayable, particularly control characters exist specifically to have special meanings outside of being shown directly to a user. Newlines and [tabs][tab] are two of these special characters which tell the terminal to move the cursor to a different location instead of displaying a character immediately.
For more advanced commands, terminals
support a whole range of ANSI escape codes which begin with
the control character 0x1b
(or \033
in octal) followed by [
. Some of
these commands are for changing the foreground or background color of text.
From the script above
printf '\033[1;38;5;%dmcolor %d\n' "$i" "$i"
sets the color to $i
(which replaces %d
in the format string)
because \033[
starts the escape sequence, 1;
means to make it bold,
and 38;5;
is the code for setting a foreground color for a 256 color
terminal, followed by the color number itself and then m
terminates
the command telling the terminal to interpret the rest of the string as
normal text. Changing the 38
to 48
makes a command for setting the
background color instead.
If you want to set colors for an 8-color terminal, the ANSI
colours
table on this page will show the proper code. It's a
little more complicated because instead of having one command with an
argument, each color is actually a separate command.
Comments
Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.
There are no comments yet.