diff options
Diffstat (limited to 'runtime/syntax/ocaml.vim')
-rw-r--r-- | runtime/syntax/ocaml.vim | 407 |
1 files changed, 341 insertions, 66 deletions
diff --git a/runtime/syntax/ocaml.vim b/runtime/syntax/ocaml.vim index af3efd3..04ba392 100644 --- a/runtime/syntax/ocaml.vim +++ b/runtime/syntax/ocaml.vim @@ -6,6 +6,7 @@ " 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") @@ -38,25 +39,18 @@ syn case match " Access to the method of an object syn match ocamlMethod "#" -" Script headers highlighted like comments -syn match ocamlComment "^#!.*" contains=@Spell - " 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\|'\)*\>/ -syn match ocamlKeyChar "|" - " Errors syn match ocamlBraceErr "}" syn match ocamlBrackErr "\]" syn match ocamlParenErr ")" syn match ocamlArrErr "|]" -syn match ocamlCommentErr "\*)" - syn match ocamlCountErr "\<downto\>" syn match ocamlCountErr "\<to\>" @@ -75,19 +69,22 @@ else syn match ocamlEndErr "\<end\>" endif -" Some convenient clusters -syn cluster ocamlAllErrs contains=ocamlBraceErr,ocamlBrackErr,ocamlParenErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr +" 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\)\>" -syn cluster ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr +" 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,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod,ocamlVal +syn cluster ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlModTypePre,ocamlModRHS,ocamlFuncWith,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlFullMod,ocamlVal " Enclosing delimiters -syn region ocamlEncl transparent matchgroup=ocamlKeyword start="(" matchgroup=ocamlKeyword end=")" contains=ALLBUT,@ocamlContained,ocamlParenErr -syn region ocamlEncl transparent matchgroup=ocamlKeyword start="{" matchgroup=ocamlKeyword end="}" contains=ALLBUT,@ocamlContained,ocamlBraceErr -syn region ocamlEncl transparent matchgroup=ocamlKeyword start="\[" matchgroup=ocamlKeyword end="\]" contains=ALLBUT,@ocamlContained,ocamlBrackErr -syn region ocamlEncl transparent matchgroup=ocamlKeyword start="\[|" matchgroup=ocamlKeyword end="|\]" contains=ALLBUT,@ocamlContained,ocamlArrErr +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 @@ -124,10 +121,6 @@ syn region ocamlPpx matchgroup=ocamlPpxEncl start="\[@\{1,3\}" contains=TOP end= "" Modules -" "sig" -syn region ocamlSig matchgroup=ocamlSigEncl start="\<sig\>" matchgroup=ocamlSigEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule -syn region ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr - " "open" syn match ocamlKeyword "\<open\>" skipwhite skipempty nextgroup=ocamlFullMod @@ -135,51 +128,66 @@ syn match ocamlKeyword "\<open\>" skipwhite skipempty nextgroup=ocamlFullMod syn match ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod " "module" - somewhat complicated stuff ;-) -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 matchgroup=ocamlKeyword end="\l\|=\|)"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS -syn region ocamlModParam start="([^*]" end=")" contained contains=ocamlGenMod,ocamlModParam1,ocamlSig,ocamlVal +" 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 region ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3 -syn region ocamlMPRestr1 matchgroup=ocamlSigEncl start="\ssig\s\=" matchgroup=ocamlSigEncl end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule -syn region ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlGenMod skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2 -syn match ocamlMPRestr3 "\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*" contained +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=ocamlMPRestr +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="([^*)]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith -syn region ocamlFuncStruct matchgroup=ocamlStructEncl start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlStructEncl end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr +syn region ocamlFuncWith start="([*)]\@!" end=")" contained contains=ocamlComment,ocamlWith,ocamlStruct skipwhite skipempty nextgroup=ocamlFuncWith -syn match ocamlModTypeRestr "\<\w\(\w\|'\)*\( *\. *\w\(\w\|'\)*\)*\>" contained -syn region ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith +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 ocamlKeyword start="\<module\>\s*\<type\>\(\s*\<of\>\)\=" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef +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 constraint else -syn keyword ocamlKeyword exception external fun - +syn keyword ocamlKeyword else +syn keyword ocamlKeyword external syn keyword ocamlKeyword in inherit initializer syn keyword ocamlKeyword lazy let match -syn keyword ocamlKeyword method mutable new nonrec of -syn keyword ocamlKeyword parser private rec -syn keyword ocamlKeyword try type +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 @@ -188,14 +196,10 @@ else syn keyword ocamlBoolean true false endif -syn keyword ocamlType array bool char exn float format format4 -syn keyword ocamlType int int32 int64 lazy_t list nativeint option -syn keyword ocamlType bytes string unit - -syn match ocamlConstructor "(\s*)" -syn match ocamlConstructor "\[\s*\]" -syn match ocamlConstructor "\[|\s*>|]" -syn match ocamlConstructor "\[<\s*>\]" +syn match ocamlEmptyConstructor "(\s*)" +syn match ocamlEmptyConstructor "\[\s*\]" +syn match ocamlEmptyConstructor "\[|\s*>|]" +syn match ocamlEmptyConstructor "\[<\s*>\]" syn match ocamlConstructor "\u\(\w\|'\)*\>" " Polymorphic variants @@ -210,26 +214,24 @@ syn match ocamlCharErr "'\\\d\d'\|'\\\d'" syn match ocamlCharErr "'\\[^\'ntbr]'" syn region ocamlString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@Spell -syn match ocamlTopStop ";;" - syn match ocamlAnyVar "\<_\>" -syn match ocamlKeyChar "|[^\]]"me=e-1 +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 -" =, *, < and > are both operator names and keywords, we let the user choose how -" to display them (has to be declared before regular infix 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 "=" -syn match ocamlStar "*" -syn match ocamlAngle "<" -syn match ocamlAngle ">" " Custom indexing operators: syn region ocamlIndexing matchgroup=ocamlIndexingOp \ start="\.[~?!:|&$%=>@^/*+-][~?!.:|&$%<=>@^*/+-]*\_s*(" @@ -248,8 +250,8 @@ 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 match ocamlInfixOp "#[~?!.:|&$%<=>@^*/+-]\+#\@!" syn match ocamlInfixOp "!=[~?!.:|&$%<=>@^*/+-]\@!" syn keyword ocamlInfixOpKeyword asr land lor lsl lsr lxor mod or @@ -266,6 +268,9 @@ 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]\?\>" @@ -273,10 +278,264 @@ 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\|'\)*"lc=1 -syn match ocamlLabel "?\(\l\|_\)\(\w\|'\)*"lc=1 +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 @@ -306,27 +565,25 @@ hi def link ocamlBrackErr Error hi def link ocamlParenErr Error hi def link ocamlArrErr Error -hi def link ocamlCommentErr 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 ocamlModType Include -hi def link ocamlMPRestr3 Include hi def link ocamlFullMod Include hi def link ocamlFuncWith Include hi def link ocamlModParam Include @@ -339,10 +596,13 @@ 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 ocamlMPRestr2 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 @@ -352,8 +612,6 @@ hi def link ocamlTopStop Keyword hi def link ocamlRefAssign ocamlKeyChar hi def link ocamlEqual ocamlKeyChar -hi def link ocamlStar ocamlInfixOp -hi def link ocamlAngle ocamlInfixOp hi def link ocamlCons ocamlInfixOp hi def link ocamlPrefixOp ocamlOperator @@ -377,7 +635,24 @@ hi def link ocamlQuotedStringDelim Identifier hi def link ocamlLabel Identifier -hi def link ocamlType Type +" 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 |