Similarly to plug-ins, color schemes are commonly distributed as clone-able Git repositories, which make it less desirable to directly edit their source files (as sometimes suggested) when wanting to customize their behavior.

In the case of plug-ins, Vim offers the after-directory mechanism, which allows personal preferences to overrule or add to the distributed defaults or system-wide settings. For example, ~/.vim/after/ftplugin/fortran.vim, if it exists, will automatically be read following the distributed fortran.vim while files in after/plugin/ may be used in a similar way to customize individual plug-ins.

Unfortunately, this behaviour isn't supported for colors/ as documented:

:colo[rscheme] {name} searches 'runtimepath' for the file "colors/{name}.vim".

The first one that is found is loaded.

Given that color schemes may be dynamically re-loaded (e.g. after setting 'background'), simply patching it in .vimrc once it has been loaded is not enough. Furthermore, this does not scale well when managing many color schemes.

The documentation for :colorscheme suggests:

To customize a colorscheme use another name, e.g. ~/.vim/colors/mine.vim, and use :runtime to load the original colorscheme:

runtime colors/evening.vim
hi Statement ctermfg=Blue guifg=Blue

However, this is inconsistent with and seems less transparent than what is described above (e.g. requiring another name). So, How can I can obtain the automatic behavior of after-directory for color schemes?


On Stackoverflow:


The AfterColors plug-in (GitHub mirror) provides an after-directory auto-loading mechanism for color schemes. This can however be easily achieved in modern Vim by using the ColorScheme autocommand event (triggered after loading a color scheme and added in v7.0164) and <amatch> (which holds the new color scheme name and was added in v7.4.109).

Therefore, the following command:

autocmd ColorScheme {pat} runtime "after/colors/" . expand("<amatch>") . ".vim"

will read after/colors/{scheme}.vim whenever the color scheme named {scheme} (based on g:colors_name) is loaded, as long as {sheme} corresponds to the globbing pattern {pat}. The pattern * can be used to match any scheme:

autocmd ColorScheme * runtime "after/colors/" . expand("<amatch>") . ".vim"

which also supports color schemes missing after/colors/ custom scripts as non-existing arguments aren't considered as errors by runtime. This one-liner allows you to structure your color scheme customization under your after-directory (typically ~/.vim/after/colors/) by using a file per scheme.

As auto-commands obviously have to be declared before being called, make sure to place the autocmd calls before calling :colorscheme, in your .vimrc. Finally, multiple autocommands may listen to the same event and will be triggered sequentially in the order in which they were defined so that:

autocmd ColorScheme * runtime "after/colors/" . expand("<amatch>") . ".vim"
autocmd ColorScheme * runtime "after/colors/common.vim"
colorscheme {scheme}

will read both after/colors/{scheme}.vim (if it exists) and after/colors/common.vim.

Similarly, sharing customization between schemes {A} and {B} may be done through

autocmd ColorScheme {A} runtime "after/colors/{B}.vim"

or by appending the following to after/colors/{A}.vim:

runtime "after/colors/{B}.vim"

but the former is more powerful given that a globbing pattern {pat} may be used.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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