The reason why this happens is that the pattern
'.*' matches an empty string (with zero width), so it ends up matching the ends of the lines and highlighting those as well.
The match engine (similar to the syntax engine) will highlight a match and start searching for the next match right where the last match ended. So, in your example, it will match
One successfully, then it will try to match the end of the line after
One, and since the
'.*' pattern matches an empty string, it will match the end of the line and highlight it too. Then it will move on to the next line, with
Two, and do the same there. Note that you're actually getting two separate matches in each line.
You have a few ways to solve this issue. As @AndrewHoLee mentioned in a comment, you can add an anchor of
^ to the pattern, so that it matches only at the beginning of the line. Such as:
:call matchadd('ErrorMsg', '^.*$')
Or, slightly simpler:
:call matchadd('ErrorMsg', '^.*')
Both of these work the same, and they prevent the second match because the
^ anchor will prevent a match from starting there. This approach has one small disadvantage though, in that empty lines will match it and get highlighted. (An empty match such as the end of the line is still possible, as long as it's also at the beginning of the line.)
Another solution is to ensure a zero-width match will not happen, which can be done by using a
\+ multi item to match one or more character, rather than
* for zero or more.
:call matchadd('ErrorMsg', '.\+')
(The solution in the answer by @DCSlagel effectively does this, since the
[^\$] group needs to match a character other than backslash or dollar-sign, so it ensures at least one character gets matched here. Of course, there's a drawback in that a line starting with one of those characters will skip it when highlighting the match.)
:call matchadd('ErrorMsg', '^.*$'). I haven't posted it as an answer as I have yet to work out the why of it.
$isn't even needed) and offers a slightly better version of it, using
'.\+'as a pattern.