Recently I found myself wanting to do something a bit weird in a Vim syntax file: run an external command, extract some text from it, and define syntax keywords based on that extracted text.

I'd never written anything more than basic config-file Vim script before, so it turned out that I was in for an adventure in frustrating esotericities of the language. Can I have a vim-like editor with a real extension language yet?

One of these frustrations is that in many constructs of the language, arguments are not automatically evaluated before being interpreted by the surrounding syntax. I assume that this has something to do with functions and other miscellaneous statements (like 'syntax') not being treated the same way.

For example, if I want to highlight a particular word in a syntax file, I use the following:

syntax keyword word1 word2 word3

The words following 'keyword' are taken literally. So if I have a variable named 'word1', it will match on the literal 'word1' instead of the contents of the variable. And I can't dump a list variable at the end of 'syntax keyword' and have it do what I mean either.

The solution is to construct a string containing the statement you want, and then manually evaluate that:

let s:syntax = 'syn keyword ' . s:group . ' ' . join(s:list)
exec s:syntax

Where 's:group' is a script-local variable that contains what syntax group I want these keywords to belong to, and 's:list' is a list of the keywords. Why 'syntax keyword' doesn't just take strings normally and evaluate variables if they're given, I do not know. Figuring out the right way to present arguments is very confusing.

Thanks to James Vega on #vim for pointing out the way to work around this to me. I never would have figured it out myself.