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