My day-to-day work on computers involves Linux consoles, lots of them. At a minimum I have a console for the machine I am doing my work on, but typically I'll be working across 3 or more hosts (my Windows workstation, my Linux workstation, a server I admin, the local cluster and a remote cluster), and almost certainly have more than one shell open per host.
I mention all this because it means I have a lot of shells around, too many to have one per window! Rather, I use GNU screen to “tab” my shells together, leaving me with one window per host that has a tab for each shell.
Because most of my work is done on remote (headless) machines via SSH the most convenient way to work with, well, anything is via text-only interfaces. For this reason, among others, vim is my preferred editor.
I like colourful syntax highlighting, and vim provides it. But only 16 colours in most terminals. It turns out this is usually because of poor configuration - most mainstream terminal emulators (PuTTY / xterm / gnome-terminal / rvxt…) support 256 colours, but you have to enable it and/or let your applications know about it capabilities.
See http://www.frexx.de/xterm-256-notes/ for some scripts which produce test patterns. Just in case that site disappears, I'll reproduce the script and screen shot here:
The Perl script: 256colors2.pl
What you will see if your terminal supports 256 colours:
And here's what you'll see if it doesn't:
:help xterm-color for the official documentation. It makes mention of 256 colours, but isn't hugely helpful.
New versions of Vim come with a colour-test script you can run. Start Vim and enter the following command:
Chances are that the first time you do this your “red” and “lightred” will look identical. Try telling Vim that your terminal supports 256 colours:
And then rerun the colour test. If all goes well you're output will look like this:
Chances are your
$TERM environment variable is set to xterm. Try setting it to
xterm-256color (remember to export it) and try again:
export TERM=xterm-256color vim "+runtime syntax/colortest.vim"
If you get an error about unknown terminal, or unknown terminal capabilities, try installed the
ncurses-term package. It contains terminal definitions which intelligent programs can use to determine the exact capabilities of a terminal named by the
$TERM environment variable. On Debian-based distros:
sudo apt-get install ncurses-term
You may need to open a new terminal for this to have an effect.
For PuTTY, you can change what
TERM name it sends under Settings → Connection → Data → “Terminal-type string”. Change it to
For gnome-terminal, the default Ubuntu terminal if you didn't customise your install, you can't change what it reports itself as:
xterm. My work around for this was to add the following snippet to my
if [ "$TERM" == "xterm" ]; then # No it isn't, it's gnome-terminal export TERM=xterm-256color fi
In case this is getting confusing here's what's been covered so far:
xterm-256color, or using login-scripts to change the reported name as a work-around.
So at this point you should be able to open a new terminal, run
vim “+runtime syntax/colortest.vim” and see 256 color mode working.
Now, unless you're extra-ordinarily lucky, running GNU screen will prevent 256 colors working. This is often because screen is compiled without 256-colour support on most distros.
But before diving into recompiling we should update screen's configuration file so that we can be sure it's doing the right thing. Create/modify
~/.screenrc and add the following lines to it:
# Enable 256-color mode when screen is started with TERM=xterm-256color # Taken from: http://frexx.de/xterm-256-notes/ # # Note that TERM != "xterm-256color" within a screen window. Rather it is # "screen" or "screen-bce" # # terminfo and termcap for nice 256 color terminal # allow bold colors - necessary for some reason attrcolor b ".I" # tell screen how to set colors. AB = background, AF=foreground termcapinfo xterm-256color 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
And then (re)start screen and try the
256color2.pl test script. If it doesn't work, and you're sure that
TERM=xterm-256color when you start screen and that it's being exported1), you need to recompile screen with 256-color support.
Here's a quick-and-dirty guide on how to recompile it on Ubuntu, see Debian's source-packages HOWTO guide for more detail.
sudo apt-get build-dep screen # Install whatever's needed to compile screen apt-get source screen # Download + extract screen source cd ./screen-4.0.3 ./configure --help | grep 256 # Find magic option we need vim debian/rules # Edit package build rules, and add \ # --enable-colors256 to the ./configure command line fakeroot dpkg-buildpackage -uc -b # Create a *.deb package file in the directory above current cd .. sudo dpkg -i screen_4.0.3-7ubuntu1_i386.deb # Install the newly create package
256color2.pl script should produce pretty colours even in screen. But Vim might not.
In my experience this is because screen sets some environment variables when it starts. In particular,
TERM=screen. This of course prevents Vim from knowing that 256-colour mode is supported. I experimented with overriding this and setting it back to
TERM=xterm-256color, but that seemed to break lots of other apps, such as
aptitude. It did fix Vim though.
Another problem is that screen sets
TERMCAP with a colours (
Co) entry set to just 8, not 256. See for yourself:
echo $TERMCAP | sed -e 's/:/\n/g' | grep Co # Prints 'Co#8'
TERMCAP is a list of colon-seperated capabilities for the current terminal. Newer distros prefer to use a system-wide
terminfo database, which allow applications to lookup, say,
xterm-256color (the name of a terminal) though an API and discover it's full list of capabilities; including that it supports 256-colors.
TERMCAP is still supported, and when defined it appears to take precedence over terminfo. At least it does with Vim.
So it would appear the correct solution is: Leave
TERM=screen alone and mangle the
TERMCAP variable so that its
Co entry is set to 256, and export it:
export TERMCAP=$(echo $TERMCAP | sed -e 's/Co#8/Co#256/g')
…and make sure Vim uses the
TERMCAP settings by adding this to
" Work-around incomplete terminfo databases " Particulalry useful when under `screen`, which may or may not be attached to " a physical terminal capable of 256color mode. if match($TERMCAP, 'Co#256:') == 0 || match($TERMCAP, ':Co#256:') > 0 set t_Co=256 endif
This will make Vim check if
TERMCAP contains a
Co#256 entry (either at the beginning or elsewhere) and set 256-colour mode accordingly.
Now run Vim and its colour test again, and you should get all the colours!
This is what
~/.bashrc is for!
if [ ! -z "$TERMCAP" ] && [ "$TERM" == "screen" ]; then export TERMCAP=$(echo $TERMCAP | sed -e 's/Co#8/Co#256/g') fi
TERM=xterm-256color; export TERMor shotcut with