Daniel Bradbury
Software engineer based in Sacramento, CA
matchadd vs match
The target of this post is to clear up any confusion about the subtle differences between matchadd
and match
/2match
/3match
. This is not meant for the novice vim user but folks that have some experience with vimL. I'll try to keep it as simple as possible for anyone interested in some of vim's inner workings.
From :help match
we get the following information:
:mat[ch] {group} /{pattern}/
Define a pattern to highlight in the current window. It will
be highlighted with {group}. Example:
:highlight MyGroup ctermbg=green guibg=green
:match MyGroup /TODO/
Instead of // any character can be used to mark the start and
end of the {pattern}. Watch out for using special characters,
such as '"' and '|'.
{group} must exist at the moment this command is executed.
The {group} highlighting still applies when a character is
to be highlighted for 'hlsearch', as the highlighting for
matches is given higher priority than that of 'hlsearch'.
Syntax highlighting (see 'syntax') is also overruled by
matches.
From the definition it should be pretty clear that match is responsible for applying defined highlights to the current window. The {group}
argument is simply the name of the highlight group definition you would like to use on a given {pattern}
.
To visualize a list of all available highlight groups you can use :highlight
. This is really handy when programatically trying to add hightlight groups for a plugin. As you can see from the screenshot below our colorscheme has redefined the majority of the groups and :hi
does a great job showing all of the possibile combinations.
Using that information we could use any one of the groups and apply a match in our current buffer. Let's take a look at using the ErrorMsg
highlight group to match the entire contents of a line.
:match ErrorMsg /\%13l/
If you have not used match
before take a moment now to play around with it in your own vim session and get a feel for how vim reacts to all different types of scenarios. Which match takes priority when running consecutive matches on the same pattern?
One of the main limitations with using match
is that you cannot continuously apply new matches and have the previous ones stick. Because of this it is not the most suitable option for creating any sort of full fledged highlighting plugin. If you read the help section below match you will encounter :2match
and :3match
which is meant to provide a way to manage 3 seperate highlight groups. Unfortunately these functions suffer from the same shortcoming we saw with the original match.
In order to compensate for the limitation on match you can create more complex patterns to include multiple line selections (/patern1\&pattern2/
) or whatever else you would normally do inside of the typical vim search regex (remember a touch of magic is only a \M
away with this type of searching). If you'd like to see evidence of the hacks that are possible while using check out the first iteration of vim-poi (fresh-start
branch is ready for testing and this logic will all be replaced with the smarter and better matchadd
pattern)
for i in b:poi_lines{a:group}
let c += 1
if c == 1
let s:build_string = s:build_string.'/\%'.string(i["line_num"]).'l\&\M'.i["content"]
else
let s:build_string = s:build_string.'\%'.string(i["line_num"]).'l\&\M'.i["content"]
endif
if c == len(b:poi_lines{a:group})
let s:build_string = s:build_string.'/'
else
let s:build_string = s:build_string.'\|'
endif
endfor