In vim, how do I highlight TODO: and FIXME:? - vim

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)

Related

Vim match weird behaviour

I¡ve setup the following match to highlight TODOs in my code:
hi todo guifg=#b294bb
match todo /TODO:?/
But the rule doesn't match the optionsl colon in TODO: (CoffeeScript file):
I've tried some Regex variations, like escaping the colon or wrapping it with parens.
The weird thing is that it works differently in some filetypes, for example:
In my screenshot (CoffeeScript) it doesn't matches the colon.
In LESS, it doesn't match anything.
In vim file, it matches both TODO and the colon.
What am I missing? Is something in my language syntax files overriding this rule?
Notice that I'm using AfterColors plugin to create this colours customisations.
The question mark matches a literal question mark in vim regex (by default). If you set the mode to very magic with \v you will get the behavior you are expecting. (Or use \?)
match todo /\v\CTODO:?/
It is recommended to set the magic mode and case sensitivity explicitly when using regex in scripts since they are affected by user settings.
Read :h magic and :h \C
The "todo" group already exists (and matches /TODO/), try using another name.

How to add words to vim coloring in C/C++ mode?

I notice that in C/C++ mode, comments such as TODO XXX and FIXME get special color marking.
How can I add the word HACK to this list of words to be marked in the same way?
I tried adding the following to my ~/.vimrc, but it didn't work:
syn keyword cTodo contained TODO FIXME XXX HACK
I would advise against directly modifying the original syntax file; you then have to maintain your version whenever the original changes (e.g. after a Vim upgrade). For these small syntax enhancements, the place is in the ~/.vim/after/syntax/c.vim file, which is sourced after the original syntax. The line would be
syn keyword cTodo contained HACK
You need to modify the syntax file. Typically, it is in /usr/share/vim/vim72/syntax, and the file you want is c.vim and cpp.vim. You will see a line syn keyword cTodo contained followed by a list of words that are considered under the Todo label for coloring. You can add your word there, or make your own keyword, but adding your own keyword would mean adding your keyword to the coloring file as well.
For user only changes, make a directory ~/.vim/syntax. Copy the c.vim and cpp.vim files there, and edit as necessary.
Second edit: Decided to look further, and it appears you can just add to a current syntax file, but I haven't tried it. Add your one line you added to your .vimrc to a file in ~/.vim/after/syntax

custom keyword highlighted as todo in vi

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.

highlight sub-match in vim

I'm trying to figure out how to highlight a specific portion of a match in vim.
Given the following example rule (taken from the coffeescript syntax file source):
syn match coffeeExtendedOp /\%(\S\s*\)\#<=[+\-*/%&|\^=!<>?.]\+\|[-=]>\|--\|++\|:/ display
This regular expression matches various coffeescript operators. The operators are highlighted (in my vimrc) like this:
hi Operator guifg=#ff0000
For example, since coffeeExtendedOp is linked to coffeeOperator which is linked to Operator, in the above source file. This all works, but I'm wondering how to specifically highlight the ++ operator matched in the above syn match with a different color, say blue, within my vimrc (that is, without altering the original source file above). I'm simply wondering if this is possible.
EDIT: I think the rules are placed under a cluster, so perhaps that's why it's not affecting anything. Is there a way to access the rule within the cluster?
EDIT: Question was clarified.
Solution:
syn match plusplus /++/ contained containedin=coffeeExtendedOp display
hi plusplus guifg=#0000ff
The problem now is that this only works when I run them as commands in vim, but not when I put it in my vimrc file. Any ideas? Could it be that the stuff is hidden behind the cluster? But then why is it visible in vim through a command? I tried including the syntax file but it didn't seem to have any effect.
Looking at the coffee.vim you linked to it seems like the dot belongs to the coffeeDotAccess syntax item. So you can highlight it just by doing this:
:hi coffeeDotAccess ctermfg=blue
I'm going to guess a bit at what you need. (I don't speak Coffeescript and your sample regex is way too complicated for me to start reading at the moment).
Transparent syntax items
You could have a look at transparent syntax rules: (http://vimdoc.sourceforge.net/htmldoc/usr_44.html)
In a C language file you would like to highlight the () text after a "while"
differently from the () text after a "for". In both of these there can be
nested () items, which should be highlighted in the same way. You must make
sure the () highlighting stops at the matching ). This is one way to do this:
:syntax region cWhile matchgroup=cWhile start=/while\s*(/ end=/)/
\ contains=cCondNest
:syntax region cFor matchgroup=cFor start=/for\s*(/ end=/)/
\ contains=cCondNest
:syntax region cCondNest start=/(/ end=/)/ contained transparent
Partial matches in regex
If you really just meant highlighting submatches, have a look at the the
\zs start match
\ze end match
In short,
:match Error /foo\zsbar\zered/
would highlight only 'bar' in 'foobarred'

Sub-match syntax highlighting in Vim

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".

Resources