Support for 256 colors in Vim under screen (Fedora)

Posted on . Updated on .

One of the positive surprises in my migration to Fedora was finding out how support for 256-color terminals worked. Some time ago, Fedora created a plan for supporting 256 colors in terminals.

They included support for those applications that needed it in the standard distribution packages, and provided a script in /etc/profile.d that detects if you’re running a shell under a terminal with support for 256 colors, changing the TERM environment variable accordingly. Apart from that, termcap is not present in the system and terminfo has proper terminal information files to support 256 colors.

This prompted me to quickly remove all tricks and specific settings I had in Slackware to enable support for 256 colors. That includes changing TERM from my own $HOME/.profile, and a few lines here and there, like a terminal information line in $HOME/.screenrc. I installed xterm, launched a login session in it and, voila, 256 colors working out of the box.

Then I launched xterm with screen, which I have configured to use a login shell too and, voila again, TERM was automatically set to screen-256color and a quick test confirmed the support was indeed present. So far, so good.

Finally, I launched Vim inside the screen session with my configured 256-colors theme (it’s inkpot, by the way) and it was also working. Strike three. Woot!

2016-06-26 Update: the “screen -T” trick described below is no longer needed in Fedora 24. See my updated post.

But I quickly noticed if I launched Vim in a new screen window, as when running “screen vim”, it was black and white. At this point, if you perform a web search the most common advice is to stick a line with “set t_Co=256” in your $HOME/.vimrc. That line tells Vim that, no matter what, the underlying terminal supports 256 colors. Most people apply that solution because it’s simple and it works, but I don’t recommend it if you can solve the problem properly.

I decided to find out why Vim didn’t think my terminal had support for 256 colors. It took me some time and fiddling to find out, but it turned out to be very simple. When launching “screen vim”, screen by default sets TERM to “screen” unless you specify otherwise in $HOME/.screenrc. Because screen is launching Vim directly in that case, the shell script in /etc/profile.d had no chance to kick in and modify TERM as usual, so TERM was being passed unmodified to Vim. You can easily check it by using “:echo $TERM” from Vim. And if TERM is “screen”, Vim will not attempt to use 256 colors.

Two proper solutions come to my mind. Please comment and share yours if you find better ways.

  1. Changing $HOME/.screenrc so screen sets TERM for new terminal windows to “screen-256color”, using the “term” command. This is not what I did, but it should work.

  2. My preferred alternative: in your login shell inside screen, TERM already has the correct value (screen-256color), so instructing screen to pass along the current TERM value to programs launched in new windows should do the trick. To do that, use “screen -T "$TERM" <command>” when creating a new window.

Choosing the second solution and using it by hand is a pain in the neck, but fortunately I already had a shell function called “launch” that launches programs in a new screen window when inside a screen session, and launches them normally otherwise. That function was the perfect place to insert the -T option without effort.

I’m pasting the function below for those that may find it useful. After defining it, I create aliases for commands I usually like to launch in a new screen window if possible, like Vim, Irssi or man, among others.

# Use "screen" if we are inside a screen session.
launch() {
    if [ -n "$PPID" -a "$( cat /proc/$PPID/comm )" = "screen" ]; then
        screen -T "$TERM" "$@"
    else
        "$@"
    fi
}
alias vim="launch vim"
alias irssi="launch irssi"
comments powered by Disqus