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.
Related
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
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.
I'm wanting to create custom syntax highlighting in vim for a task-list.
Task items begin with a hyphen. Two types of task items are relevant: (a) items without an '#done' tag. (b) items with an #done tag. (a) and (b) need to be highlighted differently.
I'm using taskpaper, which works fine, but the issue is, I'm trying to make this to work for task items that span multiple lines. For example:
- Regular item (works)
- Completed item #done (works)
- Multi-line item. This item continues on to
the line below. (doesn't work)
- Multi-line completed item. This item continues
on to the line below. (doesn't work). #done
The highlighting file at taskpaper works for the first two, but not for the second two. As a workaround hack, I tried this for the last case above:
syn region multLineDoneItem start="{" end="}" fold
HiLink multLineDoneItem NonText
But now, I'm forced to mark multi-line done items with braces like so:
- {Multi-line completed item. This item continues
on to the line below. (workaround works).}
I've already searched stackexchange and elsewhere. I would appreciate any help! :)
You could try using the \ze regex atom in the end part of your syntax region. This would allow you to match everything up to but not including the next task. I haven't looked at how you do matching but something like this might work.
syn region muiltLineItem start="^-" end="\(\s*\n)\+\ze^-" fold
syn region multiLineDoneItem start="^-" end="#done\s*\n\(\s*\n\)*\ze^-" fold
HiLink multiLineItem Normal
HiLink multiLineDoneItem NonText
I haven't tested this at all but I think it, or something like it, should work. If you wish to take indentation into account the \z regex atom will allow you to keep matching lines with the same indent.
UPDATE:
Try this:
syn match multilineItem "^-\_.\{-}\ze\(\n-\|\%$\)" fold
syn match multilineDoneItem "^-\(\%(\_^-\)\#!\_.\)\{-}#done\s*\n\ze" fold
command -nargs=+ HiLink highlight default link <args>
HiLink multilineItem Normal
HiLink multilineDoneItem NonText
delcommand HiLink
Oh, also this should work for all four cases and not just the multi-line items.
In vim, FIXME and TODO are highlighted, but I can't get FIXME: and TODO: (note the colon after the keyword) to highlight? What should I put in my .vimrc to make this happen?
Well, you've already found the problem, but here's the why.
There are three basic types of syntax matching: keywords, matches, and regions. Keywords are fixed strings, generally used for basic language keywords (int, double, ...) and also, in your case, for the FIXME and TODO. I really do mean fixed strings; they have to be exact and whole words, unlike matches and regions, which use regex. For example, from the C syntax:
syn keyword cTodo contained TODO FIXME XXX
It looks like that in pretty much all built-in syntax definitions, just with different group names (cTodo).
iskeyword tells vim whether a given character can be part of keyword. By default, it does not include colons, so when looking for keywords, vim sees "FIXME:" as "FIXME", and ignores the colon. If you tack on the colon (set iskeyword+=:), you can now define an extra bit of highlighting:
syn keyword myTodo contained TODO: FIXME:
It's up to you how you want to work it into the existing syntax/highlight groups. If it's for just one filetype, you could add it to that syntax's todo group (e.g. cTodo). If you want it everywhere, you can do "myTodo" as I suggested, then link it straight to the Todo highlighting group (hi def link myTodo Todo).
Alternatively, you can leave iskeyword alone (I'd probably recommend this), and simply use a match:
syn match myTodo contained "\<\(TODO\|FIXME\):"
hi def link myTodo Todo
augroup vimrc_todo
au!
au Syntax * syn match MyTodo /\v<(FIXME|NOTE|TODO|OPTIMIZE|XXX):/
\ containedin=.*Comment,vimCommentTitle
augroup END
hi def link MyTodo Todo
The containedin will add it to all groups ending in "Comment", plus
vimCommentTitle, where " TODO: foo would not get highlighted as MyTodo otherwise.
If you make your own environment, make syntax file (not .vimrc)
global syntax file is located vim directory (ex.
/usr/share/vim/vim72/syntax/c.vim)
and if you make ~/.vim/syntax/c.vim, then you can add syntax for your
own. (override)
Just add additional syntax in that file. (the way #Jefromi does)
First, I'll show the specific problem I'm having, but I think the problem can be generalized.
I'm working with a language that has explicit parenthesis syntax (like Lisp), but has keywords that are only reserved against the left paren. Example:
(key key)
the former is a reserved word, but the latter is a reference to the variable named "key"
Unfortunately, I find highlighting the left paren annoying, so I end up using
syn keyword classification key
instead of
syn keyword classification (key
but the former triggers on the variable uses as well.
I'd take a hack to get around my problem, but I'd be more interested in a general method to highlight just a subset of a given match.
Using syn keyword alone for this situation doesn't work right because you want your highlighting to be more aware of the surrounding syntax. A combination of syn region, syn match, and syn keyword works well.
hi link lispFuncs Function
hi link lispFunc Identifier
hi link sExpr Statement
syn keyword lispFuncs key foo bar contained containedin=lispFunc
syn match lispFunc "(\#<=\w\+" contained containedin=sExpr contains=lispFuncs
syn region sExpr matchgroup=Special start="(" end=")" contains=sExpr,lispFuncs
The above will only highlight key, foo, and bar using the Function highlight group, only if they're also matched by lispFunc.
If there are any words other than key, foo, and bar which come after a (, they will be highlighted using the Identifier highlight group. This allows you to distinguish between standard function names and user-created ones.
The ( and ) will be highlighted using the Special highlight group, and anything inside the () past the first word will be highlighted using the Statement highlight group.
There does appear to be some capability for layered highlighting, as seen here: Highlighting matches in Vim over an inverted pattern
which gives ex commands
:match myBaseHighlight /foo/
:2match myGroup /./
I haven't been able to get anything like that to work in my syntax files, though. I tried something like:
syn match Keyword "(key"
syn match Normal "("
The highlighting goes to Normal or Keyword over the whole bit depending on what gets picked up first (altered by arrangement in the file)
Vim soundly rejected using "2match" as a keyword after "syn".