I'm not sure why the answer you linked to is accepted and so highly voted, because neither of the included solutions will actually work, and while a working solution is alluded to in the explanation, that solution still involves messing with the 'iskeyword'
setting and everything that entails, which is neither necessary nor a good idea, just to fix this single issue with syntax highlighting.
There are three problems with the solution you've tried, which can be figured out by digesting the contents of the documentation at :help :syn-contains
and :help :syn-priority
.
Problem 1: contained
The first problem is that you need your myTodo
item to be found inside other syntax items, viz. comments. You might imagine that the contained
argument in the suggested :syntax
command achieves this, but that's not what that means: instead, the contained
keyword declares that your syntax item cannot be found at the top level outside of other syntax items: it doesn't specify where it can be found.
In order to allow your myTodo
item to be found inside another syntax item, it must either be specifically listed in a contains
argument in that item's definition, or instead the myTodo
item must list the other item as a containedin
argument. The first of these is not practical—the "comment" syntax item is defined elsewhere— so we must instead use containedin
:
:syntax match myTodo /\v<(TODO|FIXME).*/ containedin=.*Comment
N.B. I'm using a "very-magic" search to make the regular expression a bit easier to write/read. See :help \v
for details.
This will allow your myTodo
item to be contained within any syntax item that ends in Comment
. This isn't truly "global", but it probably more closely matches what you want. If you really want this to match anywhere, then you could instead use the special ALL
keyword described in :help :syn-contains
.
:syntax match myTodo /\v<(TODO|FIXME).*/ containedin=ALL
Problem 2: keyword
vs match
You will note that the above still doesn't actually work. This is because the existing TODO highlighting takes precedence. This is generally implemented as a keyword
, and you will see in the list of priorities linked above that keyword
s take priority over match
es that begin at the same position.
The way to work around this is to make your match start before the existing keyword, and then adjust the start of the highlighting accordingly:
:syntax match myTodo /\v.<(TODO|FIXME).*/hs=s+1 containedin=.*Comment
(See :help :syn-pattern-offset
.)
Note that this will not work at the start of the line. If you need it to, then you could instead use:
:syntax match myTodo /\v\_.<(TODO|FIXME).*/hs=s+1 containedin=.*Comment
(See :help 27.8
.)
This still won't work if your TODO item begins at the very start of the file. If you need this, you're going to need to either: delete the existing
"todo" keyword syntax items with :syntax clear
commands, or use something a bit more complicated:
:syntax keyword myTodo TODO FIXME nextgroup=myRestOfTodo
:syntax match myRestOfTodo /.*/ containedin=NONE contained
:highlight link myTodo Todo
:highlight link myRestOfTodo Todo
This sets up a keyword
item for todo items, and a match item that matches everything but can only be found immediately following a myTodo
item.
(See :help :syn-nextgroup
.)
Problem 3: Where to put the commands
So now we have some commands that will work when run manually in a file.
As a rule of thumb, Vim doesn't really care in what files you place your config. It's not true that syntax commands will only have an effect if they are in a "syntax highlighting file", as you wonder in your question.
However, the reason for all the different locations within .vim
that you can place config is that the different files are loaded automatically by Vim at various different times, and in order for our code to work, we ideally want it to be run after the existing syntax has been set up.
As such, the simplest solution that will work globally is probably to use an autocommand in your .vimrc:
augroup myTodo
autocmd!
autocmd Syntax * syntax match myTodo /\v\_.<(TODO|FIXME).*/hs=s+1 containedin=.*Comment
augroup END
highlight link myTodo Todo
If you were happy with setting up the matches specifically for each filetype, I'd recommend nixing the autocommand and instead placing the :syntax
commands within the relevant files in .vim/after/syntax
, e.g. .vim/after/syntax/plaintex.vim
I'll leave it as an exercise to the reader to figure out how to alter the above to use instead the other solution that utilises nextgroup
. ;)