[ad_1]
One fine Monday morning, Lee Hutchinson, chief technology officer of Ars Technica, came to me with a problem: the colors of his text editor, in his humble opinion, had started to suck.
Over the 20+ years of Lee’s use of Vim, he had grown used to commenting out lines in his code and config files being rendered dark blue. But after upgrading a machine to Ubuntu 20.04, Vim started rendering comments cyan – and since the “Identifier” syntax category was rendered cyan as well, he was unhappy enough to decide to change the values. by default.
At first glance, Vim appears to adhere to roughly the same configuration standard as most if not most Unix-like systems and applications – there is a set of system-wide configurations in /etc
, which can be overridden on an individual user basis by changes made in an optional configuration file in that user’s home directory. In the case of Vim, it is ~/.vimrc
: Just as Bash configurations can be overridden in ~/.bashrc
.
But when Lee tried to do his One Simple Change to Vim from Vim’s syntax highlighting – turning comments from the new cyan to dark blue, which he preferred – things got interesting.
The Hutchinson way of configuring comment highlighting
After some research on Google, the command Lee found to change the color of comments seemed fairly straightforward: highlight comment ctermcfg=19
, where 19 is the color code that Vim uses for dark blue. The problem is to make the change ~/.vimrc
didn’t really work.
To be more precise, it did work – briefly – but almost immediately after opening the file, the comments changed from dark blue to cyan. On a fast local machine, the change happened too quickly to be noticed; but Lee was ssh’ing in a remote machine, and that gave just enough delay to see his color preference applied initially but quickly reversed.
After extensive Google searches, Lee discovered an ugly workaround. There’s a very old joke that Vim isn’t a text editor at all – it’s a full-fledged operating system, just masquerading as a text editor. Like most good jokes, this one is a bit of a stretch but has a kernel of truth – Vim configuration files don’t just assign values to configuration variables; they can actually run code on their own.
In Lee’s case, he decided that since there was a delay of about 100ms between applying his dark blue comments and returning Vim, he could just wait for the program and wait 100ms to apply the change first:
function DelayedSetVariables(timer)
highlight comment ctermfg=19
endfunction
let timer=timer_start(16,'DelayedSetVariables')
Sure enough, the villainous hack worked: now, instead of initially seeing dark blue comments that then pointed to hated cyan, Hutchinson saw cyan comments that then flashed to his favorite dark blue.
It worked well enough for its purposes … but what’s the point of being a tech editor if you can’t get an issue to pass in front of a tech reporter who reports to you?
The wrong way … in fact, several wrong ways
When Lee brought me his somewhat resolved issue, it certainly looked like a bug – I may not be a Vim user myself, but with over 20 years of type operating system experience. Unix to my credit, I also expected a user. profile configuration file to cleanly overwrite a system-wide configuration. The disorderly declamations The consistent and focused problem report Lee offered me included a caveat: there were, in his words, “about 20 different places where Vim configuration changes are applied”, so tracking down the problem was unusually tricky.
I’m not a Vim user myself – I’m one of those pagans who never saw any particular reason to know more about Vim than the :q!
needed to get by – but my immediate suspicion was that a bug was causing Vim’s configuration files to be applied out of order. So I went google how to check what configurations had been applied to a running Vim instance: it turns out there is a special command :scriptnames
which will provide you with exactly that.
1: /usr/share/vim/vimrc
2: /usr/share/vim/vim81/debian.vim
3: /usr/share/vim/vim81/syntax/syntax.vim
4: /usr/share/vim/vim81/syntax/synload.vim
5: /usr/share/vim/vim81/syntax/syncolor.vim
6: /usr/share/vim/vim81/filetype.vim
7: ~/.vimrc
8: /usr/share/vim/vim81/plugin/getscriptPlugin.vim
9: /usr/share/vim/vim81/plugin/gzip.vim
10: /usr/share/vim/vim81/plugin/logiPat.vim
11: /usr/share/vim/vim81/plugin/manpager.vim
12: /usr/share/vim/vim81/plugin/matchparen.vim
13: /usr/share/vim/vim81/plugin/netrwPlugin.vim
14: /usr/share/vim/vim81/plugin/rrhelper.vim
15: /usr/share/vim/vim81/plugin/spellfile.vim
16: /usr/share/vim/vim81/plugin/tarPlugin.vim
17: /usr/share/vim/vim81/plugin/tohtml.vim
18: /usr/share/vim/vim81/plugin/vimballPlugin.vim
19: /usr/share/vim/vim81/plugin/zipPlugin.vim
20: /usr/share/vim/vim81/scripts.vim
21: /usr/share/vim/vim81/syntax/perl.vim
22: /usr/share/vim/vim81/syntax/pod.vim
Press ENTER or type command to continue
Lee wasn’t kidding about the huge array of config files to browse: my system was loading 22 separate config files, 15 of which took effect after the .vimrc
in my personal directory! So began a long, winding and ultimately unsuccessful primrose path: I wanted to find examples of the comment’s color changing somewhere. after my ~/.vimrc
, and it turned out that it just wasn’t happening.
The only place I could find where the comments color was set Cyan
was in /usr/share/vim/vim81/syncolor.vim
, some spaces in front of from my staff .vimrc
. In theory, the change of ~/.vimrc
should have replaced that of syncolor.vim
– but in practice, without the awful Lee thing, the only way I could find to change the color of the comments was inside syncolor.vim
himself.
" Many terminals can only use six different colors (plus black and white).
" Therefore the number of colors used is kept low. It doesn't look nice with
" too many colors anyway.
" Careful with "cterm=bold", it changes the color to bright for some terminals.
" There are two sets of defaults: for a dark and a light background.
if &background == "dark"
SynColor Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE
Changing ctermfg=Cyan
inside syncolor.vim
at ctermfg=19
– or better yet, ctermfg=DarkBlue
, which produced an easier-to-read shade of blue – worked as expected, and produced the result Lee wanted without the horrible timer hack. But he applied the change system-wide, not just to Lee’s own user account – and, more importantly, he didn’t explain how or why the initial change in ~/.vimrc
refused to work as planned.
I still felt a bug down, so I dug further.
" Vim syntax support file
" Maintainer: Bram Moolenaar
" Last Change: 2001 Sep 12
" This file sets up the default methods for highlighting.
" It is loaded from "synload.vim" and from Vim for ":syntax reset".
" Also used from init_highlight().
According to the comments at the top of syncolor.vim
, the changes in this file were applied in three cases – when synload.vim
is analyzed during Vim initialization, when the user issues the command :syntax reset
, and in the Vim function init_highlight()
. I knew neither Lee nor I were calling :syntax reset
, so I started to find the invocation of syncolor.vim
inside synload.vim
.
" Set the default highlighting colors. Use a color scheme if specified.
if exists("colors_name")
exe "colors " . colors_name
else
runtime! syntax/syncolor.vim
endif
If I put it simple highlight comment ctermfg=19
back to my ~/.vimrc
, and commented on runtime! syntax/syncolor.vim
in synload.vim
, I thought everything should work fine: this would still be considered a nasty hack, of course, but it would narrow the provenance of the behavior issue and allow me to write a more accurate bug report to the Vim project file.
Unfortunately, it didn’t work that way: even with runtime! syntax/syncolor.vim
commented, Cyan comments that this file specified overrode the simple parameter of my ~/.vimrc
. This meant that the configurations were called by Vim init_highlight()
function after he analyzed ~/.vimrc
.
For one thing, it certainly smelled like a bug again for me: I couldn’t override a simple configuration setting in my rc file at the user level. On the other hand, did I mention over 20 years of open source experience? I had to make sure not to miss anything obvious that would cause a bug report to be rejected with a #WONTFIX
because I had missed a deliberate idiosyncrasy of Vim.
Find the right path
Since Vim’s configuration files contained self-documenting comments, it was time to read them in more detail. I had already learned that the content of syncolor.vim
were applied by init_highlight()
and synload.vim
– but I needed to dig more.
I couldn’t go any further with the documentation comments at the top of synload.vim
or syncolor.vim
, but the next clue came from the code in syncolor.vim
himself:
if syntax_cmd == "enable"
" ":syntax enable" keeps any existing colors
command -nargs=* SynColor hi def
command -nargs=* SynLink hi def link
elseif syntax_cmd == "reset"
" ":syntax reset" resets all colors to the default
command -nargs=* SynColor hi
command -nargs=* SynLink hi! link
else
" User defined syncolor file has already set the colors.
finish
endif
Clearly there was a few good way to define user defined colors, as this if
block specifically avoided configuring them if a “user-defined syncolor file” already had one. So the next step was to create a user-defined sync file on Google. The first search result was the source of syncolor.vim
itself on Github, but the second result brought me to the Vim documentation at SourceForge.
Performing a Ctrl-F syncolor
Searching in the browser on this 5,128 line document finally got me the information I needed, about 90% from the bottom of the page:
If you want to use different colors for syntax highlighting, you can add a Vim
script file to set these colors. Put this file in a directory in
'runtimepath' which comes after $VIMRUNTIME, so that your settings overrule
the default colors. This way these colors will be used after the ":syntax
reset" command.
For Unix you can use the file ~/.vim/after/syntax/syncolor.vim.
Finally, I had found the right answer to the deceptively simple question “How do I change the color of comments in Vim?”: after creation ~/.vim
, ~/.vim/after
, and ~.vim/after/syntax
, you can finally create the file ~/.vim/after/syntax/syncolor.vim
—And changes to syntax highlight colors the applied like Lee and I expected them to.
Stroking the shaggy dog
Hope you learned something along the way from reading this horrible shaggy dog story about setting up a Linux application. Maybe you, too, just wanted to change some colors in a text editor – in which case I took you down an absurdly long path just to come up with a relatively short answer.
But more importantly, I hope the exercise in its entirety can serve as a larger troubleshooting exercise. Good Linux-ing!
[ad_2]
Source link