Photoluminescence Math, Machines, and Music

Solarized and other color schemes for Vim

7 January 2017 Negligible notes Shell Vim

In July 2016 I started to use Vim; by then, I mainly used a MacBook Air, and opened Vim in a terminal, usually within iTerm2 (instead of gVim or MacVim). One of the exciting stuff was the various color schemes available in Vim. After discovering the ‘Solarized’ by Ethan Schoonover, recommended much in Stack Overflow, I agreed that it was particularly pleasing to the eyes.

Surprisingly, the installation was far more cumbersome than I assumed, and sometimes it didn’t work. What prevented Solarized from properly functioning?

To highlight text, Vim parses it with rules according to the present file extension. The text is separated as syntax items which match a certain pattern. Afterwards, syntax items are classified into 16 syntax groups, each highlighted by one color. For example, in a cpp file the syntax item new belongs to the syntax group “Statement”. When an item is ignored, it is mapped to the ‘Normal’ group. Every group is associated with a hex color code, like #ffff00 which should appear yellow on a monitor.

In a GUI, all hex colors can be displayed, and we are done. But in a terminal, what follows is split into two cases.

If termguicolors is set true (with set termguicolors ), terminal colors, specified by variables guifg and guibg, are called. Ideally, they may be assigned all possible hex colors. Nevertheless, iTerm2 and Mac’s native Terminal app can only display 256 hex colors. A degradation function therefore must be applied to map all invalid hex colors to valid ones.

If termguicolors is set false (with set notermguicolors ), palette colors, specified by ctermfg and ctermbg, are called. They are encoded by a nonnegative integer. If t_Co equals 16, the integers range from 0 to 15, and are mapped to a ANSI palette of hex colors. If t_Co equals 256, the integers range from 0 to 255, and are mapped to a Xterm palette of hex color, as remarked above. The 16-color ANSI palette is specified by the present terminal preference, and the 256-color Xterm palette is fixed by the standard.

Solarized attempts to realize a collection of painstakingly-chosen colors to highlight the syntax groups. When ANSI palette colors are used, Solarized colors are given by the corresponding Solarized theme of the terminal, which iTerm2 fortunately provides. Without the corresponding palette, Solarized colors won’t be displayed properly. Meanwhile, when Xterm palette colors are used, none of the Solarized colors is a valid color. If a degradation function isn’t provided, the terminal is forced to guess the colors, and the result is horrible. Thus a lot can go wrong for Solarized in a terminal Vim, and it isn’t easy to reliably specify all these informations in the Vimrc for all devices and Vim variants.

Currently, Solarized isn’t frequently maintained, some successors, in addition to Solarized, are: ‘Flattened’ ‘Gruvbox’ ‘Tomorrow’ ‘Molokai’. Flattened is faithfully based on Solarized, and is still maintained.

In January 2017, I spent quite some time researching all this. On GitHub, I backed up color schemes copied into ~/.vim/colors/. That way, it wasn’t hard to modify the hex colors in the file. For example, I think the ‘Normal’ group is in a dim gray hard to read. To override that value in flattened_dark.vim, I decided to set:

hi Normal guifg=#bac3c4

Time passed, and in September 2019, I began to use VS Code; it worked like a charm. The VS Code market has a variety of extensions, all to be installed with one click. There are Vim emulators, color schemes, spelling checkers, and whatnot. Moreover, the GUI is able to show all hex colors. I use Gruvbox now, and previous research about Solarized looks entirely irrelevant.

If any, the lesson we learn is that simple and robust designs, rather than intricate but fragile ones, often remain to have its life in ever-changing new frameworks.

January 7, 2017; shortened and rewritten July 28, 2021