I have the following three lines to style comments in my syntax file. Comments start with # and are allowed to be inline or on a seperate line.
syn keyword myTodo contained TODO FIXME
syn match myComment "^#.*" contains=myTodo
syn match myComment "\s#.*"ms=s+1 contains=myTodo
It does work as long as there is no character (includes braces, etc) right before the #.
I tryed to create a rule like this:
syn match myComment ".*#.*"ms=s+1 contains=myTodo
but this would style the whole line as comment.
What do I have to do to make it style correctly, even if there is a character right before the #?
EDIT
syn match myComment "\s*#.*"ms=s+1 contains=myTodo
Hightlights the text after # correctly and the text before # is not styled as a comment but the # isn't styled as comment.
If I understood well, there is no need to describe the match before the sharp sign.
What happens if you simply try this:
syn keyword myTodo contained TODO FIXME
syn match myComment "#.*$" contains=myTodo
It's a simple case, which doesn't handle the case where a sharp sign is included into a string for example (if there is some strings in your syntax). To handle this additionnally, you can add:
syn match Constant /\v"([^\\]|\\.)*"/
syn match Normal /^.*$/ contains=Constant,myComment
Related
I have following syntax file:
syn match TaskName /^\[.*\]/
syn match TaskType /^\[.*\]\s*\zs[a-z]*/
syn match TaskDescription /^\[.*\]\s*[a-z]*\s\+\zs.*/
hi def link TaskName Title
hi def link TaskType Todo
hi def link TaskDescription Comment
and the context is:
Task Type Command
[file-run] local no description
why only [file-run] is matched?
If I type /^\[.*\]\s*\zs[a-z]* in normal mode, local will be matched.
The reason it is not matching is that :syn match does not try and
evaluate text it has already matched. So, it cannot match against the text already matched by :syn match TaskName.
Additionally, there's a lot that could be improved upon your patterns, notably:
You have a lot of pattern atoms that will match the empty string.
This makes pattern matching slow, as patterns like [a-z]* will match
everywhere (this pattern in particular is even pointed out as an example of
a pattern to avoid in the help documentation for :syn-pattern). In most
cases it is better to match 1 or more matches with \+ than 0 or
more matches with *.
You can make all of your patterns more brief and more clear using other
arguments of :syn match.
I would suggest leveraging the power of the nextgroup argument in combination
with the skipwhite argument of :syn match:
nextgroup allows you to tell
Vim to try and match the groups specified after this match.
The skipwhite argument allows you to skip over tabs and spaces when
trying to match the next group with nextgroup.
Keeping these in mind, you could rewrite your patterns to look like:
syn match TaskName /^\[.\+\]/ nextgroup=TaskType skipwhite
syn match TaskType /[a-z]\+/ nextgroup=TaskDescription skipwhite
syn match TaskDescription /\w\+\(\s\+\w\+\)*/
In order to do this, I've also edited your TaskDescription match to be “a word,
followed by 0 or more words separated by whitespace".
You can see that utilizing nextgroup and skipwhite makes each syntax match
more brief, in addition to making the contents of each group more clear.
Relevant :help queries:
:h :syn-match
:h :syn-pattern
:h :syn-nextgroup
:h :syn-skipwhite
This is a followup to Vim syntax: Spell checking between certain regions I'm trying to create a syntax file for this language called Sugar Cube 2. You can find more about it here: http://www.motoslave.net/sugarcube/2/docs/macros.html
The link has this syntax: <<link "linkText" "passageName">> e.g.:
<<link "Onward, Reginald!" "ThePassageName">>
I would like to spell check that "Onward, Reginald!" but not "ThePassageName". How do I do that? I tried messing around with lines like this, but I think I'm going in the wrong direction:
syn region noSpellString start=+"+ end=+"+ skip=+\\"+ contains=#NoSpell
syn region spellString start=+"+ end=+"+ skip=+\\"+ nextgroup=noSpellString
syn match linkMacro "<<link\s+" nextgroup=spellString skipwhite skipempty
Your approach looks good to me. :syn region is the right choice if the strings can span multiple lines. For single-line strings, :syn match (with a suitable pattern that skips contained escaped quotes) would be better.
Your example almost works:
The linkMacro pattern needs to use \s\+ to match.
the spellString is missing the skipwhite
syn region noSpellString start=+"+ end=+"+ skip=+\\"+ contains=#NoSpell
syn region spellString start=+"+ end=+"+ skip=+\\"+ nextgroup=noSpellString skipwhite
syn match linkMacro "<<link\s\+" nextgroup=spellString skipwhite skipempty
For syntax scripts, all syntax groups should start with a prefix that is equal to the syntax name. So, syntax/sugarcube2.vim should have syntax names like sugarcube2LinkMacro, sugarcube2SpellString, etc.
I am using a language embedded inside of Scala that has a :: operator. I would like to modify my scala.vim syntax file to recognize this new operator.
This is what I've tried (the first line works fine, but I don't know how to add the :: operator to it):
syn match COperator "[&|~><!)(*#%#+/=?:;}{,.\^\-\[\]]"
syn match COperator "\v::"
syn match COperator "\v\:\:"
hi link COperator Special
Any advice?
An existing scalaOperator ":\{2,\}" was causing all sequences of : to match (if there are two or more series of :), overriding my own syn match COperator statements.
The solution to get :: to match as a COperator was to simply rename the scalaOperator that matches series of : to a COperator:
syn match COperator ":\{2,\}"
Summary: check for existing match rules that override your own match rules.
I am trying to write a syntax highlighter in VIM. How do you highlight a match within another match?
To find each match, I created two syn match lines, which work where the matches are separate.
syn match celString "^xpath=.\{-};" -> matches "xpath=.........;"
syn match celComment "\${.\{-}}" -> matches "${LIB_METADATA};"
The first line is pink for the xpath string and blue for the ${..} string.
The second line is pink for the xpath string, but the ${..} contained inside that string is ignored.
I've tried to change the order of the syn match lines, but that doesn't have any effect.
I'd appreciate your ideas.
By default, Vim only applies the syntax groups to text that hasn't yet been assigned a syntax. To specify that one group can contain other groups, use the contains=... attribute:
:syn match celString "^xpath=.\{-};" contains=celComment
The order of definition shouldn't matter here. See :help :syn-contains for more information.
Starting with vim and love that it highlights todo comments. Around here, however we use a custom keyword (first initial last initial todo: abTODO) so it's easy to grep for todos that apply to a specific person.
I'd love to add mine as a keyword that vi picks up and highlights along with todo, fixme and xxx.
In vim, how do I highlight TODO: and FIXME:? seems to apply, but using the following does not work:
syn match myTodo contained "abTODO"
hi def link myTodo Todo
UPDATE
In my .vimrc I have the following 3 lines (as suggested):
syntax enable
syn match myTodo "\<\l\{2\}TODO\>"
hi def link myTodo Todo
That is a lowercase L, not 1. However abTODO is still not being highlighted at all.
Try this match:
syn match myTodo "\<\l\{2\}TODO\>"
Explanation:
\< matches the beginning of a word
\l\{2\} matches precisely two lowercase letters
TODO\> matches the string TODO at the end of the word
Your highlight command is fine at it is. I don't think the contained option is necessary here.