I want to create a syntax file in vim for a custom file type I have. Part of the syntax is this line
entry: 1,02:15:00,03:15:00,56,Some String
I would like to match every part separately to assign different colors. entry
should be a part, 1
should be a part, 02:15:00
should be a part, 03:15:00
should be a different part, 56
yet another part, Some String
a different part, and all ,
s as a part. Each of these should be named differently so I can color them with different colors as needed.
I was able to match them with contains
, but similar values (first time and second time) get the same name. I also tried using nextgroup
to chain them one after another, but this left me with ,
having many names I need to color separately (and there are many commas in the original file not like the simple example I shown here).
Is there a way to do such syntax highlighting in a proper way?
You can link all comma names to one with
" Adjust the below to make commas have another color.
" It is common that instead of defining colors directly you link
" new highlighting groups to some standard one.
hi def link MySyntaxComma Delimiter
hi def link MySyntaxCommaAfterNumber MySyntaxComma
hi def link MySyntaxCommaAfterFirstTime MySyntaxComma
hi def link MySyntaxCommaAfterSecondTime MySyntaxComma
hi def link MySyntaxCommaAfterSecondNumber MySyntaxComma
You can also use a loop with :execute
to hide the repeating rules:
syntax match MySyntaxEntryStart /^entry:\s*/ nextgroup=MySyntaxNumber1
let s:rules=[['Number1', '\d\+'], ['Time1', '\d\d:\d\d:\d\d'], ['Time2', '\d\d:\d\d:\d\d'], ['Number2', '\d\+'], ['String', '.*']]
while !empty(s:rules)
let [s:name, s:reg]=remove(s:rules, 0)
let s:cmd='syntax match MySyntax'.s:name.' /'.s:reg.'/ contained'
if !empty(s:rules)
let s:cmd.=' nextgroup=MySyntaxCommaAfter'.s:name
execute 'syntax match MySyntaxCommaAfter'.s:name.' /,/ contained nextgroup=MySyntax'.s:rules[0][0]
execute 'hi def link MySyntaxCommaAfter'.s:name.' MySyntaxComma'
endif
execute s:cmd
endwhile
unlet s:rules s:cmd s:name s:reg