Search code examples
vimcolor-scheme

Vim: Change syntax coloring rules when changing colorscheme


In Vim, is it possible to change the syntax coloring rules for a given language, together when the colorscheme is changed?

Here is an example:

I installed some plugins for coloring matlab code in Vim. It provides several .vim files:

.vim/colors/matlabdark.vim
.vim/colors/matlablight.vim
.vim/ftplugin/matlab.vim
.vim/indent/matlab.vim
.vim/syntax/matlabcolours.vim
.vim/syntax/matlab.vim

It works very nice with provided colorschemes. However, I sometimes want to use different colorschemes, and when I apply another colorscheme (e.g. solarized), commas and semicolons have too intense background color. I checked into .vim/syntax/matlab.vim, and I see that commas and semicolons are assigned to the group SpecialKey.

I tried to edit that part of .vim/syntax/matlab.vim into:

syn match matlabComma        ","    display
syn match MatlabSemicolon    ";"    display
(...)
command -nargs=+ HiLink hi def link <args>     " creates HiLink command
(...)
if g:colors_name == 'solarized'                " added by me
  HiLink matlabComma         Normal            " added by me
  HiLink matlabSemicolonn    Normal            " added by me
else                                           " added by me
  HiLink matlabComma         SpecialKey
  HiLink matlabSemicolonn    SpecialKey
endif                                          " added by me
(...)

but nothing happens when I change the colorscheme to solarized. Then I tried to put this script into .vim/after/syntax/ but also without luck.

I suppose that I need to somehow change the code of solarized, or any other colorscheme to achieve what I wanted, but I simply can't see how. I don't know enough about vim scripting to understand what files/scripts are executed when colorscheme is being changed. Probably only the .vim/colors/<wanted_scheme>.vim script.

If needed, the matlab can be found here.


Solution

  • The problem is that the :HiLink command expands to :hi def link; the def means that the command just defines defaults in case there's no existing one. If the syntax plugin was already sourced once, that's not the case anymore, and your change becomes ineffective.

    Now, if you don't mind manipulating the script, drop the def, and it should work.

    Another way would be to redefine the link via an :autocmd that is triggered by the change in colorscheme:

    :autocmd ColorScheme * if g:colors_name == 'solarized' | hi link matlabComma Normal | else | hi link matlabComma SpecialKey | endif
    

    Finally, do you really need to switch colorschemes on the fly? Some plugins won't handle that gracefully, neither.