55

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?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Paul Biggar
  • 27,579
  • 21
  • 99
  • 152
  • 1
    That's odd; mine highlight with or without the colon. That syntax highlighting is defined in individual syntaxes, I think - is this happening in some specific filetype? – Cascabel Nov 04 '10 at 13:50
  • @Jefromi: I think it happens in every filetype. – Paul Biggar Nov 04 '10 at 13:51
  • 3
    what does `:verbose set iskeyword?` tell? – Benoit Nov 04 '10 at 13:52
  • 1
    @Benoit: Brilliant. I was able to track it down to some latex settings which said: `set iskeyword+=:`. I'm not sure what that means though (and the built-in help isn't much use). So now TODO: highlights the TODO part, but not the colon. I'm not sure which I want, but I wouldn't mind testing the latter. Is it possible to highlight the colon too? – Paul Biggar Nov 04 '10 at 14:02
  • 1
    Yes. You have to do some `:syntax match cTodo /\ – Benoit Nov 04 '10 at 14:07

3 Answers3

62

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
Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • +1 @Jefromi, however, I don't think this syn match works. I slapped it in my .vimrc and if I change FIXME to something else it's not highlighted. –  Nov 17 '11 at 01:00
  • 2
    @G33kx0r: It's not the fault of this match; it works if it still exists. I suspect you're enabling syntax (one way or another) *after* the lines in your vimrc run, and when syntax is enabled, it first clears old syntax then loads the appropriate one. You can check to see if that match is still in place using `:syn list myTodo`. See also `:help syntax-loading`. – Cascabel Nov 17 '11 at 01:33
  • Setting first `syntax on` and afterwards `syn match myTodo contained "\<\(TODO\|FIXME\):"`in my `vimrc` file and `hi! def link myTodo Todo` doesn't work for me. On the other hand if I do, for instance, `au BufNewFile,BufRead *.tex syn match texTodo "\<\(TODO\|FIXME\):"` the resulting `tex` file is properly highlighted. Is there a general solution? – petobens Jun 11 '13 at 18:24
  • Not work anymore: `syn keyword cTodo contained TODO FIXME XXX; highlight cTODO ctermbg=red ctermfg=yellow term=bold,italic` – Run Dec 08 '21 at 07:45
17
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.

blueyed
  • 27,102
  • 4
  • 75
  • 71
  • 2
    Usage notes: you can add this to your .vimrc, and remove the colon (':') if you just want the word highlighted, and not the colon following it. I prefer the highlighting to read _NOTE_:, not _NOTE:_ . I also sometimes write NOTE or TODO not followed by a colon. – Ari Sep 15 '16 at 22:08
  • I added an additional line: `hi def link MyTodo pythonTodo`. Works. – Nikos Alexandris Jul 28 '18 at 09:16
  • 1
    If you're creating a new autocommand group "vimrc_todo" is the `au!` (clear other autocommands) necessary? Genuinely asking because I'm not sure, not being snarky. – Michael Thompson Feb 07 '19 at 19:12
  • This is my approach. It does more but you get less control over what it highlights: https://pastebin.com/raw/5JnXcsfx – FocusedWolf Jul 19 '20 at 01:46
2

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)

Adi Inbar
  • 12,097
  • 13
  • 56
  • 69