2

I am currently setting up vim, for the first time. I'm on Arch and i3, fresh install.

I installed termite as my default terminal emulator. I also tried st. Now st had a black background by default but termite had a greyish background. I guess, it's something like #3f3f3f i.e. termite had by default a non-black background. I'm just mentioning st here because it might give some extra information.

To set up vim, I rm -Rf .vim and rm .vimrc .viminfo so we literally start from scratch. (Though there wasn't either .vim or .vimrc anway)

My current .vimrc:

syntax on

set noerrorbells
set tabstop=4 softtabstop=4
set shiftwidth=4
set expandtab
set smartindent
set nu
set nowrap
set smartcase
set noswapfile
set nobackup
set undodir=~/.vim/undodir
set undofile
set incsearch

colorscheme default

set colorcolumn=80
highlight ColorColumn ctermbg=0

This, together with the default background color of termite, i.e. I never set any background color with a config (the .config/termite/config doesn't exist) leads to me not seeing the ColorColumn although the background of vim is not black but grayish - vim uses the background color from the terminal.

Now let's add

[colors]
background = white

to .config/termite/config and suddenly we see our ColorColumn in black. Note that the background color basically didn't change. It was never black to begin with.

In short: If we set the background color of the terminal, everything works as expected. If we don't set the background color of the terminal, we can't see the black ColorColumn although termite defaults to a non-black background color.

What's going on here?

1 Answer 1

2

There are a few concepts you should know about to understand what is going on here. Also, some of these get a bit complicated, so I might end up simplifying it a bit and not going into all the details in this answer.

Terminals (going back to a lineage tracing back to the original xterm) typically support 16 colors, from a palette mapping numbers 0 to 15 to the different colors. Typically color 0 is black and color 15 is bright white.

But usually with modern terminal emulators, you can actually configure this palette to something else (anything else.) Most palettes will keep the general arrangement of colors, just adjust the brightness or perhaps adjust the hue or saturation, but keep them around the same spots...

Other palettes are more radical and shift everything around, in order to have three or four shades of the light color and three or four shades of the dark color (at the cost of having fewer actual colors available in the palette.) For a very well known example of such a color palette, see the "solarized" theme.

So it's quite possible (or even probable) that the palette your Termite is configured to has color 0 mapped not to pitch black (#000000), but to the same dark gray (#3f3f3f) that you have for your background. That would be typically a color palette with less contrast and it wouldn't be unusual to find you're using one.

Now there's also the concept of foreground and background colors (or perhaps "default" foreground and background), which nowadays often are separate from the colors in the palette. So, counting those two, you can end up with a total of 18 distinct basic colors available for the application (though it's also quite common to pick the default foreground and background from the palette too.)

From the point of view of an application running inside the terminal, it can set attributes to pick among the 16 colors in the palette for foreground and background of the next characters to be output to the screen, or you can "clear attributes" which will drop your color selections and go back to your "default" foreground and background colors.

My bet here is that the default background color is this dark gray (#3f3f3f) that you mentioned, and it also coincides with color 0 in the default palette, so that's why you can't distinguish them apart.

When you're updating your Termite config to set bacckground = white, you're changing this default background color. However, you'll notice that the background color is totally detached from the palette... So color 0 from the palette will continue the same, which is most probably the dark gray (#3f3f3f), so now you can see it.

(You mentioned that it's black, I guess implying that it's pure black, but I think that may not be the case. The juxtaposition of the dark gray next to a bright white may make it look darker than it actually is, making you think it's pure black, darker than the default background color you replaced.)

Note that the palette is not necessarily reversed when you switch to a light background, which means color 0 in the palette is no longer same or very close to the background, but now it's the one with most contrast to it. (Color 7 is perhaps now the one closer to the background color, that's usually a very light gray. Or color 15 which is usually a brighter white.)

One other factor you might find interesting is that Vim allows you to compensate for a distinction between the palette and the "default" background. This is implemented in form of the 'background' option, which you can query with :set background? and you can change with :set background=light or :set background=dark.

In your specific case, with ctermbg=0, nothing will change by setting that option. But Vim colorschemes may react to it, by deciding to use different colors depending on what 'background' is set to. Many well made themes will essentially include two full sets of color choices, one for dark and one for light. It's quite possible that your Vim theme is doing that, and actually using color 0 (and not the default background color) when 'background' is set to dark, in which case even if your default background color is distinct from color 0 from the palette, the Vim colorscheme might be using 0 for background, making it the same as your color column.

And you should also know that Vim tries to "guess" which setting of 'background' to use, based on the "default" background color your terminal is using. Most modern terminals allow programs to query them for the color settings (including querying the palette colors and even setting the palette colors.) Vim tries to query the terminal for the background color at startup. It then calculates the brightness of the color and sets 'background' appropriately, depending on whether the brightness number indicates that it's a light or a dark color.

That's why even if your Vim colorscheme will hardcode color 0 for normal background when 'background' is set to "dark", it is also able to use a different color when your Termite background is now set to white. Vim will detect it and set 'background' to "light" and the colorscheme will know not to use color 0 for the background anymore, but either keep the default, or pick a light color from the palette.

This discussion bypasses most of the higher color support in terminals. Nowadays you get terminals with 256-color support (the base 16 from the palette are typically configurable, the remainder are typically standard, though some terminals might allow you to set them from the application too) and "True Color" support, which means terminal applications are able to use 24-bit colors to get the full gamut from #000000 to #ffffff. The most common situation (lowest common denominator) is 16-color support, with the customizable palette, with default foreground and background, so I limited the discussion to that setting, which I believe should fully explain what you're experiencing.

2
  • 1
    Thanks a lot for this nice and interesting explanation. It's way better than what I expected to get! :) It explains a lot and seems to be a rather deep topic in itself. Never thought I'd end up here when I started setting up my first .vimrc. :)
    – xotix
    Sep 11, 2020 at 8:39
  • Welcome to Vi and Vim! Feel free to ask more questions as you're configuring and learning to use Vim!
    – filbranden
    Sep 11, 2020 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.