1" Vim syntax file 2" Language: OCaml 3" Filenames: *.ml *.mli *.mll *.mly 4" Maintainers: Markus Mottl <[email protected]> 5" Karl-Heinz Sylla <[email protected]> 6" Issac Trotts <[email protected]> 7" URL: http://www.ocaml.info/vim/syntax/ocaml.vim 8" Last Change: 9" 2018 Nov 08 - Improved highlighting of operators (Maëlan) 10" 2018 Apr 22 - Improved support for PPX (Andrey Popp) 11" 2018 Mar 16 - Remove raise, lnot and not from keywords (Étienne Millon, "copy") 12" 2017 Apr 11 - Improved matching of negative numbers (MM) 13" 2016 Mar 11 - Improved support for quoted strings (Glen Mével) 14" 2015 Aug 13 - Allow apostrophes in identifiers (Jonathan Chan, Einar Lielmanis) 15" 2015 Jun 17 - Added new "nonrec" keyword (MM) 16 17" A minor patch was applied to the official version so that object/end 18" can be distinguished from begin/end, which is used for indentation, 19" and folding. (David Baelde) 20 21" quit when a syntax file was already loaded 22if exists("b:current_syntax") && b:current_syntax == "ocaml" 23 finish 24endif 25 26" ' can be used in OCaml identifiers 27setlocal iskeyword+=' 28 29" OCaml is case sensitive. 30syn case match 31 32" Access to the method of an object 33syn match ocamlMethod "#" 34 35" Script headers highlighted like comments 36syn match ocamlComment "^#!.*" contains=@Spell 37 38" Scripting directives 39syn match ocamlScript "^#\<\(quit\|labels\|warnings\|warn_error\|directory\|remove_directory\|cd\|load\|load_rec\|use\|mod_use\|install_printer\|remove_printer\|require\|list\|ppx\|principal\|predicates\|rectypes\|thread\|trace\|untrace\|untrace_all\|print_depth\|print_length\|camlp4o\|camlp4r\|topfind_log\|topfind_verbose\)\>" 40 41" lowercase identifier - the standard way to match 42syn match ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/ 43 44syn match ocamlKeyChar "|" 45 46" Errors 47syn match ocamlBraceErr "}" 48syn match ocamlBrackErr "\]" 49syn match ocamlParenErr ")" 50syn match ocamlArrErr "|]" 51 52syn match ocamlCommentErr "\*)" 53 54syn match ocamlCountErr "\<downto\>" 55syn match ocamlCountErr "\<to\>" 56 57if !exists("ocaml_revised") 58 syn match ocamlDoErr "\<do\>" 59endif 60 61syn match ocamlDoneErr "\<done\>" 62syn match ocamlThenErr "\<then\>" 63 64" Error-highlighting of "end" without synchronization: 65" as keyword or as error (default) 66if exists("ocaml_noend_error") 67 syn match ocamlKeyword "\<end\>" 68else 69 syn match ocamlEndErr "\<end\>" 70endif 71 72" Some convenient clusters 73syn cluster ocamlAllErrs contains=ocamlBraceErr,ocamlBrackErr,ocamlParenErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr 74 75syn cluster ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr 76 77syn cluster ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod,ocamlVal 78 79 80" Enclosing delimiters 81syn region ocamlEncl transparent matchgroup=ocamlKeyword start="(" matchgroup=ocamlKeyword end=")" contains=ALLBUT,@ocamlContained,ocamlParenErr 82syn region ocamlEncl transparent matchgroup=ocamlKeyword start="{" matchgroup=ocamlKeyword end="}" contains=ALLBUT,@ocamlContained,ocamlBraceErr 83syn region ocamlEncl transparent matchgroup=ocamlKeyword start="\[" matchgroup=ocamlKeyword end="\]" contains=ALLBUT,@ocamlContained,ocamlBrackErr 84syn region ocamlEncl transparent matchgroup=ocamlKeyword start="\[|" matchgroup=ocamlKeyword end="|\]" contains=ALLBUT,@ocamlContained,ocamlArrErr 85 86 87" Comments 88syn region ocamlComment start="(\*" end="\*)" contains=@Spell,ocamlComment,ocamlTodo 89syn keyword ocamlTodo contained TODO FIXME XXX NOTE 90 91 92" Objects 93syn region ocamlEnd matchgroup=ocamlObject start="\<object\>" matchgroup=ocamlObject end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr 94 95 96" Blocks 97if !exists("ocaml_revised") 98 syn region ocamlEnd matchgroup=ocamlKeyword start="\<begin\>" matchgroup=ocamlKeyword end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr 99endif 100 101 102" "for" 103syn region ocamlNone matchgroup=ocamlKeyword start="\<for\>" matchgroup=ocamlKeyword end="\<\(to\|downto\)\>" contains=ALLBUT,@ocamlContained,ocamlCountErr 104 105 106" "do" 107if !exists("ocaml_revised") 108 syn region ocamlDo matchgroup=ocamlKeyword start="\<do\>" matchgroup=ocamlKeyword end="\<done\>" contains=ALLBUT,@ocamlContained,ocamlDoneErr 109endif 110 111" "if" 112syn region ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr 113 114"" PPX nodes 115 116syn match ocamlPpxIdentifier /\(\[@\{1,3\}\)\@<=\w\+\(\.\w\+\)*/ 117syn region ocamlPpx matchgroup=ocamlPpxEncl start="\[@\{1,3\}" contains=TOP end="\]" 118 119"" Modules 120 121" "sig" 122syn region ocamlSig matchgroup=ocamlSigEncl start="\<sig\>" matchgroup=ocamlSigEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule 123syn region ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr 124 125" "open" 126syn region ocamlNone matchgroup=ocamlKeyword start="\<open\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\( *\. *\u\(\w\|'\)*\)*\>" contains=@ocamlAllErrs,ocamlComment 127 128" "include" 129syn match ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod 130 131" "module" - somewhat complicated stuff ;-) 132syn region ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef 133syn region ocamlPreDef start="."me=e-1 matchgroup=ocamlKeyword end="\l\|=\|)"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS 134syn region ocamlModParam start="([^*]" end=")" contained contains=ocamlGenMod,ocamlModParam1,ocamlSig,ocamlVal 135syn match ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty 136syn match ocamlGenMod "()" contained skipwhite skipempty 137 138syn region ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3 139syn region ocamlMPRestr1 matchgroup=ocamlSigEncl start="\ssig\s\=" matchgroup=ocamlSigEncl end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule 140syn region ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2 141syn match ocamlMPRestr3 "\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*" contained 142syn match ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod 143syn keyword ocamlKeyword val 144syn region ocamlVal matchgroup=ocamlKeyword start="\<val\>" matchgroup=ocamlLCIdentifier end="\<\l\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment,ocamlFullMod skipwhite skipempty nextgroup=ocamlMPRestr 145syn region ocamlModRHS start="." end=". *\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod 146syn match ocamlFullMod "\<\u\(\w\|'\)*\( *\. *\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith 147 148syn region ocamlFuncWith start="([^*)]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith 149syn region ocamlFuncStruct matchgroup=ocamlStructEncl start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr 150 151syn match ocamlModTypeRestr "\<\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*\>" contained 152syn region ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith 153syn match ocamlWith "\<\(\u\(\w\|'\)* *\. *\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest 154syn region ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained 155 156" "struct" 157syn region ocamlStruct matchgroup=ocamlStructEncl start="\<\(module\s\+\)\=struct\>" matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr 158 159" "module type" 160syn region ocamlKeyword start="\<module\>\s*\<type\>\(\s*\<of\>\)\=" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef 161syn match ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s+1 skipwhite skipempty nextgroup=ocamlFullMod 162 163" Quoted strings 164syn region ocamlString matchgroup=ocamlQuotedStringDelim start="{\z\([a-z_]*\)|" end="|\z1}" contains=@Spell 165 166syn keyword ocamlKeyword and as assert class 167syn keyword ocamlKeyword constraint else 168syn keyword ocamlKeyword exception external fun 169 170syn keyword ocamlKeyword in inherit initializer 171syn keyword ocamlKeyword lazy let match 172syn keyword ocamlKeyword method mutable new nonrec of 173syn keyword ocamlKeyword parser private rec 174syn keyword ocamlKeyword try type 175syn keyword ocamlKeyword virtual when while with 176 177if exists("ocaml_revised") 178 syn keyword ocamlKeyword do value 179 syn keyword ocamlBoolean True False 180else 181 syn keyword ocamlKeyword function 182 syn keyword ocamlBoolean true false 183endif 184 185syn keyword ocamlType array bool char exn float format format4 186syn keyword ocamlType int int32 int64 lazy_t list nativeint option 187syn keyword ocamlType bytes string unit 188 189syn match ocamlConstructor "(\s*)" 190syn match ocamlConstructor "\[\s*\]" 191syn match ocamlConstructor "\[|\s*>|]" 192syn match ocamlConstructor "\[<\s*>\]" 193syn match ocamlConstructor "\u\(\w\|'\)*\>" 194 195" Polymorphic variants 196syn match ocamlConstructor "`\w\(\w\|'\)*\>" 197 198" Module prefix 199syn match ocamlModPath "\u\(\w\|'\)* *\."he=e-1 200 201syn match ocamlCharacter "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'" 202syn match ocamlCharacter "'\\x\x\x'" 203syn match ocamlCharErr "'\\\d\d'\|'\\\d'" 204syn match ocamlCharErr "'\\[^\'ntbr]'" 205syn region ocamlString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@Spell 206 207syn match ocamlTopStop ";;" 208 209syn match ocamlAnyVar "\<_\>" 210syn match ocamlKeyChar "|[^\]]"me=e-1 211syn match ocamlKeyChar ";" 212syn match ocamlKeyChar "\~" 213syn match ocamlKeyChar "?" 214 215"" Operators 216 217" The grammar of operators is found there: 218" https://caml.inria.fr/pub/docs/manual-ocaml/names.html#operator-name 219" https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:ext-ops 220" https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:index-operators 221" =, *, < and > are both operator names and keywords, we let the user choose how 222" to display them (has to be declared before regular infix operators): 223syn match ocamlEqual "=" 224syn match ocamlStar "*" 225syn match ocamlAngle "<" 226syn match ocamlAngle ">" 227" Custom indexing operators: 228syn match ocamlIndexingOp "\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\(()\|\[]\|{}\)\(<-\)\?" 229" Extension operators (has to be declared before regular infix operators): 230syn match ocamlExtensionOp "#[#~?!.:|&$%<=>@^*/+-]\+" 231" Infix and prefix operators: 232syn match ocamlPrefixOp "![~?!.:|&$%<=>@^*/+-]*" 233syn match ocamlPrefixOp "[~?][~?!.:|&$%<=>@^*/+-]\+" 234syn match ocamlInfixOp "[&$%@^/+-][~?!.:|&$%<=>@^*/+-]*" 235syn match ocamlInfixOp "[|<=>*][~?!.:|&$%<=>@^*/+-]\+" 236syn match ocamlInfixOp "#[~?!.:|&$%<=>@^*/+-]\+#\@!" 237syn match ocamlInfixOp "!=[~?!.:|&$%<=>@^*/+-]\@!" 238syn keyword ocamlInfixOpKeyword asr land lor lsl lsr lxor mod or 239" := is technically an infix operator, but we may want to show it as a keyword 240" (somewhat analogously to = for let‐bindings and <- for assignations): 241syn match ocamlRefAssign ":=" 242" :: is technically not an operator, but we may want to show it as such: 243syn match ocamlCons "::" 244" -> and <- are keywords, not operators (but can appear in longer operators): 245syn match ocamlArrow "->[~?!.:|&$%<=>@^*/+-]\@!" 246if exists("ocaml_revised") 247 syn match ocamlErr "<-[~?!.:|&$%<=>@^*/+-]\@!" 248else 249 syn match ocamlKeyChar "<-[~?!.:|&$%<=>@^*/+-]\@!" 250endif 251 252syn match ocamlNumber "-\=\<\d\(_\|\d\)*[l|L|n]\?\>" 253syn match ocamlNumber "-\=\<0[x|X]\(\x\|_\)\+[l|L|n]\?\>" 254syn match ocamlNumber "-\=\<0[o|O]\(\o\|_\)\+[l|L|n]\?\>" 255syn match ocamlNumber "-\=\<0[b|B]\([01]\|_\)\+[l|L|n]\?\>" 256syn match ocamlFloat "-\=\<\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>" 257 258" Labels 259syn match ocamlLabel "\~\(\l\|_\)\(\w\|'\)*"lc=1 260syn match ocamlLabel "?\(\l\|_\)\(\w\|'\)*"lc=1 261syn region ocamlLabel transparent matchgroup=ocamlLabel start="[~?](\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr 262 263 264" Synchronization 265syn sync minlines=50 266syn sync maxlines=500 267 268if !exists("ocaml_revised") 269 syn sync match ocamlDoSync grouphere ocamlDo "\<do\>" 270 syn sync match ocamlDoSync groupthere ocamlDo "\<done\>" 271endif 272 273if exists("ocaml_revised") 274 syn sync match ocamlEndSync grouphere ocamlEnd "\<\(object\)\>" 275else 276 syn sync match ocamlEndSync grouphere ocamlEnd "\<\(begin\|object\)\>" 277endif 278 279syn sync match ocamlEndSync groupthere ocamlEnd "\<end\>" 280syn sync match ocamlStructSync grouphere ocamlStruct "\<struct\>" 281syn sync match ocamlStructSync groupthere ocamlStruct "\<end\>" 282syn sync match ocamlSigSync grouphere ocamlSig "\<sig\>" 283syn sync match ocamlSigSync groupthere ocamlSig "\<end\>" 284 285" Define the default highlighting. 286" Only when an item doesn't have highlighting yet 287 288hi def link ocamlBraceErr Error 289hi def link ocamlBrackErr Error 290hi def link ocamlParenErr Error 291hi def link ocamlArrErr Error 292 293hi def link ocamlCommentErr Error 294 295hi def link ocamlCountErr Error 296hi def link ocamlDoErr Error 297hi def link ocamlDoneErr Error 298hi def link ocamlEndErr Error 299hi def link ocamlThenErr Error 300 301hi def link ocamlCharErr Error 302 303hi def link ocamlErr Error 304 305hi def link ocamlComment Comment 306 307hi def link ocamlModPath Include 308hi def link ocamlObject Include 309hi def link ocamlModule Include 310hi def link ocamlModParam1 Include 311hi def link ocamlModType Include 312hi def link ocamlMPRestr3 Include 313hi def link ocamlFullMod Include 314hi def link ocamlModTypeRestr Include 315hi def link ocamlWith Include 316hi def link ocamlMTDef Include 317hi def link ocamlSigEncl ocamlModule 318hi def link ocamlStructEncl ocamlModule 319 320hi def link ocamlScript Include 321 322hi def link ocamlConstructor Constant 323 324hi def link ocamlVal Keyword 325hi def link ocamlModPreRHS Keyword 326hi def link ocamlMPRestr2 Keyword 327hi def link ocamlKeyword Keyword 328hi def link ocamlMethod Include 329hi def link ocamlKeyChar Keyword 330hi def link ocamlAnyVar Keyword 331hi def link ocamlTopStop Keyword 332 333hi def link ocamlRefAssign ocamlKeyChar 334hi def link ocamlEqual ocamlKeyChar 335hi def link ocamlStar ocamlInfixOp 336hi def link ocamlAngle ocamlInfixOp 337hi def link ocamlCons ocamlInfixOp 338 339hi def link ocamlPrefixOp ocamlOperator 340hi def link ocamlInfixOp ocamlOperator 341hi def link ocamlExtensionOp ocamlOperator 342hi def link ocamlIndexingOp ocamlOperator 343 344if exists("ocaml_highlight_operators") 345 hi def link ocamlInfixOpKeyword ocamlOperator 346 hi def link ocamlOperator Operator 347else 348 hi def link ocamlInfixOpKeyword Keyword 349endif 350 351hi def link ocamlBoolean Boolean 352hi def link ocamlCharacter Character 353hi def link ocamlNumber Number 354hi def link ocamlFloat Float 355hi def link ocamlString String 356hi def link ocamlQuotedStringDelim Identifier 357 358hi def link ocamlLabel Identifier 359 360hi def link ocamlType Type 361 362hi def link ocamlTodo Todo 363 364hi def link ocamlEncl Keyword 365 366hi def link ocamlPpxEncl ocamlEncl 367 368let b:current_syntax = "ocaml" 369 370" vim: ts=8 371