| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 
 | " Vim syntax file
" Language:     OCaml
" Filenames:    *.ml *.mli *.mll *.mly
" Maintainers:  Markus Mottl      <markus.mottl@gmail.com>
"               Karl-Heinz Sylla  <Karl-Heinz.Sylla@gmd.de>
"               Issac Trotts      <ijtrotts@ucdavis.edu>
" URL:          https://github.com/ocaml/vim-ocaml
" Last Change:
"               2019 Nov 05 - Accurate type highlighting (Maëlan)
"               2018 Nov 08 - Improved highlighting of operators (Maëlan)
"               2018 Apr 22 - Improved support for PPX (Andrey Popp)
"               2018 Mar 16 - Remove raise, lnot and not from keywords (Étienne Millon, "copy")
"               2017 Apr 11 - Improved matching of negative numbers (MM)
"               2016 Mar 11 - Improved support for quoted strings (Glen Mével)
"               2015 Aug 13 - Allow apostrophes in identifiers (Jonathan Chan, Einar Lielmanis)
"               2015 Jun 17 - Added new "nonrec" keyword (MM)
" A minor patch was applied to the official version so that object/end
" can be distinguished from begin/end, which is used for indentation,
" and folding. (David Baelde)
" Quit when a syntax file was already loaded
if exists("b:current_syntax") && b:current_syntax == "ocaml"
  finish
endif
let s:keepcpo = &cpo
set cpo&vim
" ' can be used in OCaml identifiers
setlocal iskeyword+='
" ` is part of the name of polymorphic variants
setlocal iskeyword+=`
" OCaml is case sensitive.
syn case match
" Access to the method of an object
syn match    ocamlMethod       "#"
" Scripting directives
syn 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\)\>"
" lowercase identifier - the standard way to match
syn match    ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/
" Errors
syn match    ocamlBraceErr   "}"
syn match    ocamlBrackErr   "\]"
syn match    ocamlParenErr   ")"
syn match    ocamlArrErr     "|]"
syn match    ocamlCountErr   "\<downto\>"
syn match    ocamlCountErr   "\<to\>"
if !exists("ocaml_revised")
  syn match    ocamlDoErr      "\<do\>"
endif
syn match    ocamlDoneErr    "\<done\>"
syn match    ocamlThenErr    "\<then\>"
" Error-highlighting of "end" without synchronization:
" as keyword or as error (default)
if exists("ocaml_noend_error")
  syn match    ocamlKeyword    "\<end\>"
else
  syn match    ocamlEndErr     "\<end\>"
endif
" These keywords are only expected nested in constructions that are handled by
" the type linter, so outside of type contexts we highlight them as errors:
syn match    ocamlKwErr  "\<\(mutable\|nonrec\|of\|private\)\>"
" Some convenient clusters
syn cluster  ocamlAllErrs contains=@ocamlAENoParen,ocamlParenErr
syn cluster  ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr,ocamlKwErr
syn cluster  ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlModTypePre,ocamlModRHS,ocamlFuncWith,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlFullMod,ocamlVal
" Enclosing delimiters
syn region   ocamlNone transparent matchgroup=ocamlEncl start="(" matchgroup=ocamlEncl end=")" contains=ALLBUT,@ocamlContained,ocamlParenErr
syn region   ocamlNone transparent matchgroup=ocamlEncl start="{" matchgroup=ocamlEncl end="}"  contains=ALLBUT,@ocamlContained,ocamlBraceErr
syn region   ocamlNone transparent matchgroup=ocamlEncl start="\[" matchgroup=ocamlEncl end="\]" contains=ALLBUT,@ocamlContained,ocamlBrackErr
syn region   ocamlNone transparent matchgroup=ocamlEncl start="\[|" matchgroup=ocamlEncl end="|\]" contains=ALLBUT,@ocamlContained,ocamlArrErr
" Comments
syn region   ocamlComment start="(\*" end="\*)" contains=@Spell,ocamlComment,ocamlTodo
syn keyword  ocamlTodo contained TODO FIXME XXX NOTE
" Objects
syn region   ocamlEnd matchgroup=ocamlObject start="\<object\>" matchgroup=ocamlObject end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
" Blocks
if !exists("ocaml_revised")
  syn region   ocamlEnd matchgroup=ocamlKeyword start="\<begin\>" matchgroup=ocamlKeyword end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
endif
" "for"
syn region   ocamlNone matchgroup=ocamlKeyword start="\<for\>" matchgroup=ocamlKeyword end="\<\(to\|downto\)\>" contains=ALLBUT,@ocamlContained,ocamlCountErr
" "do"
if !exists("ocaml_revised")
  syn region   ocamlDo matchgroup=ocamlKeyword start="\<do\>" matchgroup=ocamlKeyword end="\<done\>" contains=ALLBUT,@ocamlContained,ocamlDoneErr
endif
" "if"
syn region   ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr
"" PPX nodes
syn match ocamlPpxIdentifier /\(\[@\{1,3\}\)\@<=\w\+\(\.\w\+\)*/
syn region ocamlPpx matchgroup=ocamlPpxEncl start="\[@\{1,3\}" contains=TOP end="\]"
"" Modules
" "open"
syn match   ocamlKeyword "\<open\>" skipwhite skipempty nextgroup=ocamlFullMod
" "include"
syn match    ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
" "module" - somewhat complicated stuff ;-)
" 2022-10: please document it?
syn region   ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<_\|\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef
syn region   ocamlPreDef start="."me=e-1 end="[a-z:=)]\@=" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod,ocamlModTypeRestr nextgroup=ocamlModTypePre,ocamlModPreRHS
syn region   ocamlModParam start="(\*\@!" end=")" contained contains=ocamlGenMod,ocamlModParam,ocamlModParam1,ocamlSig,ocamlVal
syn match    ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty
syn match    ocamlGenMod "()" contained skipwhite skipempty
syn match    ocamlModTypePre ":" contained skipwhite skipempty nextgroup=ocamlModTRWith,ocamlSig,ocamlFunctor,ocamlModTypeRestr,ocamlModTypeOf
syn match    ocamlModTypeRestr "\<\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*\>" contained
syn match    ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
syn keyword  ocamlKeyword val
syn region   ocamlVal matchgroup=ocamlKeyword start="\<val\>" matchgroup=ocamlLCIdentifier end="\<\l\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment,ocamlFullMod skipwhite skipempty nextgroup=ocamlModTypePre
syn region   ocamlModRHS start="." end=". *\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
syn match    ocamlFullMod "\<\u\(\w\|'\)*\( *\. *\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith
syn region   ocamlFuncWith start="([*)]\@!" end=")" contained contains=ocamlComment,ocamlWith,ocamlStruct skipwhite skipempty nextgroup=ocamlFuncWith
syn region   ocamlModTRWith start="(\*\@!" end=")" contained contains=@ocamlAENoParen,ocamlWith
syn match    ocamlWith "\<\(\u\(\w\|'\)* *\. *\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest
syn region   ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained
" "struct"
syn region   ocamlStruct matchgroup=ocamlStructEncl start="\<\(module\s\+\)\=struct\>" matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
" "sig"
syn region   ocamlSig matchgroup=ocamlSigEncl start="\<sig\>" matchgroup=ocamlSigEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
" "functor"
syn region   ocamlFunctor start="\<functor\>" matchgroup=ocamlKeyword end="->" contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod skipwhite skipempty nextgroup=ocamlStruct,ocamlSig,ocamlFuncWith,ocamlFunctor
" "module type"
syn region   ocamlModTypeOf start="\<module\s\+type\(\s\+of\)\=\>" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef
syn match    ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s+1 skipwhite skipempty nextgroup=ocamlFullMod
" Quoted strings
syn region ocamlString matchgroup=ocamlQuotedStringDelim start="{\z\([a-z_]*\)|" end="|\z1}" contains=@Spell
syn region ocamlString matchgroup=ocamlQuotedStringDelim start="{%[a-z_]\+\(\.[a-z_]\+\)\?\( \z\([a-z_]\+\)\)\?|" end="|\z1}" contains=@Spell
syn keyword  ocamlKeyword  and as assert class
syn keyword  ocamlKeyword  else
syn keyword  ocamlKeyword  external
syn keyword  ocamlKeyword  in inherit initializer
syn keyword  ocamlKeyword  lazy let match
syn keyword  ocamlKeyword  method new
syn keyword  ocamlKeyword  parser rec
syn keyword  ocamlKeyword  try
syn keyword  ocamlKeyword  virtual when while with
" Keywords which are handled by the type linter:
"     as (within a type equation)
"     constraint exception mutable nonrec of private type
" The `fun` keyword has special treatment because of the syntax `fun … : t -> e`
" where `->` ends the type context rather than being part of it; to handle that,
" we blacklist the ocamlTypeAnnot matchgroup, and we plug ocamlFunTypeAnnot
" instead (later in this file, by using containedin=ocamlFun):
syn region ocamlFun matchgroup=ocamlKeyword start='\<fun\>' matchgroup=ocamlArrow end='->'
\ contains=ALLBUT,@ocamlContained,ocamlArrow,ocamlInfixOp,ocamlTypeAnnot
if exists("ocaml_revised")
  syn keyword  ocamlKeyword  do value
  syn keyword  ocamlBoolean  True False
else
  syn keyword  ocamlKeyword  function
  syn keyword  ocamlBoolean  true false
endif
syn match    ocamlEmptyConstructor  "(\s*)"
syn match    ocamlEmptyConstructor  "\[\s*\]"
syn match    ocamlEmptyConstructor  "\[|\s*>|]"
syn match    ocamlEmptyConstructor  "\[<\s*>\]"
syn match    ocamlConstructor  "\u\(\w\|'\)*\>"
" Polymorphic variants
syn match    ocamlConstructor  "`\w\(\w\|'\)*\>"
" Module prefix
syn match    ocamlModPath      "\u\(\w\|'\)* *\."he=e-1
syn match    ocamlCharacter    "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'"
syn match    ocamlCharacter    "'\\x\x\x'"
syn match    ocamlCharErr      "'\\\d\d'\|'\\\d'"
syn match    ocamlCharErr      "'\\[^\'ntbr]'"
syn region   ocamlString       start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@Spell
syn match    ocamlAnyVar       "\<_\>"
syn match    ocamlKeyChar      "|]\@!"
syn match    ocamlKeyChar      ";"
syn match    ocamlKeyChar      "\~"
syn match    ocamlKeyChar      "?"
" NOTE: for correct precedence, the rule for ";;" must come after that for ";"
syn match    ocamlTopStop      ";;"
"" Operators
" The grammar of operators is found there:
"     https://caml.inria.fr/pub/docs/manual-ocaml/names.html#operator-name
"     https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:ext-ops
"     https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#s:index-operators
" = is both an operator name and a keyword, we let the user choose how
" to display it (has to be declared before regular infix operators):
syn match    ocamlEqual        "="
" Custom indexing operators:
syn region   ocamlIndexing matchgroup=ocamlIndexingOp
  \ start="\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\_s*("
  \ end=")\(\_s*<-\)\?"
  \ contains=ALLBUT,@ocamlContained,ocamlParenErr
syn region   ocamlIndexing matchgroup=ocamlIndexingOp
  \ start="\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\_s*\["
  \ end="]\(\_s*<-\)\?"
  \ contains=ALLBUT,@ocamlContained,ocamlBrackErr
syn region   ocamlIndexing matchgroup=ocamlIndexingOp
  \ start="\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\_s*{"
  \ end="}\(\_s*<-\)\?"
  \ contains=ALLBUT,@ocamlContained,ocamlBraceErr
" Extension operators (has to be declared before regular infix operators):
syn match    ocamlExtensionOp          "#[#~?!.:|&$%<=>@^*/+-]\+"
" Infix and prefix operators:
syn match    ocamlPrefixOp              "![~?!.:|&$%<=>@^*/+-]*"
syn match    ocamlPrefixOp           "[~?][~?!.:|&$%<=>@^*/+-]\+"
syn match    ocamlInfixOp   "[&$%<>@^*/+-][~?!.:|&$%<=>@^*/+-]*"
syn match    ocamlInfixOp            "[|=][~?!.:|&$%<=>@^*/+-]\+"
syn match    ocamlInfixOp               "#[~?!.:|&$%<=>@^*/+-]\+#\@!"
syn match    ocamlInfixOp              "!=[~?!.:|&$%<=>@^*/+-]\@!"
syn keyword  ocamlInfixOpKeyword      asr land lor lsl lsr lxor mod or
" := is technically an infix operator, but we may want to show it as a keyword
" (somewhat analogously to = for let‐bindings and <- for assignations):
syn match    ocamlRefAssign    ":="
" :: is technically not an operator, but we may want to show it as such:
syn match    ocamlCons         "::"
" -> and <- are keywords, not operators (but can appear in longer operators):
syn match    ocamlArrow        "->[~?!.:|&$%<=>@^*/+-]\@!"
if exists("ocaml_revised")
  syn match    ocamlErr        "<-[~?!.:|&$%<=>@^*/+-]\@!"
else
  syn match    ocamlKeyChar    "<-[~?!.:|&$%<=>@^*/+-]\@!"
endif
" Script shebang (has to be declared after operators)
syn match    ocamlShebang       "\%1l^#!.*$"
syn match    ocamlNumber        "-\=\<\d\(_\|\d\)*[l|L|n]\?\>"
syn match    ocamlNumber        "-\=\<0[x|X]\(\x\|_\)\+[l|L|n]\?\>"
syn match    ocamlNumber        "-\=\<0[o|O]\(\o\|_\)\+[l|L|n]\?\>"
syn match    ocamlNumber        "-\=\<0[b|B]\([01]\|_\)\+[l|L|n]\?\>"
syn match    ocamlFloat         "-\=\<\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>"
" Labels
syn match    ocamlLabel        "[~?]\(\l\|_\)\(\w\|'\)*:\?"
syn region   ocamlLabel transparent matchgroup=ocamlLabel start="[~?](\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"" Type contexts
" How we recognize type contexts is explained in `type-linter-notes.md`
" and a test suite is found in `type-linter-test.ml`.
"
" ocamlTypeExpr is the cluster of things that can make up a type expression
" (in a loose sense, e.g. the “as” keyword and universal quantification are
" included). Regions containing a type expression use it like this:
"
"     contains=@ocamlTypeExpr,...
"
" ocamlTypeContained is the cluster of things that can be found in a type
" expression or a type definition. It is not expected to be used in any region,
" it exists solely for throwing things in it that should not pollute the main
" linter.
"
" Both clusters are filled in incrementally. Every match group that is not to be
" found at the main level must be declared as “contained” and added to either
" ocamlTypeExpr or ocamlTypeContained.
"
" In these clusters we don’t put generic things that can also be found elswhere,
" i.e. ocamlComment and ocamlPpx, because everything that is in these clusters
" is also put in ocamlContained and thus ignored by the main linter.
"syn cluster ocamlTypeExpr contains=
syn cluster ocamlTypeContained contains=@ocamlTypeExpr
syn cluster ocamlContained add=@ocamlTypeContained
" We’ll use a “catch-all” highlighting group to show as error anything that is
" not matched more specifically; we don’t want spaces to be reported as errors
" (different background color), so we just catch them here:
syn cluster ocamlTypeExpr add=ocamlTypeBlank
syn match    ocamlTypeBlank    contained  "\_s\+"
hi link ocamlTypeBlank NONE
" NOTE: Carefully avoid catching "(*" here.
syn cluster ocamlTypeExpr add=ocamlTypeParen
syn region ocamlTypeParen contained transparent
\ matchgroup=ocamlEncl start="(\*\@!"
\ matchgroup=ocamlEncl end=")"
\ contains=@ocamlTypeExpr,ocamlComment,ocamlPpx
syn cluster ocamlTypeExpr add=ocamlTypeKeyChar,ocamlTypeAs
syn match    ocamlTypeKeyChar  contained  "->"
syn match    ocamlTypeKeyChar  contained  "\*"
syn match    ocamlTypeKeyChar  contained  "#"
syn match    ocamlTypeKeyChar  contained  ","
syn match    ocamlTypeKeyChar  contained  "\."
syn keyword  ocamlTypeAs       contained  as
hi link ocamlTypeAs ocamlKeyword
syn cluster ocamlTypeExpr add=ocamlTypeVariance
syn match ocamlTypeVariance contained "[-+!]\ze *\('\|\<_\>\)"
syn match ocamlTypeVariance contained "[-+] *!\+\ze *\('\|\<_\>\)"
syn match ocamlTypeVariance contained "! *[-+]\+\ze *\('\|\<_\>\)"
syn cluster ocamlTypeContained add=ocamlTypeEq
syn match    ocamlTypeEq       contained  "[+:]\?="
hi link ocamlTypeEq ocamlKeyChar
syn cluster ocamlTypeExpr add=ocamlTypeVar,ocamlTypeConstr,ocamlTypeAnyVar,ocamlTypeBuiltin
syn match    ocamlTypeVar      contained   "'\(\l\|_\)\(\w\|'\)*\>"
syn match    ocamlTypeConstr   contained  "\<\(\l\|_\)\(\w\|'\)*\>"
" NOTE: for correct precedence, the rule for the wildcard (ocamlTypeAnyVar)
" must come after the rule for type constructors (ocamlTypeConstr).
syn match    ocamlTypeAnyVar   contained  "\<_\>"
" NOTE: For correct precedence, these builtin names must occur after the rule
" for type constructors (ocamlTypeConstr) but before the rule for non-optional
" labeled arguments (ocamlTypeLabel). For the latter to take precedence over
" these builtin names, we use “syn match” here instead of “syn keyword”.
syn match    ocamlTypeBuiltin  contained  "\<array\>"
syn match    ocamlTypeBuiltin  contained  "\<bool\>"
syn match    ocamlTypeBuiltin  contained  "\<bytes\>"
syn match    ocamlTypeBuiltin  contained  "\<char\>"
syn match    ocamlTypeBuiltin  contained  "\<exn\>"
syn match    ocamlTypeBuiltin  contained  "\<float\>"
syn match    ocamlTypeBuiltin  contained  "\<format\>"
syn match    ocamlTypeBuiltin  contained  "\<format4\>"
syn match    ocamlTypeBuiltin  contained  "\<format6\>"
syn match    ocamlTypeBuiltin  contained  "\<in_channel\>"
syn match    ocamlTypeBuiltin  contained  "\<int\>"
syn match    ocamlTypeBuiltin  contained  "\<int32\>"
syn match    ocamlTypeBuiltin  contained  "\<int64\>"
syn match    ocamlTypeBuiltin  contained  "\<lazy_t\>"
syn match    ocamlTypeBuiltin  contained  "\<list\>"
syn match    ocamlTypeBuiltin  contained  "\<nativeint\>"
syn match    ocamlTypeBuiltin  contained  "\<option\>"
syn match    ocamlTypeBuiltin  contained  "\<out_channel\>"
syn match    ocamlTypeBuiltin  contained  "\<ref\>"
syn match    ocamlTypeBuiltin  contained  "\<result\>"
syn match    ocamlTypeBuiltin  contained  "\<scanner\>"
syn match    ocamlTypeBuiltin  contained  "\<string\>"
syn match    ocamlTypeBuiltin  contained  "\<unit\>"
syn cluster ocamlTypeExpr add=ocamlTypeLabel
syn match    ocamlTypeLabel    contained  "?\?\(\l\|_\)\(\w\|'\)*\_s*:[>=]\@!"
hi link ocamlTypeLabel ocamlLabel
" Object type
syn cluster ocamlTypeExpr add=ocamlTypeObject
syn region ocamlTypeObject contained
\ matchgroup=ocamlEncl start="<"
\ matchgroup=ocamlEncl end=">"
\ contains=ocamlTypeObjectDots,ocamlLCIdentifier,ocamlTypeObjectAnnot,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeObject ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypeObjectDots
syn match ocamlTypeObjectDots contained "\.\."
hi link ocamlTypeObjectDots ocamlKeyChar
syn cluster ocamlTypeContained add=ocamlTypeObjectAnnot
syn region ocamlTypeObjectAnnot contained
\ matchgroup=ocamlKeyChar start=":"
\ matchgroup=ocamlKeyChar end=";\|>\@="
\ contains=@ocamlTypeExpr,ocamlComment,ocamlPpx
hi link ocamlTypeObjectAnnot ocamlTypeCatchAll
" Record type definition
syn cluster ocamlTypeContained add=ocamlTypeRecordDecl
syn region ocamlTypeRecordDecl contained
\ matchgroup=ocamlEncl start="{"
\ matchgroup=ocamlEncl end="}"
\ contains=ocamlTypeMutable,ocamlLCIdentifier,ocamlTypeRecordAnnot,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeRecordDecl ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypeMutable
syn keyword ocamlTypeMutable contained mutable
hi link ocamlTypeMutable ocamlKeyword
syn cluster ocamlTypeContained add=ocamlTypeRecordAnnot
syn region ocamlTypeRecordAnnot contained
\ matchgroup=ocamlKeyChar start=":"
\ matchgroup=ocamlKeyChar end=";\|}\@="
\ contains=@ocamlTypeExpr,ocamlComment,ocamlPpx
hi link ocamlTypeRecordAnnot ocamlTypeCatchAll
" Polymorphic variant types
" NOTE: Carefully avoid catching "[@" here.
syn cluster ocamlTypeExpr add=ocamlTypeVariant
syn region ocamlTypeVariant contained
\ matchgroup=ocamlEncl start="\[>" start="\[<" start="\[@\@!"
\ matchgroup=ocamlEncl end="\]"
\ contains=ocamlTypeVariantKeyChar,ocamlTypeVariantConstr,ocamlTypeVariantAnnot,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeVariant ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypeVariantKeyChar
syn match ocamlTypeVariantKeyChar contained "|"
syn match ocamlTypeVariantKeyChar contained ">"
hi link ocamlTypeVariantKeyChar ocamlKeyChar
syn cluster ocamlTypeContained add=ocamlTypeVariantConstr
syn match ocamlTypeVariantConstr contained "`\w\(\w\|'\)*\>"
hi link ocamlTypeVariantConstr ocamlConstructor
syn cluster ocamlTypeContained add=ocamlTypeVariantAnnot
syn region ocamlTypeVariantAnnot contained
\ matchgroup=ocamlKeyword start="\<of\>"
\ matchgroup=ocamlKeyChar end="|\|>\|\]\@="
\ contains=@ocamlTypeExpr,ocamlTypeAmp,ocamlComment,ocamlPpx
hi link ocamlTypeVariantAnnot ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypeAmp
syn match ocamlTypeAmp contained "&"
hi link ocamlTypeAmp ocamlTypeKeyChar
" Sum type definition
syn cluster ocamlTypeContained add=ocamlTypeSumDecl
syn region ocamlTypeSumDecl contained
\ matchgroup=ocamlTypeSumBar    start="|"
\ matchgroup=ocamlTypeSumConstr start="\<\u\(\w\|'\)*\>"
\ matchgroup=ocamlTypeSumConstr start="\<false\>" start="\<true\>"
\ matchgroup=ocamlTypeSumConstr start="(\_s*)" start="\[\_s*]" start="(\_s*::\_s*)"
\ matchgroup=NONE end="\(\<type\>\|\<exception\>\|\<val\>\|\<module\>\|\<class\>\|\<method\>\|\<constraint\>\|\<inherit\>\|\<object\>\|\<struct\>\|\<open\>\|\<include\>\|\<let\>\|\<external\>\|\<in\>\|\<end\>\|)\|]\|}\|;\|;;\|=\)\@="
\ matchgroup=NONE end="\(\<and\>\)\@="
\ contains=ocamlTypeSumBar,ocamlTypeSumConstr,ocamlTypeSumAnnot,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeSumDecl ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypeSumBar
syn match ocamlTypeSumBar contained "|"
hi link ocamlTypeSumBar ocamlKeyChar
syn cluster ocamlTypeContained add=ocamlTypeSumConstr
syn match ocamlTypeSumConstr contained "\<\u\(\w\|'\)*\>"
syn match ocamlTypeSumConstr contained "\<false\>"
syn match ocamlTypeSumConstr contained "\<true\>"
syn match ocamlTypeSumConstr contained "(\_s*)"
syn match ocamlTypeSumConstr contained "\[\_s*]"
syn match ocamlTypeSumConstr contained "(\_s*::\_s*)"
hi link ocamlTypeSumConstr ocamlConstructor
syn cluster ocamlTypeContained add=ocamlTypeSumAnnot
syn region ocamlTypeSumAnnot contained
\ matchgroup=ocamlKeyword start="\<of\>"
\ matchgroup=ocamlKeyChar start=":"
\ matchgroup=NONE end="|\@="
\ matchgroup=NONE end="\(\<type\>\|\<exception\>\|\<val\>\|\<module\>\|\<class\>\|\<method\>\|\<constraint\>\|\<inherit\>\|\<object\>\|\<struct\>\|\<open\>\|\<include\>\|\<let\>\|\<external\>\|\<in\>\|\<end\>\|)\|]\|}\|;\|;;\)\@="
\ matchgroup=NONE end="\(\<and\>\)\@="
\ contains=@ocamlTypeExpr,ocamlTypeRecordDecl,ocamlComment,ocamlPpx
hi link ocamlTypeSumAnnot ocamlTypeCatchAll
" Type context opened by “type” (type definition), “constraint” (type
" constraint) and “exception” (exception definition)
syn region ocamlTypeDef
\ matchgroup=ocamlKeyword start="\<type\>\(\_s\+\<nonrec\>\)\?\|\<constraint\>\|\<exception\>"
\ matchgroup=NONE end="\(\<type\>\|\<exception\>\|\<val\>\|\<module\>\|\<class\>\|\<method\>\|\<constraint\>\|\<inherit\>\|\<object\>\|\<struct\>\|\<open\>\|\<include\>\|\<let\>\|\<external\>\|\<in\>\|\<end\>\|)\|]\|}\|;\|;;\)\@="
\ contains=@ocamlTypeExpr,ocamlTypeEq,ocamlTypePrivate,ocamlTypeDefDots,ocamlTypeRecordDecl,ocamlTypeSumDecl,ocamlTypeDefAnd,ocamlComment,ocamlPpx
hi link ocamlTypeDef ocamlTypeCatchAll
syn cluster ocamlTypeContained add=ocamlTypePrivate
syn keyword ocamlTypePrivate contained private
hi link ocamlTypePrivate ocamlKeyword
syn cluster ocamlTypeContained add=ocamlTypeDefAnd
syn keyword ocamlTypeDefAnd contained and
hi link ocamlTypeDefAnd ocamlKeyword
syn cluster ocamlTypeContained add=ocamlTypeDefDots
syn match ocamlTypeDefDots contained "\.\."
hi link ocamlTypeDefDots ocamlKeyChar
" When "exception" is preceded by "with", "|" or "(", that’s not an exception
" definition but an exception pattern; we simply highlight the keyword without
" starting a type context.
" NOTE: These rules must occur after that for "exception".
syn match ocamlKeyword "\<with\_s\+exception\>"lc=4
syn match ocamlKeyword "|\_s*exception\>"lc=1
syn match ocamlKeyword "(\_s*exception\>"lc=1
" Type context opened by “:” (countless kinds of type annotations) and “:>”
" (type coercions)
syn region ocamlTypeAnnot matchgroup=ocamlKeyChar start=":\(>\|\_s*type\>\|[>:=]\@!\)"
\ matchgroup=NONE end="\(\<type\>\|\<exception\>\|\<val\>\|\<module\>\|\<class\>\|\<method\>\|\<constraint\>\|\<inherit\>\|\<object\>\|\<struct\>\|\<open\>\|\<include\>\|\<let\>\|\<external\>\|\<in\>\|\<end\>\|)\|]\|}\|;\|;;\)\@="
\ matchgroup=NONE end="\(;\|}\)\@="
\ matchgroup=NONE end="\(=\|:>\)\@="
\ contains=@ocamlTypeExpr,ocamlComment,ocamlPpx
hi link ocamlTypeAnnot ocamlTypeCatchAll
" Type annotation that gives the return type of a `fun` keyword
" (the type context is ended by `->`)
syn cluster ocamlTypeContained add=ocamlFunTypeAnnot
syn region ocamlFunTypeAnnot contained containedin=ocamlFun
\ matchgroup=ocamlKeyChar start=":"
\ matchgroup=NONE end="\(->\)\@="
\ contains=@ocamlTypeExpr,ocamlComment,ocamlPpx
hi link ocamlFunTypeAnnot ocamlTypeCatchAll
" Module paths (including functors) in types.
" NOTE: This rule must occur after the rule for ocamlTypeSumDecl as it must take
" precedence over it (otherwise the module name would be mistakenly highlighted
" as a constructor).
" NOTE: Carefully avoid catching "(*" here.
syn cluster ocamlTypeExpr add=ocamlTypeModPath
syn match ocamlTypeModPath contained "\<\u\(\w\|'\)*\_s*\."
syn region ocamlTypeModPath contained transparent
\ matchgroup=ocamlModPath start="\<\u\(\w\|'\)*\_s*(\*\@!"
\ matchgroup=ocamlModPath end=")\_s*\."
\ contains=ocamlTypeDotlessModPath,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeModPath ocamlModPath
syn cluster ocamlTypeContained add=ocamlTypeDotlessModPath
syn match ocamlTypeDotlessModPath contained "\<\u\(\w\|'\)*\_s*\.\?"
syn region ocamlTypeDotlessModPath contained transparent
\ matchgroup=ocamlModPath start="\<\u\(\w\|'\)*\_s*(\*\@!"
\ matchgroup=ocamlModPath end=")\_s*\.\?"
\ contains=ocamlTypeDotlessModPath,ocamlTypeBlank,ocamlComment,ocamlPpx
hi link ocamlTypeDotlessModPath ocamlTypeModPath
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Synchronization
syn sync minlines=50
syn sync maxlines=500
if !exists("ocaml_revised")
  syn sync match ocamlDoSync      grouphere  ocamlDo      "\<do\>"
  syn sync match ocamlDoSync      groupthere ocamlDo      "\<done\>"
endif
if exists("ocaml_revised")
  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(object\)\>"
else
  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(begin\|object\)\>"
endif
syn sync match ocamlEndSync     groupthere ocamlEnd     "\<end\>"
syn sync match ocamlStructSync  grouphere  ocamlStruct  "\<struct\>"
syn sync match ocamlStructSync  groupthere ocamlStruct  "\<end\>"
syn sync match ocamlSigSync     grouphere  ocamlSig     "\<sig\>"
syn sync match ocamlSigSync     groupthere ocamlSig     "\<end\>"
" Define the default highlighting.
hi def link ocamlBraceErr	   Error
hi def link ocamlBrackErr	   Error
hi def link ocamlParenErr	   Error
hi def link ocamlArrErr	   Error
hi def link ocamlCountErr	   Error
hi def link ocamlDoErr	   Error
hi def link ocamlDoneErr	   Error
hi def link ocamlEndErr	   Error
hi def link ocamlThenErr	   Error
hi def link ocamlKwErr	   Error
hi def link ocamlCharErr	   Error
hi def link ocamlErr	   Error
hi def link ocamlComment	   Comment
hi def link ocamlShebang    ocamlComment
hi def link ocamlModPath	   Include
hi def link ocamlObject	   Include
hi def link ocamlModule	   Include
hi def link ocamlModParam1    Include
hi def link ocamlGenMod       Include
hi def link ocamlFullMod	   Include
hi def link ocamlFuncWith	   Include
hi def link ocamlModParam     Include
hi def link ocamlModTypeRestr Include
hi def link ocamlWith	   Include
hi def link ocamlMTDef	   Include
hi def link ocamlSigEncl	   ocamlModule
hi def link ocamlStructEncl	   ocamlModule
hi def link ocamlScript	   Include
hi def link ocamlConstructor  Constant
hi def link ocamlEmptyConstructor  ocamlConstructor
hi def link ocamlVal          Keyword
hi def link ocamlModTypePre   Keyword
hi def link ocamlModPreRHS    Keyword
hi def link ocamlFunctor	   Keyword
hi def link ocamlModTypeOf  Keyword
hi def link ocamlKeyword	   Keyword
hi def link ocamlMethod	   Include
hi def link ocamlArrow	   Keyword
hi def link ocamlKeyChar	   Keyword
hi def link ocamlAnyVar	   Keyword
hi def link ocamlTopStop	   Keyword
hi def link ocamlRefAssign    ocamlKeyChar
hi def link ocamlEqual        ocamlKeyChar
hi def link ocamlCons         ocamlInfixOp
hi def link ocamlPrefixOp       ocamlOperator
hi def link ocamlInfixOp        ocamlOperator
hi def link ocamlExtensionOp    ocamlOperator
hi def link ocamlIndexingOp     ocamlOperator
if exists("ocaml_highlight_operators")
    hi def link ocamlInfixOpKeyword ocamlOperator
    hi def link ocamlOperator       Operator
else
    hi def link ocamlInfixOpKeyword Keyword
endif
hi def link ocamlBoolean	   Boolean
hi def link ocamlCharacter    Character
hi def link ocamlNumber	   Number
hi def link ocamlFloat	   Float
hi def link ocamlString	   String
hi def link ocamlQuotedStringDelim Identifier
hi def link ocamlLabel	   Identifier
" Type linting groups that the user can customize:
" - ocamlTypeCatchAll: anything in a type context that is not caught by more
"   specific rules (in principle, this should only match syntax errors)
" - ocamlTypeConstr: type constructors
" - ocamlTypeBuiltin: builtin type constructors (like int or list)
" - ocamlTypeVar: type variables ('a)
" - ocamlTypeAnyVar: wildcard (_)
" - ocamlTypeVariance: variance and injectivity indications (+'a, !'a)
" - ocamlTypeKeyChar: symbols such as -> and *
" Default values below mimick the behavior before the type linter was
" implemented, but now we can do better. :-)
hi def link ocamlTypeCatchAll Error
hi def link ocamlTypeConstr   NONE
hi def link ocamlTypeBuiltin  Type
hi def link ocamlTypeVar      NONE
hi def link ocamlTypeAnyVar   NONE
hi def link ocamlTypeVariance ocamlKeyChar
hi def link ocamlTypeKeyChar  ocamlKeyChar
hi def link ocamlTodo	   Todo
hi def link ocamlEncl	   Keyword
hi def link ocamlPpxEncl       ocamlEncl
let b:current_syntax = "ocaml"
let &cpo = s:keepcpo
unlet s:keepcpo
" vim: ts=8
 |