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