Writing vim syntax files never ceases to make me feel like an idiot.
I have a new custom language call jsond, and I wanted to get syntax highlighting working in vim. Using racket
syntax works pretty well (at least with my fork).
Here are some example files:
#lang jsond
#:name albums
["Cycles", "Flatspin", "Long Way to Climb"]
#:name favorites
{
"Jonathan Gordon": 0,
"Brad Rubinstein": 2,
"Paul Willmott": 1,
"Jason Hall": 0,
"Adam Rich": 1
}
#lang jsond
#:name abc "abc"
;; comment
#:name num 123
#:name array [1, 2, {"xyz": "abc"}, true, false, null]
As you can see, the language is effectively #:name <id> <json>
, with a few other things.
Here's my syntax file:
" Vim syntax file
" Language: #lang jsond
" Initializing:
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
syntax match fallbackError /./
syntax include @json syntax/json.vim
if version < 600
set iskeyword=33,35-39,42-58,60-90,94,95,97-122,126,_
else
" syntax iskeyword 33,35-39,42-58,60-90,94,95,97-122,126,_
" converted from decimal to char
" :s/\d\+/\=submatch(0)->str2nr()->nr2char()/g
" but corrected to remove duplicate _, move ^ to end
syntax iskeyword @,!,#-',*-:,<-Z,a-z,~,_,^
" expanded
" syntax iskeyword !,#,$,%,&,',*,+,,,-,.,/,0-9,:,<,=,>,?,@,A-Z,_,a-z,~,^
endif
syntax match jsondSyntax "#lang " nextgroup=jsondLang
syntax keyword jsondLang jsond
syntax keyword jsondName #:name nextgroup=jsondVarName skipwhite skipempty
syntax match jsondVarName ,\<\k+\>, nextgroup=@json skipwhite skipempty
" Comments
syntax match jsondComment /;.*$/ contains=jsondTodo,jsondNote,@Spell
syntax region jsondMultilineComment start=/#|/ end=/|#/ contains=jsondMultilineComment,jsondTodo,jsondNote,@Spell
syntax keyword jsondTodo FIXME TODO XXX contained
syntax match jsondNote /\CNOTE\ze:\?/ contained
" Define the default highlighting.
" For version 5.7 and earlier: only when not done already
" For version 5.8 and later: only when an item doesn't have highlighting yet
if version >= 508 || !exists("did_jsond_syntax_inits")
if version < 508
let did_jsond_syntax_inits = 1
command -nargs=+ HiLink highlight link <args>
else
command -nargs=+ HiLink highlight def link <args>
endif
HiLink jsondSyntax Statement
HiLink jsondName Type
HiLink jsondComment Comment
HiLink jsondMultilineComment Comment
HiLink jsondTodo Todo
HiLink jsondNote SpecialComment
HiLink fallbackError Error
delcommand HiLink
endif
let b:current_syntax = "jsond"
Only the #lang
line, comments, and #:name
elements are highlighted. The identifiers and the JSON values get red error highlights (and no, removing the fallback group didn't help).
I felt sure that using nextgroup=… skipwhite skipempty
would work here, and I'm not sure how to fix it.