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