View raw

1 { 2 "name": "OCaml", 3 "scopeName": "source.ocaml", 4 "fileTypes": ["ml", "eliom", ".ocamlinit"], 5 "patterns": [ 6 { "include": "#directives" }, 7 { "include": "#comments" }, 8 { "include": "#strings" }, 9 { "include": "#characters" }, 10 { "include": "#attributes" }, 11 { "include": "#extensions" }, 12 { "include": "#modules" }, 13 { "include": "#bindings" }, 14 { "include": "#operators" }, 15 { "include": "#keywords" }, 16 { "include": "#literals" }, 17 { "include": "#types" }, 18 { "include": "#identifiers" } 19 ], 20 "repository": { 21 "directives": { 22 "patterns": [ 23 { 24 "comment": "line number directive", 25 "begin": "^[[:space:]]*(#)[[:space:]]*([[:digit:]]+)", 26 "end": "$", 27 "beginCaptures": { 28 "1": { "name": "keyword.other.ocaml" }, 29 "2": { "name": "constant.numeric.decimal.integer.ocaml" } 30 }, 31 "contentName": "comment.line.directive.ocaml" 32 }, 33 { 34 "comment": "toplevel directives", 35 "patterns": [ 36 { 37 "comment": "general, loading codes", 38 "begin": "^[[:space:]]*(#)[[:space:]]*(help|quit|cd|directory|remove_directory|load_rec|load|use|mod_use)", 39 "end": "$", 40 "beginCaptures": { 41 "1": { "name": "keyword.other.ocaml" }, 42 "2": { "name": "keyword.other.ocaml" } 43 }, 44 "patterns": [{ "include": "#strings" }] 45 }, 46 { 47 "comment": "environment queries", 48 "begin": "^[[:space:]]*(#)[[:space:]]*(show_class_type|show_class|show_exception|show_module_type|show_module|show_type|show_val|show)", 49 "end": "$", 50 "beginCaptures": { 51 "1": { "name": "keyword.other.ocaml" }, 52 "2": { "name": "keyword.other.ocaml" } 53 }, 54 "patterns": [{ "include": "#types" }, { "include": "#identifiers" }] 55 }, 56 { 57 "comment": "pretty-printing, tracing", 58 "begin": "^[[:space:]]*(#)[[:space:]]*(install_printer|print_depth|print_length|remove_printer|trace|untrace_all|untrace)", 59 "end": "$", 60 "beginCaptures": { 61 "1": { "name": "keyword.other.ocaml" }, 62 "2": { "name": "keyword.other.ocaml" } 63 }, 64 "patterns": [{ "include": "#literals" }, { "include": "#identifiers" }] 65 }, 66 { 67 "comment": "compiler options", 68 "begin": "^[[:space:]]*(#)[[:space:]]*(labels|ppx|principal|rectypes|warn_error|warnings)", 69 "end": "$", 70 "beginCaptures": { 71 "1": { "name": "keyword.other.ocaml" }, 72 "2": { "name": "keyword.other.ocaml" } 73 }, 74 "patterns": [{ "include": "#strings" }, { "include": "#literals" }] 75 } 76 ] 77 }, 78 { 79 "comment": "topfind directives", 80 "begin": "^[[:space:]]*(#)[[:space:]]*(require|list|camlp4o|camlp4r|predicates|thread)", 81 "end": "$", 82 "beginCaptures": { 83 "1": { "name": "keyword.other.ocaml" }, 84 "2": { "name": "keyword.other.ocaml" } 85 }, 86 "patterns": [{ "include": "#strings" }] 87 }, 88 { 89 "comment": "cppo directives", 90 "begin": "^[[:space:]]*(#)[[:space:]]*(define|undef|ifdef|ifndef|if|else|elif|endif|include|warning|error|ext|endext)", 91 "end": "$", 92 "beginCaptures": { 93 "1": { "name": "keyword.other.ocaml" }, 94 "2": { "name": "keyword.other.ocaml" } 95 }, 96 "patterns": [ 97 { "name": "keyword.other.ocaml", "match": "\\b(defined)\\b" }, 98 { "name": "keyword.other.ocaml", "match": "\\\\" }, 99 { "include": "#comments" }, 100 { "include": "#strings" }, 101 { "include": "#characters" }, 102 { "include": "#keywords" }, 103 { "include": "#operators" }, 104 { "include": "#literals" }, 105 { "include": "#types" }, 106 { "include": "#identifiers" } 107 ] 108 } 109 ] 110 }, 111 112 "comments": { 113 "patterns": [ 114 { 115 "comment": "empty comment", 116 "name": "comment.block.ocaml", 117 "match": "\\(\\*\\*\\)" 118 }, 119 { 120 "comment": "ocamldoc comment", 121 "name": "comment.doc.ocaml", 122 "begin": "\\(\\*\\*(?!\\*)", 123 "end": "\\*\\)", 124 "patterns": [ 125 { "include": "source.ocaml.ocamldoc#markup" }, 126 { "include": "#strings-in-comments" }, 127 { "include": "#comments" } 128 ] 129 }, 130 { 131 "comment": "Cinaps comment", 132 "begin": "\\(\\*\\$", 133 "end": "\\*\\)", 134 "beginCaptures": [{ "name": "comment.cinaps.ocaml" }], 135 "endCaptures": [{ "name": "comment.cinaps.ocaml" }], 136 "patterns": [{ "include": "$self" }] 137 }, 138 { 139 "comment": "block comment", 140 "name": "comment.block.ocaml", 141 "begin": "\\(\\*", 142 "end": "\\*\\)", 143 "patterns": [{ "include": "#strings-in-comments" }, { "include": "#comments" }] 144 } 145 ] 146 }, 147 148 "strings-in-comments": { 149 "patterns": [ 150 { 151 "comment": "char literal", 152 "match": "'(\\\\)?.'" 153 }, 154 { 155 "comment": "string literal", 156 "begin": "\"", 157 "end": "\"", 158 "patterns": [{ "match": "\\\\\\\\" }, { "match": "\\\\\"" }] 159 }, 160 { 161 "comment": "quoted string literal", 162 "begin": "\\{([[:lower:]_]*)\\|", 163 "end": "\\|\\1\\}" 164 } 165 ] 166 }, 167 168 "strings": { 169 "patterns": [ 170 { 171 "comment": "quoted string literal", 172 "name": "string.quoted.braced.ocaml", 173 "begin": "\\{(%%?[[:alpha:]_][[:word:]']*(\\.[[:alpha:]_][[:word:]']*)*[[:space:]]*)?([[:lower:]_]*)\\|", 174 "end": "\\|\\3\\}", 175 "beginCaptures": { 176 "1": { "name": "keyword.other.extension.ocaml" } 177 } 178 }, 179 { 180 "comment": "string literal", 181 "name": "string.quoted.double.ocaml", 182 "begin": "\"", 183 "end": "\"", 184 "patterns": [ 185 { 186 "comment": "escaped newline", 187 "name": "constant.character.escape.ocaml", 188 "match": "\\\\$" 189 }, 190 { 191 "comment": "escaped backslash", 192 "name": "constant.character.escape.ocaml", 193 "match": "\\\\\\\\" 194 }, 195 { 196 "comment": "escaped quote or whitespace", 197 "name": "constant.character.escape.ocaml", 198 "match": "\\\\[\"'ntbr ]" 199 }, 200 { 201 "comment": "character from decimal ASCII code", 202 "name": "constant.character.escape.ocaml", 203 "match": "\\\\[[:digit:]]{3}" 204 }, 205 { 206 "comment": "character from hexadecimal ASCII code", 207 "name": "constant.character.escape.ocaml", 208 "match": "\\\\x[[:xdigit:]]{2}" 209 }, 210 { 211 "comment": "character from octal ASCII code", 212 "name": "constant.character.escape.ocaml", 213 "match": "\\\\o[0-3][0-7]{2}" 214 }, 215 { 216 "comment": "unicode character escape sequence", 217 "name": "constant.character.escape.ocaml", 218 "match": "\\\\u\\{[[:xdigit:]]{1,6}\\}" 219 }, 220 { 221 "comment": "printf format string", 222 "name": "constant.character.printf.ocaml", 223 "match": "%[-0+ #]*([[:digit:]]+|\\*)?(.([[:digit:]]+|\\*))?[lLn]?[diunlLNxXosScCfFeEgGhHBbat!%@,]" 224 }, 225 { 226 "comment": "unknown escape sequence", 227 "name": "invalid.illegal.unknown-escape.ocaml", 228 "match": "\\\\." 229 } 230 ] 231 } 232 ] 233 }, 234 235 "characters": { 236 "patterns": [ 237 { 238 "comment": "character literal from escaped backslash", 239 "name": "string.quoted.single.ocaml", 240 "match": "'(\\\\\\\\)'", 241 "captures": { "1": { "name": "constant.character.escape.ocaml" } } 242 }, 243 { 244 "comment": "character literal from escaped quote or whitespace", 245 "name": "string.quoted.single.ocaml", 246 "match": "'(\\\\[\"'ntbr ])'", 247 "captures": { "1": { "name": "constant.character.escape.ocaml" } } 248 }, 249 { 250 "comment": "character literal from decimal ASCII code", 251 "name": "string.quoted.single.ocaml", 252 "match": "'(\\\\[[:digit:]]{3})'", 253 "captures": { "1": { "name": "constant.character.escape.ocaml" } } 254 }, 255 { 256 "comment": "character literal from hexadecimal ASCII code", 257 "name": "string.quoted.single.ocaml", 258 "match": "'(\\\\x[[:xdigit:]]{2})'", 259 "captures": { "1": { "name": "constant.character.escape.ocaml" } } 260 }, 261 { 262 "comment": "character literal from octal ASCII code", 263 "name": "string.quoted.single.ocaml", 264 "match": "'(\\\\o[0-3][0-7]{2})'", 265 "captures": { "1": { "name": "constant.character.escape.ocaml" } } 266 }, 267 { 268 "comment": "character literal from unknown escape sequence", 269 "name": "string.quoted.single.ocaml", 270 "match": "'(\\\\.)'", 271 "captures": { 272 "1": { "name": "invalid.illegal.unknown-escape.ocaml" } 273 } 274 }, 275 { 276 "comment": "character literal", 277 "name": "string.quoted.single.ocaml", 278 "match": "'.'" 279 } 280 ] 281 }, 282 283 "attributes": { 284 "begin": "\\[(@|@@|@@@)[[:space:]]*([[:alpha:]_]+(\\.[[:word:]']+)*)", 285 "end": "\\]", 286 "beginCaptures": { 287 "1": { "name": "keyword.operator.attribute.ocaml" }, 288 "2": { 289 "name": "keyword.other.attribute.ocaml", 290 "patterns": [ 291 { 292 "name": "keyword.other.ocaml punctuation.other.period punctuation.separator.period", 293 "match": "\\." 294 } 295 ] 296 } 297 }, 298 "patterns": [{ "include": "$self" }] 299 }, 300 301 "extensions": { 302 "begin": "\\[(%|%%)[[:space:]]*([[:alpha:]_]+(\\.[[:word:]']+)*)", 303 "end": "\\]", 304 "beginCaptures": { 305 "1": { "name": "keyword.operator.extension.ocaml" }, 306 "2": { 307 "name": "keyword.other.extension.ocaml", 308 "patterns": [ 309 { 310 "name": "keyword.other.ocaml punctuation.other.period punctuation.separator.period", 311 "match": "\\." 312 } 313 ] 314 } 315 }, 316 "patterns": [{ "include": "$self" }] 317 }, 318 319 "modules": { 320 "patterns": [ 321 { 322 "begin": "\\b(sig)\\b", 323 "end": "\\b(end)\\b", 324 "beginCaptures": [{ "name": "keyword.other.ocaml" }], 325 "endCaptures": [{ "name": "keyword.other.ocaml" }], 326 "patterns": [{ "include": "source.ocaml.interface" }] 327 }, 328 { 329 "begin": "\\b(struct)\\b", 330 "end": "\\b(end)\\b", 331 "beginCaptures": [{ "name": "keyword.other.ocaml" }], 332 "endCaptures": [{ "name": "keyword.other.ocaml" }], 333 "patterns": [{ "include": "$self" }] 334 } 335 ] 336 }, 337 338 "bindings": { 339 "patterns": [ 340 { 341 "comment": "for loop", 342 "match": "\\b(for)[[:space:]]+([[:lower:]_][[:word:]']*)", 343 "captures": { 344 "1": { "name": "keyword.ocaml" }, 345 "2": { "name": "entity.name.function.binding.ocaml" } 346 } 347 }, 348 { 349 "comment": "local open/exception/module", 350 "match": "\\b(let)[[:space:]]+(open|exception|module)\\b(?!')", 351 "captures": { 352 "1": { "name": "keyword.ocaml" }, 353 "2": { "name": "keyword.ocaml" } 354 } 355 }, 356 { 357 "comment": "let expression", 358 "match": "\\b(let)[[:space:]]+(?!lazy\\b(?!'))(rec[[:space:]]+)?(?!rec\\b(?!'))([[:lower:]_][[:word:]']*)(?![[:word:]'])[[:space:]]*(?!,|::|[[:space:]])", 359 "captures": { 360 "1": { "name": "keyword.ocaml" }, 361 "2": { "name": "keyword.ocaml" }, 362 "3": { "name": "entity.name.function.binding.ocaml" } 363 } 364 }, 365 { 366 "comment": "using binding operators", 367 "match": "\\b(let|and)([$&*+\\-/=>@^|<][!?$&*+\\-/=>@^|%:]*)[[:space:]]*(?!lazy\\b(?!'))([[:lower:]_][[:word:]']*)(?![[:word:]'])[[:space:]]*(?!,|::|[[:space:]])", 368 "captures": { 369 "1": { "name": "keyword.ocaml" }, 370 "2": { "name": "keyword.ocaml" }, 371 "3": { "name": "entity.name.function.binding.ocaml" } 372 } 373 }, 374 { 375 "comment": "first class module packing", 376 "match": "\\([[:space:]]*(val)[[:space:]]+([[:lower:]_][[:word:]']*)", 377 "captures": { 378 "1": { "name": "keyword.ocaml" }, 379 "2": { "patterns": [{ "include": "$self" }] } 380 } 381 }, 382 { 383 "comment": "locally abstract types", 384 "match": "(?:\\(|(:))[[:space:]]*(type)((?:[[:space:]]+[[:lower:]_][[:word:]']*)+)", 385 "captures": { 386 "1": { 387 "name": "keyword.other.ocaml punctuation.other.colon punctuation.colon" 388 }, 389 "2": { "name": "keyword.ocaml" }, 390 "3": { "name": "entity.name.function.binding.ocaml" } 391 } 392 }, 393 { 394 "comment": "optional labeled argument with type", 395 "begin": "(\\?)\\([[:space:]]*([[:lower:]_][[:word:]']*)", 396 "beginCaptures": { 397 "1": { "name": "variable.parameter.optional.ocaml" }, 398 "2": { "name": "variable.parameter.optional.ocaml" } 399 }, 400 "end": "\\)", 401 "patterns": [{ "include": "$self" }] 402 }, 403 { 404 "comment": "labeled argument with type", 405 "begin": "(~)\\([[:space:]]*([[:lower:]_][[:word:]']*)", 406 "beginCaptures": { 407 "1": { "name": "variable.parameter.labeled.ocaml" }, 408 "2": { "name": "variable.parameter.labeled.ocaml" } 409 }, 410 "end": "\\)", 411 "patterns": [{ "include": "$self" }] 412 }, 413 { "include": "source.ocaml.interface#bindings" } 414 ] 415 }, 416 417 "operators": { 418 "patterns": [ 419 { 420 "comment": "binding operator", 421 "name": "keyword.ocaml", 422 "match": "\\b(let|and)[$&*+\\-/=>@^|<][!?$&*+\\-/=>@^|%:]*" 423 }, 424 { 425 "comment": "infix symbol", 426 "name": "keyword.operator.ocaml", 427 "match": "[$&*+\\-/=>@^%<][~!?$&*+\\-/=>@^|%<:.]*" 428 }, 429 { 430 "comment": "infix symbol that begins with vertical bar", 431 "name": "keyword.operator.ocaml", 432 "match": "\\|[~!?$&*+\\-/=>@^|%<:.]+" 433 }, 434 { 435 "comment": "vertical bar", 436 "name": "keyword.other.ocaml", 437 "match": "(?<!\\[)(\\|)(?!\\])" 438 }, 439 { 440 "comment": "infix symbol", 441 "name": "keyword.operator.ocaml", 442 "match": "#[~!?$&*+\\-/=>@^|%<:.]+" 443 }, 444 { 445 "comment": "prefix symbol", 446 "name": "keyword.operator.ocaml", 447 "match": "![~!?$&*+\\-/=>@^|%<:.]*" 448 }, 449 { 450 "comment": "prefix symbol", 451 "name": "keyword.operator.ocaml", 452 "match": "[?~][~!?$&*+\\-/=>@^|%<:.]+" 453 }, 454 { 455 "comment": "named operator", 456 "name": "keyword.operator.ocaml", 457 "match": "\\b(or|mod|land|lor|lxor|lsl|lsr|asr)\\b" 458 }, 459 { 460 "comment": "method invocation", 461 "name": "keyword.other.ocaml", 462 "match": "#" 463 }, 464 { 465 "comment": "type annotation", 466 "name": "keyword.other.ocaml punctuation.other.colon punctuation.colon", 467 "match": ":" 468 }, 469 { 470 "comment": "field accessor", 471 "name": "keyword.other.ocaml punctuation.other.period punctuation.separator.period", 472 "match": "\\." 473 }, 474 { 475 "comment": "semicolon separator", 476 "name": "keyword.other.ocaml punctuation.separator.terminator punctuation.separator.semicolon", 477 "match": ";" 478 }, 479 { 480 "comment": "comma separator", 481 "name": "keyword.other.ocaml punctuation.comma punctuation.separator.comma", 482 "match": "," 483 } 484 ] 485 }, 486 487 "keywords": { 488 "patterns": [ 489 { 490 "comment": "reserved ocaml keyword", 491 "name": "keyword.other.ocaml", 492 "match": "\\b(and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|virtual|when|while|with)\\b(?!')" 493 } 494 ] 495 }, 496 497 "literals": { 498 "patterns": [ 499 { 500 "comment": "boolean literal", 501 "name": "constant.language.boolean.ocaml", 502 "match": "\\b(true|false)\\b" 503 }, 504 505 { 506 "comment": "floating point decimal literal with exponent", 507 "name": "constant.numeric.decimal.float.ocaml", 508 "match": "\\b([[:digit:]][[:digit:]_]*(\\.[[:digit:]_]*)?[eE][+-]?[[:digit:]][[:digit:]_]*[g-zG-Z]?)\\b" 509 }, 510 { 511 "comment": "floating point decimal literal", 512 "name": "constant.numeric.decimal.float.ocaml", 513 "match": "\\b([[:digit:]][[:digit:]_]*)(\\.[[:digit:]_]*[g-zG-Z]?\\b|\\.)" 514 }, 515 { 516 "comment": "floating point hexadecimal literal with exponent part", 517 "name": "constant.numeric.hexadecimal.float.ocaml", 518 "match": "\\b((0x|0X)[[:xdigit:]][[:xdigit:]_]*(\\.[[:xdigit:]_]*)?[pP][+-]?[[:digit:]][[:digit:]_]*[g-zG-Z]?)\\b" 519 }, 520 { 521 "comment": "floating point hexadecimal literal", 522 "name": "constant.numeric.hexadecimal.float.ocaml", 523 "match": "\\b((0x|0X)[[:xdigit:]][[:xdigit:]_]*)(\\.[[:xdigit:]_]*[g-zG-Z]?\\b|\\.)" 524 }, 525 526 { 527 "comment": "decimal integer literal", 528 "name": "constant.numeric.decimal.integer.ocaml", 529 "match": "\\b([[:digit:]][[:digit:]_]*[lLng-zG-Z]?)\\b" 530 }, 531 { 532 "comment": "hexadecimal integer literal", 533 "name": "constant.numeric.hexadecimal.integer.ocaml", 534 "match": "\\b((0x|0X)[[:xdigit:]][[:xdigit:]_]*[lLng-zG-Z]?)\\b" 535 }, 536 { 537 "comment": "octal integer literal", 538 "name": "constant.numeric.octal.integer.ocaml", 539 "match": "\\b((0o|0O)[0-7][0-7_]*[lLng-zG-Z]?)\\b" 540 }, 541 542 { 543 "comment": "binary integer literal", 544 "name": "constant.numeric.binary.integer.ocaml", 545 "match": "\\b((0b|0B)[0-1][0-1_]*[lLng-zG-Z]?)\\b" 546 }, 547 548 { 549 "comment": "unit literal", 550 "name": "constant.language.unit.ocaml", 551 "match": "\\(\\)" 552 }, 553 { 554 "comment": "parentheses", 555 "begin": "\\(", 556 "end": "\\)", 557 "patterns": [{ "include": "$self" }] 558 }, 559 560 { 561 "comment": "empty array", 562 "name": "constant.language.array.ocaml", 563 "match": "\\[\\|\\|\\]" 564 }, 565 { 566 "comment": "array", 567 "begin": "\\[\\|", 568 "end": "\\|\\]", 569 "patterns": [{ "include": "$self" }] 570 }, 571 572 { 573 "comment": "empty list", 574 "name": "constant.language.list.ocaml", 575 "match": "\\[\\]" 576 }, 577 { 578 "comment": "list", 579 "begin": "\\[", 580 "end": "]", 581 "patterns": [{ "include": "$self" }] 582 }, 583 { 584 "comment": "braces", 585 "begin": "\\{", 586 "end": "\\}", 587 "patterns": [{ "include": "$self" }] 588 } 589 ] 590 }, 591 592 "types": { 593 "patterns": [ 594 { 595 "comment": "type parameter", 596 "name": "storage.type.ocaml", 597 "match": "'[[:alpha:]][[:word:]']*\\b|'_\\b" 598 }, 599 { 600 "comment": "weak type parameter", 601 "name": "storage.type.weak.ocaml", 602 "match": "'_[[:alpha:]][[:word:]']*\\b" 603 }, 604 { 605 "comment": "builtin type", 606 "name": "support.type.ocaml", 607 "match": "\\b(unit|bool|int|int32|int64|nativeint|float|char|bytes|string)\\b" 608 } 609 ] 610 }, 611 612 "identifiers": { 613 "patterns": [ 614 { 615 "comment": "wildcard underscore", 616 "name": "constant.language.ocaml", 617 "match": "\\b_\\b" 618 }, 619 { 620 "comment": "capital identifier for constructor, exception, or module", 621 "name": "constant.language.capital-identifier.ocaml", 622 "match": "\\b[[:upper:]][[:word:]']*('|\\b)" 623 }, 624 { 625 "comment": "lowercase identifier", 626 "name": "source.ocaml", 627 "match": "\\b[[:lower:]_][[:word:]']*('|\\b)" 628 }, 629 { 630 "comment": "polymorphic variant tag", 631 "name": "constant.language.polymorphic-variant.ocaml", 632 "match": "\\`[[:alpha:]][[:word:]']*\\b" 633 }, 634 { 635 "comment": "empty list (can be used as a constructor)", 636 "name": "constant.language.list.ocaml", 637 "match": "\\[\\]" 638 } 639 ] 640 } 641 } 642 } 643