**See also:** * [[:coding:version_control:git#Colour|Colour in GIT]] ====== Colour colour everywhere! 256 colour-mode for Linux consoles ====== 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 [[wp>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, [[wp>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. ===== So, does terminal do 256 colours? ===== See [[https://gist.github.com/hSATAC/1095100]] for a script which produce test patterns. Just in case it disappears, I'll reproduce the script and screen shot here: The Perl script: {{:unix:256colors2.pl|256colors2.pl}} What you will see if your terminal supports 256 colours: {{ :unix:256colors2.png |Expected output from 256colors2.pl}} And here's what you'll see if it doesn't: {{ :unix:16colors.png |16-colour mode output from 256colors2.pl}} Make sure you are running these scripts directly in your terminal - don't start them from within screen or any other kind of "manager" that might interpret / translate output. If you use [[wp>PuTTY]], then be sure to tick "Allow terminal to use xterm 256-color mode" under Settings -> Window -> Colours ==== Gnome Terminal ==== Gnome Terminal //does// support 256 colour mode, but doesn't always sets the ''TERM'' variable to ''xterm'', rather than ''xterm-256color''. There's no way to override this directly, but you can work around it by setting: Profile Preferences → Title and Command → Run a custom command instead of my shell → ''env TERM=xterm-256color /bin/bash'' Credit to https://superuser.com/questions/841016/how-to-configure-gnome-terminal-to-use-xterm-256color-by-default ===== OK, it does. Now how about Vim? ===== See '':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: :runtime syntax/colortest.vim 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: :let &t_Co=256 And then rerun the colour test. If all goes well you're output will look like this: {{ :unix:256colourvim.png |Successful 256 colour test in Vim}} ===== Getting Vim to use all colours without hard-coding it ===== 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. ===== Setting TERM=xterm-256color by default ===== For PuTTY, you can change what ''TERM'' name it sends under Settings -> Connection -> Data -> "Terminal-type string". Change it to ''xterm-256color'', done! 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 ''~/.bashrc'': if [ "$TERM" == "xterm" ]; then # No it isn't, it's gnome-terminal export TERM=xterm-256color fi ===== Recap: The story so far ===== In case this is getting confusing here's what's been covered so far: - Checking your terminal can display 256 colour text - Checking Vim can make use of these colours by setting ''TERM=xterm-256color'' * Possibly installing a support package so that so is a meaningful name - Configuring the terminal to report it's ''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. ===== And finally, keeping it working under GNU screen ===== Now, unless you're extra-ordinarily lucky, running [[wp>GNU screen]] will prevent 256 colors working. This is often because screen is compiled without 256-colour support on most distros. ==== Run-time configuration ==== 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 exported((TERM=xterm-256color sets it for the current shell, but only the current shell. Child processes will not see it. To cause child processes to see it it must be 'exported' with the 'export' command. E.g.: ''TERM=xterm-256color; export TERM'' or shotcut with ''export TERM=xterm-256color'')), you need to recompile screen with 256-color support. ==== Compile-time configuration ==== Here's a quick-and-dirty guide on how to recompile it on Ubuntu, see [[http://www.debian.org/doc/manuals/apt-howto/ch-sourcehandling.en.html|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 Now the ''256color2.pl'' script should produce pretty colours even in screen. But Vim might not. ==== Vim under screen refuses to conform! ==== 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. But ''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 ''~/.vimrc'': " 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! ==== Making the TERMCAP mangling automatic ==== 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