From 5d8f2c8526b59dc7d4495a5abee0e3d0c47e4f25 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Mon, 24 Aug 2020 07:53:16 +0300 Subject: [PATCH] [LIGO-13] Add CameLIGO and ReasonLIGO Problem: The previous version of the extension only supported PascaLIGO dialect. We need to add syntax highlighting and activation events for ReasonLIGO and CameLIGO. Solution: Add .tmlanguage.json files for ReasonLIGO and CameLIGO, add activation events. --- .../lsp/vscode-plugin/client/src/extension.ts | 1 + tools/lsp/vscode-plugin/package.json | 11 + .../syntaxes/ligo.tmLanguage.json | 221 +- .../syntaxes/mligo.configuration.json | 25 + .../syntaxes/mligo.tmLanguage.json | 252 ++ .../syntaxes/religo.tmLanguage.json | 2069 ++++++++++++++++- 6 files changed, 2442 insertions(+), 137 deletions(-) create mode 100644 tools/lsp/vscode-plugin/syntaxes/mligo.configuration.json create mode 100644 tools/lsp/vscode-plugin/syntaxes/mligo.tmLanguage.json diff --git a/tools/lsp/vscode-plugin/client/src/extension.ts b/tools/lsp/vscode-plugin/client/src/extension.ts index 81dc395fc..a3a7961f5 100644 --- a/tools/lsp/vscode-plugin/client/src/extension.ts +++ b/tools/lsp/vscode-plugin/client/src/extension.ts @@ -25,6 +25,7 @@ export function activate(context: ExtensionContext) { // Register the server for plain text documents documentSelector: [ { scheme: 'file', language: 'ligo' }, + { scheme: 'file', language: 'mligo' }, { scheme: 'file', language: 'religo' } ], synchronize: { diff --git a/tools/lsp/vscode-plugin/package.json b/tools/lsp/vscode-plugin/package.json index 7890ef574..191961276 100644 --- a/tools/lsp/vscode-plugin/package.json +++ b/tools/lsp/vscode-plugin/package.json @@ -31,6 +31,12 @@ "extensions": ["ligo"], "configuration": "./syntaxes/ligo.configuration.json" }, + { + "id": "mligo", + "aliases": ["CameLIGO"], + "extensions": ["mligo"], + "configuration": "./syntaxes/mligo.configuration.json" + }, { "id": "religo", "aliases": ["ReasonLIGO"], @@ -44,6 +50,11 @@ "scopeName": "source.ligo", "path": "./syntaxes/ligo.tmLanguage.json" }, + { + "language": "mligo", + "scopeName": "source.mligo", + "path": "./syntaxes/mligo.tmLanguage.json" + }, { "language": "religo", "scopeName": "source.religo", diff --git a/tools/lsp/vscode-plugin/syntaxes/ligo.tmLanguage.json b/tools/lsp/vscode-plugin/syntaxes/ligo.tmLanguage.json index b13d3c515..706d8b2a9 100644 --- a/tools/lsp/vscode-plugin/syntaxes/ligo.tmLanguage.json +++ b/tools/lsp/vscode-plugin/syntaxes/ligo.tmLanguage.json @@ -2,101 +2,194 @@ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", "name": "ligo", "patterns": [ - { "include": "#controlkeywords" }, - { "include": "#function" }, - { "include": "#strings" }, + { "include": "#string" }, + { "include": "#single-quotes" }, { "include": "#comment" }, - { "include": "#multilineComment" }, - { "include": "#singlequotes" }, - { "include": "#type" }, - { "include": "#typeDeclaration" }, - { "include": "#otherkeywords" }, - { "include": "#variableInit" }, - { "include": "#variableDeclaration" } + { "include": "#function" }, + { "include": "#binding" }, + { "include": "#type-annotation" }, + { "include": "#type-definition" }, + { "include": "#control-keywords" }, + { "include": "#other-keywords" }, + { "include": "#function-application" }, + { "include": "#identifiers" } ], "repository": { - "controlkeywords": { - "patterns": [{ - "name": "keyword.control.ligo", - "match": "\\b(if|while|for|return|nil|remove|from|else|then|None|Some|True|False|Unit|skip)\\b" - }] - }, - "otherkeywords": { - "patterns": [{ - "name": "keyword.other.ligo", - "match": "\\b(case|with|is|function|var|const|type|end|begin|block|sender|source|amount|balance|now)\\b" - }] - }, "function": { + "begin": "\\b(recursive\\s+)?(function)\\s+([a-zA-Z_]\\w*)\\b", + "beginCaptures": { + "1": { "name": "keyword.other.recursive.ligo" }, + "2": { "name": "keyword.other.function.ligo" }, + "3": { "name": "entity.name.function" } + }, + "end": "\\b(is)\\b", + "endCaptures": { + "1": { "name": "keyword.other.is.ligo"} + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#type-annotation" }, + { "include": "#binding" } + ] + }, + + "binding": { + "begin": "\\b(var|const)\\s+([a-zA-Z_]\\w*)\\b", + "end": "([=),;]|:=)", + "beginCaptures": { + "1": { "name": "keyword.other.binding.ligo" }, + "2": { "name": "entity.name.variable"} + }, + "endCaptures": { + "1": { "name": "keyword.operator.eq.ligo"} + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#type-annotation" } + ] + }, + + "type-annotation": { + "begin": "(:)\\s*", + "beginCaptures": { + "1": { "name": "keyword.operator.type.ligo" } + }, + "end": "(?:\\||(?=[;)=}\\]]|\\bis\\b|:=)|$)", + "patterns": [ + { "include": "#comment" }, + { "include": "#type-expression" } + ] + }, + + "type-expression": { "patterns": [ { - "name": "entity.name.function.ligo", - "match": "(?!with\\b)\\b\\w+ ?(?=\\()" + "begin": "\\(", + "end": "\\)", + "patterns": [ + { "include": "#comment" }, + { "include": "#type-expression" } + ] + }, + { + "match": "((?:(?!\\bis\\b|:=)[^=()|;}\\]])*)", + "captures": { + "1": { "name": "entity.name.type.ligo" } + } } ] }, - "strings": { + + "type-definition": { + "begin": "\\b(type)\\s+([a-zA-Z_]\\w*)\\s+(is)\\b", + "beginCaptures": { + "1": { "name": "keyword.other.typedef.ligo" }, + "2": { "name": "entity.name.type.ligo" }, + "3": { "name": "keyword.other.is.ligo" } + }, + "end": "(?=\\b(?:function|type||const|var)\\b)", + "patterns": [ + { "include": "#comment" }, + { "include": "#struct-type" }, + { "include": "#sum-type" } + ] + }, + + "struct-type": { + "begin": "\\b(record)\\s*\\[", + "beginCaptures": { + "1": { "name": "keyword.other.record.ligo" } + }, + "end": "\\]", + "patterns": [ + { "include": "#comment" }, + { "include": "#identifiers" }, + { "include": "#type-annotation" } + ] + }, + + "sum-type": { + "begin": "\\b([a-zA-Z_]\\w*)\\s+(of)", + "beginCaptures": { + "1": { "name": "entity.name.function.ligo" }, + "2": { "name": "keyword.other.of.ligo" } + }, + "end": "(\\||\\blet\\b|\\btype\\b)", + "patterns": [ + { "include": "#type-expression" } + ] + }, + + "string": { "name": "string.quoted.double.ligo", "begin": "\"", "end": "\"", - "patterns": [ - { + "patterns": [{ "name": "constant.character.escape.ligo", "match": "\\\\." - } - ] + }] }, - "singlequotes" : { + + "single-quotes" : { "name": "string.quoted.single.ligo", "begin": "\\'", "end": "\\'", "patterns" : [] }, + + "comment": { "patterns": [ { "name": "comment.line.double-slash.ligo", "match": "(//.*)" - } - ] - }, - "multilineComment" : { - "name" : "comment.line.double-slash.ligo", - "begin" : "\\(\\*", - "end" : "\\*\\)", - "patterns" : [] - }, - "type" : { - "patterns" : [ + }, { - "name" : "support.type.ligo", - "match": "\\b(bool|int|unit|string|nat|tez|map|timestamp|signature|key|big_map|list|set|record|address|option)\\b" + "name" : "comment.line.double-slash.ligo", + "begin" : "\\(\\*", + "end" : "\\*\\)", + "patterns" : [] } ] }, - "typeDeclaration" : { - "patterns" : [ - { - "name" : "support.type.ligo", - "match": "\\w+ ?(?= is )" - } - ] + + "list-cons": { + "match": "::", + "name": "keyword.operator.cons.ligo" }, - "variableInit" : { - "patterns" : [ - { - "name" : "support.variable.ligo", - "match": "\\w+ ?(?=\\:\\=)" - } - ] + + "control-keywords": { + "name": "keyword.control.ligo", + "match": "\\b(case|of|if|then|else|for|to|skip|assert|failwith)\\b" }, - "variableDeclaration" : { - "patterns" : [ - { - "name" : "support.variable.ligo", - "match": "\\w+ ?(?=\\:)" - } - ] + + "other-keywords": { + "name": "keyword.other.ligo", + "match": "\\b(block|with|begin|end|record)\\b" + }, + + "numeric-literals": { + "name": "constant.numeric.ligo", + "match": "\\b\\d+" + }, + + "operators": { + "name": "keyword.operator.other.ligo", + "match": "([-+*/])" + }, + + "function-application": { + "match": "\\b([a-zA-Z_]\\w*)\\s+\\(", + "captures": { + "1": { "name": "entity.name.function" } + } + }, + + "identifiers": { + "match": "\\b([a-zA-Z_]\\w*)\\b", + "captures": { + "1": { "name": "entity.name.variable" } + } } }, "scopeName": "source.ligo" diff --git a/tools/lsp/vscode-plugin/syntaxes/mligo.configuration.json b/tools/lsp/vscode-plugin/syntaxes/mligo.configuration.json new file mode 100644 index 000000000..9e0e35fff --- /dev/null +++ b/tools/lsp/vscode-plugin/syntaxes/mligo.configuration.json @@ -0,0 +1,25 @@ +{ + "comments": { + "lineComment": "//", + "blockComment": [ "(*", "*)" ] + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +} diff --git a/tools/lsp/vscode-plugin/syntaxes/mligo.tmLanguage.json b/tools/lsp/vscode-plugin/syntaxes/mligo.tmLanguage.json new file mode 100644 index 000000000..aed09e1f4 --- /dev/null +++ b/tools/lsp/vscode-plugin/syntaxes/mligo.tmLanguage.json @@ -0,0 +1,252 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "mligo", + "patterns": [ + { "include": "#string" }, + { "include": "#single-quotes" }, + { "include": "#comment" }, + { "include": "#list-cons" }, + { "include": "#let-binding" }, + { "include": "#lambda" }, + { "include": "#type-definition" }, + { "include": "#type-annotation" }, + { "include": "#control-keywords" }, + { "include": "#other-keywords" }, + { "include": "#numeric-literals" }, + { "include": "#operators" }, + { "include": "#function-application" }, + { "include": "#identifiers" } + ], + "repository": { + "let-binding": { + "begin": "\\b(let)\\b", + "end": "(\\=)", + "beginCaptures": { + "1": { "name": "keyword.other.let-binding.mligo" } + }, + "endCaptures": { + "1": { "name": "keyword.operator.eq.mligo"} + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#let-rec" }, + { "include": "#let-function" }, + { "include": "#let-constant" } + ] + }, + + "let-rec": { + "match": "\\b(rec)\\b", + "name": "keyword.other.recursive.mligo" + }, + + "let-function": { + "begin": "([a-zA-Z_]\\w*)?\\b(?=\\s*\\()", + "beginCaptures": { + "1": { "name": "entity.name.function.mligo" } + }, + "end": "(?=\\=)", + "patterns": [ + { "include": "#comment" }, + { "include": "#parenthesized-definition" }, + { "include": "#type-annotation" } + ] + }, + + "parenthesized-definition": { + "begin": "\\(", + "beginCaptures": { + "1": { "name": "keyword.operator.parenthesis.mligo" } + }, + "end": "\\)", + "endCaptures": { + "1": { "name": "keyword.operator.parenthesis.mligo" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#names-tuple" }, + { "include": "#type-annotation" } + ] + }, + + "names-tuple": { + "begin": "(?<=\\()", + "end": "(?=:)", + "patterns": [ + { "include": "#comment" }, + { "include": "#names-tuple-name" } + ] + }, + + "names-tuple-name": { + "match": "(?:([a-zA-Z_]\\w*)(?=\\s*[,:]))+", + "name": "support.variable.parameter.mligo" + }, + + "type-annotation": { + "begin": "(:)\\s*", + "beginCaptures": { + "1": { "name": "keyword.operator.type.mligo" } + }, + "end": "(?:[;|]|(?=[)=}])|$)", + "patterns": [ + { "include": "#comment" }, + { "include": "#type-expression" } + ] + }, + + "type-expression": { + "patterns": [ + { + "begin": "\\(", + "end": "\\)", + "patterns": [ + { "include": "#comment" }, + { "include": "#type-expression" } + ] + }, + { + "match": "([^=()|;}]*)", + "captures": { + "1": { "name": "entity.name.type.mligo" } + } + } + ] + }, + + "let-constant": { + "begin": "([a-zA-Z_]\\w*)\\b(?!\\s*\\()", + "beginCaptures": { + "1": { "name": "support.variable.mligo" } + }, + "end": "(?=\\=)", + "patterns": [ + { "include": "#comment" }, + { "include": "#type-annotation" } + ] + }, + + "lambda": { + "begin": "\\b(fun)\\b", + "beginCaptures": { + "1": { "name": "keyword.other.lambda.mligo" } + }, + "end": "(->)", + "endCaptures": { + "1": { "name": "keyword.operator.lambda.mligo"} + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#parenthesized-definition" } + ] + }, + + "type-definition": { + "begin": "\\b(type)\\s+([a-zA-Z_]\\w*)\\b", + "beginCaptures": { + "1": { "name": "keyword.other.typedef.mligo" }, + "2": { "name": "entity.name.type.mligo" } + }, + "end": "(?=(?:\\blet\\b|\\btype\\b))", + "patterns": [ + { "include": "#comment" }, + { "include": "#struct-type" }, + { "include": "#sum-type" } + ] + }, + + "struct-type": { + "begin": "\\{", + "end": "\\}", + "patterns": [ + { "include": "#comment" }, + { "include": "#names-tuple-name" }, + { "include": "#type-annotation" } + ] + }, + + "sum-type": { + "begin": "\\b([a-zA-Z_]\\w*)\\s+(of)", + "beginCaptures": { + "1": { "name": "entity.name.function.mligo" }, + "2": { "name": "keyword.other.of.mligo" } + }, + "end": "(\\||\\blet\\b|\\btype\\b)", + "patterns": [ + { "include": "#type-expression" } + ] + }, + + "string": { + "name": "string.quoted.double.mligo", + "begin": "\"", + "end": "\"", + "patterns": [{ + "name": "constant.character.escape.mligo", + "match": "\\\\." + }] + }, + "single-quotes" : { + "name": "string.quoted.single.mligo", + "begin": "\\'", + "end": "\\'", + "patterns" : [] + }, + + + "comment": { + "patterns": [ + { + "name": "comment.line.double-slash.mligo", + "match": "(//.*)" + }, + { + "name" : "comment.line.double-slash.mligo", + "begin" : "\\(\\*", + "end" : "\\*\\)", + "patterns" : [] + } + ] + }, + + "list-cons": { + "match": "::", + "name": "keyword.operator.cons.mligo" + }, + + "control-keywords": { + "name": "keyword.control.mligo", + "match": "\\b(match|with|if|then|else|assert|failwith)\\b" + }, + + "other-keywords": { + "name": "keyword.other.mligo", + "match": "\\b(in|begin|end)\\b" + }, + + "numeric-literals": { + "name": "constant.numeric.mligo", + "match": "\\b\\d+" + }, + + "operators": { + "name": "keyword.operator.other.mligo", + "match": "([-+*/])" + }, + + "function-application": { + "comment": "We need a negative lookahead here because instead of matching the first rule, TM picks the _longest match_. Without the lookahead, this rule conflicts with #let-binding and #control-keywords.", + "match": "(?<=(?:match|with|if|then|else|assert|in|begin|failwith) |->|^|[|=\\.(])\\s*((?!(?:match|with|if|then|else|assert|in|begin|end|let|type|fun|failwith)\\b)[a-zA-Z_]\\w*)\\s+(?=(\\d|[\\[('\"]|[a-zA-Z_]\\w*))", + "captures": { + "1": { "name": "entity.name.function" } + } + }, + "identifiers": { + "match": "\\b([a-zA-Z_]\\w*)\\b", + "captures": { + "1": { "name": "entity.name.variable" } + } + } + }, + "scopeName": "source.mligo" +} diff --git a/tools/lsp/vscode-plugin/syntaxes/religo.tmLanguage.json b/tools/lsp/vscode-plugin/syntaxes/religo.tmLanguage.json index 19108d6f5..db9ede3df 100644 --- a/tools/lsp/vscode-plugin/syntaxes/religo.tmLanguage.json +++ b/tools/lsp/vscode-plugin/syntaxes/religo.tmLanguage.json @@ -1,94 +1,2017 @@ { - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "religo", + "name": "ReasonLIGO", "scopeName": "source.religo", + "fileTypes": [ + "religo", + "rligo" + ], "patterns": [ - { "include": "#controlkeywords" }, - { "include": "#strings" }, - { "include": "#comment" }, - { "include": "#multilineComment" }, - { "include": "#singlequotes" }, - { "include": "#type" }, - { "include": "#typeDeclaration" }, - { "include": "#otherkeywords" }, - { "include": "#variableInit" }, - { "include": "#variableDeclaration" } + { "include": "#structure-expression-block-item" }, + { "include": "#value-expression" } ], "repository": { - "controlkeywords": { - "patterns": [{ - "name": "keyword.control.religo", - "match": "\\b(if|then|else|remove|from|None|Some|true|false|skip)\\b" - }] + "attribute": { + "begin": "(?=\\[(@{1,3})[[:space:]]*[[:alpha:]])", + "end": "\\]", + "patterns": [ + { + "begin": "\\[(@{1,3})", + "end": "(?=[^_\\.'[:word:]])", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#attribute-identifier" } + ] + }, + { "include": "#attribute-payload" } + ] + }, + "attribute-identifier": { + "patterns": [ + { + "match": "\\b([[:alpha:]][[:word:]]*)\\b[[:space:]]*(?:(\\.))", + "captures": { + "1": { "name": "support.class entity.name.class" }, + "2": { "name": "keyword.control.less" } + } + }, + { + "match": "\\b([[:alpha:]][[:word:]]*)\\b", + "name": "constant.language" + } + ] + }, + "attribute-payload": { + "patterns": [ + { + "begin": "(:)", + "end": "(?=\\])", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#structure-expression" }, + { "include": "#module-item-type" }, + { "include": "#type-expression" } + ] + }, + { + "begin": "([\\?])", + "end": "(?=\\])", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#pattern-guard" }, + { "include": "#pattern" } + ] + }, + { "include": "#structure-expression-block-item" }, + { "include": "#value-expression" } + ] + }, + + "comment": { + "name": "comment", + "patterns": [ + { "include": "#comment-block-doc" }, + { "include": "#comment-block" }, + { "include": "#comment-standard" } + ] + }, + "comment-block": { + "begin": "/\\*", + "end": "\\*/", + "name": "comment.block", + "patterns": [ + { "include": "#comment" } + ] + }, + "comment-standard": { + "begin": "//", + "end": "\n", + "name": "comment.standard", + "patterns": [ + { "include": "#comment" } + ] + }, + "comment-block-doc": { + "begin": "/\\*\\*(?!/)", + "end": "\\*/", + "name": "comment.block.documentation", + "patterns": [ + { "include": "#comment" } + ] + }, + "condition-lhs": { + "begin": "(?|~$\\\\])([\\?])(?![#\\-:!?.@*/&%^+<=>|~$\\\\])", + "end": "(?=[\\)])", + "beginCaptures": { + "1": { "name": "keyword.control variable.interpolation" } }, - "otherkeywords": { - "patterns": [{ - "name": "keyword.other.religo", - "match": "\\b(let|rec|switch|type|sender|source|amount|balance|now)\\b" - }] + "patterns": [ + { + "match": "(?:\\b|[[:space:]]+)([?])(?:\\b|[[:space:]]+)", + "name": "keyword.control variable.interpolation" + }, + { "include": "#value-expression" } + ] + }, + "extension-node": { + "begin": "(?=\\[(%{1,3})[[:space:]]*[[:alpha:]])", + "end": "\\]", + "patterns": [ + { + "begin": "\\[(%{1,3})", + "end": "(?=[^_\\.'[:word:]])", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#attribute-identifier" } + ] + }, + { "include": "#attribute-payload" } + ] + }, + "jsx": { + "patterns": [ + { "include": "#jsx-head" }, + { "include": "#jsx-tail" } + ] + }, + "jsx-attributes": { + "patterns": [ + { + "begin": "\\b([[:lower:]][[:word:]]*)\\b[[:space:]]*(=)", + "end": "(?[:lower:]])", + "comment": "meta.separator", + "beginCaptures": { + "1": { "name": "entity.other.attribute-name" }, + "2": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#value-expression-atomic-with-paths" } + ] + }, + { + "match": "(\\b([[:lower:]][[:word:]]*)\\b[[:space:]]*+)", + "captures": { + "1": { "comment": "meta.separator" }, + "2": { "name": "entity.other.attribute-name" } + } + } + ] + }, + "jsx-body": { + "begin": "((>))", + "end": "(?=))|(?=])[[:space:]]*+", + "comment": "meta.separator", + "patterns": [ + { + "match": "\\b[[:upper:]][[:word:]]*\\b", + "name": "entity.name.tag.inline.any.class" + }, + { + "match": "\\b[[:lower:]][[:word:]]*\\b", + "name": "entity.name.tag.inline.any.html" + } + ] + }, + { "include": "#jsx-attributes" }, + { "include": "#jsx-body" } + ] + }, + "jsx-tail": { + "begin": "\\G(/>)|()", + "applyEndPatternLast": true, + "comment": "meta.separator", + "beginCaptures": { + "1": { "name": "punctuation.definition.tag.end.js" }, + "2": { "name": "punctuation.definition.tag.begin.js" } + }, + "endCaptures": { + "1": { "name": "punctuation.definition.tag.end.js" } + }, + "patterns": [ + { + "match": "\\b[[:upper:]][[:word:]]*\\b", + "name": "entity.name.tag.inline.any.class" + }, + { + "match": "\\b[[:lower:]][[:word:]]*\\b", + "name": "entity.name.tag.inline.any.html" + } + ] + }, + "module-name-extended": { + "patterns": [ + { "include": "#module-name-simple" }, + { + "begin": "([\\(])", + "end": "([\\)])", + "captures": { + "1": { "name": "constant.language" } + }, + "patterns": [ + { "include": "#module-path-extended" } + ] + } + ] + }, + "module-name-simple": { + "match": "\\b[[:upper:]][[:word:]]*\\b", + "name": "support.class entity.name.class" + }, + "module-path-extended": { + "patterns": [ + { "include": "#module-name-extended" }, + { "include": "#comment" }, + { + "comment": "NOTE: end early to avoid too much reparsing", + "begin": "([\\.])", + "end": "(?<=[[:word:]\\)])|(?=[^\\.[:upper:]/])", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { + "begin": "(?<=[\\.])", + "end": "(?<=[[:word:]\\)])|(?=[^\\.[:upper:]/])", + "patterns": [ + { "include": "#comment" }, + { "include": "#module-name-extended" } + ] + } + ] + } + ] + }, + "module-path-extended-prefix": { + "begin": "(?=\\b[[:upper:]])", + "end": "([\\.])|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#module-path-extended" } + ] + }, + "module-path-simple": { + "patterns": [ + { "include": "#module-name-simple" }, + { "include": "#comment" }, + { + "comment": "NOTE: end early to avoid too much reparsing", + "begin": "([\\.])", + "end": "(?<=[[:word:]\\)])|(?=[^\\.[:upper:]/])", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { + "begin": "(?<=[\\.])", + "end": "(?<=[[:word:]\\)])|(?=[^\\.[:upper:]/])", + "patterns": [ + { "include": "#comment" }, + { "include": "#module-name-simple" } + ] + } + ] + } + ] + }, + "module-path-simple-prefix": { + "begin": "(?=\\b[[:upper:]])", + "end": "([\\.])|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#module-path-simple" } + ] + }, + "module-item-include": { + "begin": "\\b(include)\\b", + "end": "(;)|(?=}|\\b(class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|type|val)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.include" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#signature-expression" } + ] + }, + "module-item-let": { + "begin": "\\b(let)\\b", + "end": "(;)|(?=}|\\b(class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#module-item-let-value" } + ] + }, + "module-item-let-value": { + "patterns": [ + { "include": "#module-item-let-value-and" }, + { "include": "#module-item-let-value-rec" }, + { "include": "#module-item-let-value-bind-name-params-type-body" } + ] + }, + "module-item-let-value-and": { + "begin": "\\b(and)\\b", + "end": "(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "patterns": [ + { "include": "#module-item-let-value-bind-name-params-type-body" } + ] + }, + "module-item-let-value-bind-body": { + "begin": "(=>?)", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#value-expression" } + ] + }, + "module-item-let-value-bind-name-or-pattern": { + "begin": "(?<=[^[:word:]]and|^and|[^[:word:]]external|^external|[^[:word:]]let|^let|[^[:word:]]method|^method|[^[:word:]]rec|^rec)[[:space:]]*", + "end": "(?<=[^[:space:]])|(?=[[:space:]]|[;:}=]|\\b(and|as|class|constraint|exception|external|for|include|inherit|let|method|module|nonrec|open|private|rec|switch|try|type|val|while|with)\\b)", + "patterns": [ + { "include": "#comment" }, + { + "match": "\\b(?:([_][[:word:]]+)|([[:lower:]][[:word:]]*))\\b", + "captures": { + "1": { "name": "comment" }, + "2": { "name": "entity.name.variable.religo" } + } + }, + { "include": "#module-item-let-value-bind-parens-params" }, + { "include": "#pattern" } + ] + }, + "module-item-let-value-bind-name-params-type-body": { + "begin": "(?<=[^[:word:]]and|^and|[^[:word:]]external|^external|[^[:word:]]let|^let|[^[:word:]]method|^method|[^[:word:]]rec|^rec)", + "end": "(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { + "comment": "FIXME; hack for punned arguments", + "begin": "(::)", + "end": "(?<=[[:space:]])", + "beginCaptures": { + "1": { "name": "keyword.control" } + }, + "patterns": [ + { "include": "#pattern" }, + { + "begin": "(=)", + "end": "(\\?)|(?<=[^[:space:]=][[:space:]])(?=[[:space:]]*+[^\\.])", + "beginCaptures": { + "1": { "name": "keyword.control.eq.religo" } + }, + "endCaptures": { + "1": { "name": "storage.type.religo" } + }, + "patterns": [ + { "include": "#value-expression-atomic-with-paths" } + ] + } + ] + }, + { "include": "#module-item-let-value-bind-name-or-pattern" }, + { "include": "#module-item-let-value-bind-params-type" }, + { "include": "#module-item-let-value-bind-type" }, + { "include": "#module-item-let-value-bind-body" } + ] + }, + "module-item-let-value-bind-params-type": { + "begin": "(?=[^[:space:]:=])", + "end": "(?=[;}=]|\\b(class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { "include": "#comment" }, + { "include": "#module-item-let-value-param" }, + { + "begin": "(?]|[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { + "begin": "\\b(type)\\b", + "end": "([\\.])", + "beginCaptures": { + "1": { "name": "constant.language" } + }, + "endCaptures": { + "1": { "name": "entity.name.function" } + }, + "patterns": [ + { "include": "#pattern-variable" } + ] + }, + { "include": "#type-expression" } + ] + }, + "module-item-let-value-param": { + "patterns": [ + { "include": "#module-item-let-value-param-label" }, + { "include": "#module-item-let-value-param-type" }, + { "include": "#module-item-let-value-param-module" }, + { "include": "#pattern" } + ] + }, + "module-item-let-value-param-label": { + "patterns": [ + { + "begin": "(\\b[[:lower:]][[:word:]]*\\b)?[[:space:]]*(::)", + "end": "(?<=[[:space:]])", + "beginCaptures": { + "1": { "name": "entity.name.variable.religo" }, + "2": { "name": "keyword.control.religo" } + }, + "patterns": [ + { "include": "#pattern" }, + { + "begin": "(=)", + "end": "(\\?)|(?<=[^[:space:]=][[:space:]])(?=[[:space:]]*+[^\\.])", + "beginCaptures": { + "1": { "name": "keyword.control.less.religo" } + }, + "endCaptures": { + "1": { "name": "storage.type.religo" } + }, + "patterns": [ + { "include": "#value-expression-atomic-with-paths" } + ] + } + ] + } + ] + }, + "module-item-let-value-param-module": { + "comment": "FIXME: merge with pattern-parens", + "begin": "\\([[:space:]]*(?=\\b(module)\\b)", + "end": "\\)", + "patterns": [ + { + "begin": "\\b(module)\\b", + "end": "(?=\\))", + "beginCaptures": { + "1": { "name": "keyword.other.religo" } + }, + "patterns": [ + { + "match": "\\b[[:upper:]][[:word:]]*\\b", + "name": "support.class.religo" + } + ] + } + ] + }, + "module-item-let-value-param-type": { + "comment": "FIXME: merge with pattern-parens", + "begin": "\\((?=\\b(type)\\b)", + "end": "\\)", + "patterns": [ + { + "begin": "\\b(type)\\b", + "end": "(?=\\))", + "beginCaptures": { + "1": { "name": "keyword.other.religo" } + }, + "patterns": [ + { "include": "#pattern-variable" } + ] + } + ] + }, + "module-item-let-value-rec": { + "begin": "(?:\\G|^)[[:space:]]*\\b(rec)\\b", + "end": "(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.religo storage.modifier.religo" } + }, + "patterns": [ + { "include": "#module-item-let-value-bind-name-params-type-body" } + ] + }, + "module-item-open": { + "begin": "\\b(open)\\b", + "end": "(;)|(?=}|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.open" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#module-path-simple" } + ] + }, + "module-item-type": { + "comment": "FIXME: the semi-colon is optional so we can re-use this for hover, which does not print the trailing ;", + "begin": "\\b(type)\\b", + "end": "(;)|(?=[\\)}]|\\b(class|exception|external|include|inherit|let|method|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#module-item-type-and" }, + { "include": "#module-item-type-constraint" }, + { "include": "#module-item-type-bind" } + ] + }, + "module-item-type-and": { + "comment": "FIXME: the optional `type` is for module constraints", + "begin": "\\b(and)\\b([[:space:]]*type)?", + "end": "(?=[;\\)}]|\\b(class|exception|external|include|inherit|let|method|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.other" }, + "2": { "name": "constant.language" } + }, + "patterns": [ + { "include": "#module-item-type-bind-name-tyvars-body" } + ] + }, + "module-item-type-bind": { + "comment": "FIXME: only allow module paths before type variables", + "patterns": [ + { "include": "#module-item-type-bind-nonrec" }, + { "include": "#module-item-type-bind-name-tyvars-body" } + ] + }, + "module-item-type-bind-body": { + "comment": "FIXME: parsing", + "begin": "(\\+?=)", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#module-item-type-bind-body-item" } + ] + }, + "module-item-type-bind-body-item": { + "patterns": [ + { + "match": "(=)(?!>)|\\b(private)\\b", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "variable.other.class.js variable.interpolation storage.modifier" } + } + }, + { + "comment": "FIXME: specialized version of variant rule that also scans for (", + "match": "\\b([[:upper:]][[:word:]]*)\\b(?![[:space:]]*[\\.\\(])", + "captures": { + "1": { "name": "constant.language" } + } + }, + { + "begin": "(\\.\\.)", + "end": "(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + } + }, + { + "begin": "(\\|)(?![#\\-:!?.@*/&%^+<=>|~$\\\\])[[:space:]]*", + "end": "(?=[;\\)}]|\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\])|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#value-expression-constructor" }, + { + "match": "([:])|\\b(of)\\b", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "keyword.other" } + } + }, + { "include": "#type-expression" } + ] + }, + { + "comment": "FIXME: remove this once the pretty printer no longer outputs 'of'", + "match": "(:)|(\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))|\\b(of)\\b", + "captures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "2": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "3": { "name": "keyword.other" } + } + }, + { "include": "#type-expression" } + ] + }, + "module-item-type-bind-name-tyvars": { + "begin": "(?<=\\G|^|\\.)[[:space:]]*\\b([[:lower:]][[:word:]]*)\\b", + "end": "(?=\\+?=|[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "entity.name.variable" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#attribute" }, + { + "match": "_", + "name": "comment" + }, + { + "comment": "FIXME: add separate type-variable rule", + "match": "([+\\-])?(?:(_)|(')([[:lower:]][[:word:]]*)\\b)(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "2": { "name": "comment" }, + "3": { "name": "comment" }, + "4": { "name": "variable.parameter string.other.link variable.language" } + } + } + ] + }, + "module-item-type-bind-name-tyvars-body": { + "begin": "(?=(\\G|^)[[:space:]]*\\b[[:alpha:]])", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { "include": "#module-path-simple-prefix" }, + { "include": "#module-item-type-bind-name-tyvars" }, + { "include": "#module-item-type-bind-body" } + ] + }, + "module-item-type-bind-nonrec": { + "begin": "(?:\\G|^)[[:space:]]*\\b(nonrec)\\b", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control storage.modifier" } + }, + "patterns": [ + { "include": "#module-item-type-bind-name-tyvars-body" } + ] + }, + "module-item-type-constraint": { + "comment": "FIXME: proper parsing", + "begin": "\\b(constraint)\\b", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation storage.modifier" } + }, + "patterns": [ + { + "comment": "FIXME: add separate type-variable rule", + "match": "([+\\-])?(')([_[:lower:]][[:word:]]*)\\b(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "2": { "name": "comment" }, + "3": { "name": "variable.parameter string.other.link variable.language" } + } + }, + { + "match": "=", + "name": "keyword.control.less" + }, + { "include": "#type-expression" } + ] + }, + "object-item": { + "begin": "\\G|(;)", + "end": "(?=[;}]|\\b(class|constraint|exception|external|include|let|module|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [] + }, + "operator": { + "patterns": [ + { "include": "#operator-infix" }, + { "include": "#operator-prefix" } + ] + }, + "operator-infix": { + "patterns": [ + { + "match": ";", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" + }, + { "include": "#operator-infix-assign" }, + { "include": "#operator-infix-builtin" }, + { "include": "#operator-infix-custom" }, + { "comment": "#operator-infix-custom-hash" } + ] + }, + "operator-infix-assign": { + "match": "(?|~$\\\\])(=)(?![#\\-:!?.@*/&%^+<=>|~$\\\\])", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control.less" + }, + "operator-infix-builtin": { + "match": ":=", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control.less" + }, + "operator-infix-custom": { + "match": "(?:(?|~$\\\\])((<>))(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))|([#\\-@*/&%^+<=>$\\\\][#\\-:!?.@*/&%^+<=>|~$\\\\]*|[|][#\\-:!?.@*/&%^+<=>|~$\\\\]+)", + "captures": { + "1": { "comment": "meta.separator" }, + "2": { "name": "punctuation.definition.tag.begin.js" }, + "3": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + } + }, + "operator-infix-custom-hash": { + "match": "#[\\-:!?.@*/&%^+<=>|~$]+", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" + }, + "operator-prefix": { + "patterns": [ + { "include": "#operator-prefix-bang" }, + { "include": "#operator-prefix-label-token" } + ] + }, + "operator-prefix-bang": { + "match": "![\\-:!?.@*/&%^+<=>|~$]*", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" + }, + "operator-prefix-label-token": { + "match": "[?~][\\-:!?.@*/&%^+<=>|~$]+", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" + }, + "pattern": { + "patterns": [ + { "include": "#attribute" }, + { "include": "#comment" }, + { "include": "#pattern-atomic" }, + { + "match": "[[:space:]]*+(?:(\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))|\\b(as)\\b|(\\.\\.\\.?))[[:space:]]*+", + "captures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "2": { "name": "keyword.other" }, + "3": { "name": "keyword.control" } + } + } + ] + }, + "pattern-atomic": { + "patterns": [ + { + "match": "\\b(exception)\\b", + "name": "keyword.other" + }, + { "include": "#value-expression-literal" }, + { "include": "#module-path-simple-prefix" }, + { "include": "#pattern-list-or-array" }, + { "include": "#pattern-record" }, + { "include": "#pattern-variable" }, + { "include": "#pattern-parens" } + ] + }, + "pattern-guard": { + "begin": "\\b(when)\\b", + "end": "(?==>)", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "patterns": [ + { "include": "#value-expression" } + ] + }, + "pattern-list-or-array": { + "begin": "(\\[\\|?)(?![@%])", + "end": "(\\|?\\])", + "beginCaptures": { + "1": { "name": "constant.language" } + }, + "endCaptures": { + "1": { "name": "constant.language" } + }, + "patterns": [ + { "include": "#value-expression-literal-list-or-array-separator" }, + { "include": "#pattern" } + ] + }, + "pattern-parens": { + "begin": "(?=\\()", + "end": "\\)|(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { "include": "#pattern-parens-lhs" }, + { "include": "#type-annotation-rhs" } + ] + }, + "pattern-parens-lhs": { + "begin": "\\(|(,)", + "end": "(?=(?:[,:\\)]))|(?=[;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#pattern" } + ] + }, + "record-path": { + "begin": "\\b[[:lower:]][[:word:]]*\\b", + "end": "(?=[^[:space:]\\.])(?!/\\*)", + "patterns": [ + { "include": "#comment" }, + { "include": "#record-path-suffix" } + ] + }, + "record-path-suffix": { + "begin": "(\\.)", + "end": "(\\))|\\b([[:upper:]][[:word:]]*)\\b|\\b([[:lower:]][[:word:]]*)\\b|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "endCaptures": { + "1": { "name": "keyword.control" }, + "2": { "name": "support.class entity.name.class" }, + "3": { "name": "markup.inserted constant.language support.property-value entity.name.filename" } + }, + "patterns": [ + { "include": "#comment" }, + { + "begin": "([\\(])", + "end": "(?=[\\)])", + "beginCaptures": { + "1": { "name": "keyword.control" } + }, + "patterns": [ + { "include": "#comment" }, + { + "match": "\\b([[:lower:]][[:word:]]*)\\b(?=[^\\)]*([\\.]))", + "captures": { + "1": { "name": "markup.inserted constant.language support.property-value entity.name.filename" }, + "2": { "name": "keyword.other" } + } + }, + { + "match": "([\\.])", + "name": "keyword.control.less" + }, + { + "match": "\\b([[:lower:]][[:word:]]*)\\b[[:space:]]*", + "captures": { + "1": { "name": "variable.parameter string.other.link variable.language" } + } + }, + { "include": "#value-expression" } + ] + } + ] + }, + "pattern-record": { + "begin": "{", + "end": "}", + "patterns": [ + { "include": "#comment" }, + { "include": "#pattern-record-item" } + ] + }, + "pattern-record-field": { + "begin": "\\b([_][[:word:]]*)\\b|\\b([[:lower:]][[:word:]]*)\\b", + "end": "(,)|(?=})", + "beginCaptures": { + "1": { "name": "comment" }, + "2": { "name": "markup.inserted constant.language support.property-value entity.name.filename" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#comment" }, + { + "begin": "\\G(:)", + "end": "(?=[,}])", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#pattern" } + ] + } + ] + }, + "pattern-record-item": { + "patterns": [ + { "include": "#module-path-simple-prefix" }, + { "include": "#pattern-record-field" } + ] + }, + "pattern-variable": { + "patterns": [ + { + "match": "\\b(_(?:[[:lower:]][[:word:]]*)?)\\b(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "comment" } + } + }, + { + "match": "\\b([[:lower:]][[:word:]]*)\\b(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "variable.other" } + } + } + ] + }, + "signature-expression": { + "patterns": [ + { + "comment": "FIXME: scan for :upper: to disambiguate type/signature in hover", + "begin": "(?=\\([[:space:]]*[[:upper:]][[:word:]]*[[:space:]]*:)", + "end": "(?=[;])", + "patterns": [ + { + "begin": "(?=\\()", + "end": "(?=[;]|=>)", + "patterns": [] + }, + { + "begin": "(=>)", + "end": "(?=[;\\(])", + "beginCaptures": { + "1": { "name": "markup.inserted keyword.control.less" } + }, + "patterns": [ + { "include": "#structure-expression" } + ] + } + ] + }, + { + "begin": "\\b(module)\\b[[:space:]]*\\b(type)\\b([[:space:]]*\\b(of)\\b)?", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "markup.inserted keyword.other variable.other.readwrite.instance" }, + "2": { "name": "constant.language" }, + "3": { "name": "markup.inserted keyword.other variable.other.readwrite.instance" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#module-path-simple" }, + { + "match": "\\b([[:upper:]][[:word:]]*)\\b", + "name": "support.class entity.name.class" + } + ] + }, + { "include": "#signature-expression-constraints" }, + { "include": "#structure-expression" } + ] + }, + "signature-expression-constraints": { + "begin": "(?=\\b(with))", + "end": "(?=[;\\)}]|\\b(class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|val)\\b)", + "patterns": [ + { + "begin": "\\b(and|with)\\b", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation storage.modifier" } + }, + "patterns": [ + { "include": "#comment" }, + { + "comment": "FIXME: special version of #module-item-type with non-consuming `;`. Atom seems to need this to work.", + "begin": "\\b(type)\\b", + "end": "(?=[;\\)}]|\\b(class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|val|with)\\b)", + "beginCaptures": { + "1": { "name": "constant.language" } + }, + "patterns": [ + { "include": "#module-item-type-and" }, + { "include": "#module-item-type-constraint" }, + { "include": "#module-item-type-bind" } + ] + }, + { + "begin": "(?=\\b(module)\\b)", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|val|with)\\b)", + "patterns": [ + { + "begin": "\\b(module)\\b", + "end": "(?=:?=|[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "markup.inserted keyword.control keyword.other variable.other.readwrite.instance" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#module-path-simple" }, + { + "match": "[[:upper:]][[:word:]]*", + "name": "support.class entity.name.class" + } + ] + }, + { + "begin": "(:=)|(=)", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "markup.inserted keyword.control.less" }, + "2": { "name": "markup.inserted keyword.control.less" } + }, + "patterns": [ + { "include": "#structure-expression" } + ] + } + ] + } + ] + } + ] + }, + "structure-expression": { + "patterns": [ + { "include": "#comment" }, + { + "comment": "FIXME: scan for :upper: or `val` to disambiguate types from signatures for hover", + "begin": "\\((?=[[:space:]]*(\\b(val)\\b|[^'\\[<[:lower:]]))", + "end": "\\)|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|with)\\b)", + "patterns": [ + { "include": "#comment" }, + { + "comment": "FIXME: might need to refactor this or include more expressions", + "include": "#structure-expression-block" + }, + { + "begin": "\\b(val)\\b", + "end": "(?=\\))|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "patterns": [ + { "include": "#comment" }, + { + "match": "\\b([[:lower:]][[:word:]]*)\\b", + "name": "support.class entity.name.class" + } + ] + }, + { "include": "#module-path-simple" }, + { + "begin": "(:)", + "end": "(?=[\\)])|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#signature-expression" } + ] + } + ] + }, + { "include": "#module-path-simple" }, + { "include": "#structure-expression-block" } + ] + }, + "structure-expression-block": { + "begin": "{", + "end": "}", + "patterns": [ + { "include": "#structure-expression-block-item" } + ] + }, + "structure-expression-block-item": { + "patterns": [ + { "include": "#attribute" }, + { "include": "#comment" }, + { "include": "#module-item-include" }, + { "include": "#module-item-let" }, + { "include": "#module-item-open" }, + { "include": "#module-item-type" } + ] + }, + "type-annotation-rhs": { + "begin": "(?|~$\\\\])([:])(?![#\\-:!?.@*/&%^+<=>|~$\\\\])", + "end": "(?=\\))|(?=[,;}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#type-expression" } + ] + }, + "type-expression": { + "patterns": [ + { + "match": "([\\.])", + "name": "entity.name.function" + }, + { "include": "#type-expression-atomic" }, + { "include": "#type-expression-arrow" } + ] + }, + "type-expression-atomic": { + "patterns": [ + { "include": "#attribute" }, + { "include": "#comment" }, + { "include": "#module-path-extended-prefix" }, + { "include": "#type-expression-label" }, + { + "match": "\\b(as)\\b", + "name": "variable.other.class.js variable.interpolation storage.modifier" + }, + { "include": "#type-expression-constructor" }, + { "include": "#type-expression-object" }, + { "include": "#type-expression-parens" }, + { "include": "#type-expression-polymorphic-variant" }, + { "include": "#type-expression-record" }, + { "include": "#type-expression-variable" } + ] + }, + "type-expression-arrow": { + "match": "=>", + "name": "markup.inserted keyword.control.less" + }, + "type-expression-constructor": { + "match": "(_)(?![[:alnum:]])|\\b([_[:lower:]][[:word:]]*)\\b(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "comment" }, + "2": { "name": "support.type" } + } + }, + "type-expression-label": { + "begin": "\\b([_[:lower:]][[:word:]]*)\\b(::)", + "end": "(?<==>)", + "beginCaptures": { + "1": { "name": "markup.inserted constant.language support.property-value entity.name.filename" }, + "2": { "name": "keyword.control" } + }, + "patterns": [ + { "include": "#type-expression" }, + { + "match": "(\\?)", + "captures": { + "1": { "name": "keyword.control.less" } + } + } + ] + }, + "type-expression-object": { + "comment": "FIXME: separate sub-rules", + "begin": "(<)", + "end": "(>)", + "captures": { + "1": { "name": "entity.name.function" } + }, + "patterns": [ + { + "begin": "(\\.\\.)", + "end": "(?=>)", + "beginCaptures": { + "1": { "name": "constant.language" } + } + }, + { + "comment": "FIXME: method item", + "begin": "(?=[_[:lower:]])", + "end": "(,)|(?=>)", + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { + "comment": "FIXME: method name", + "begin": "(?=[_[:lower:]])", + "end": "(?=:)", + "patterns": [ + { + "match": "\\b([_[:lower:]][[:word:]]*)\\b", + "captures": { + "1": { "name": "markup.inserted constant.language support.property-value entity.name.filename" } + } + } + ] + }, + { + "comment": "FIXME: method type", + "begin": "(:)", + "end": "(?=[,>])", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#type-expression" } + ] + } + ] + } + ] + }, + "type-expression-parens": { + "comment": "FIXME: proper tuple types", + "begin": "\\(", + "end": "\\)", + "patterns": [ + { + "begin": "\\b(module)\\b", + "end": "(?=[\\)])", + "beginCaptures": { + "1": { "name": "keyword.other" } + }, + "patterns": [ + { "include": "#module-path-extended" }, + { "include": "#signature-expression-constraints" } + ] + }, + { + "match": ",", + "name": "keyword.control.less" + }, + { "include": "#type-expression" } + ] + }, + "type-expression-polymorphic-variant": { + "comment": "FIXME: proper parsing", + "begin": "(\\[)([<>])?", + "end": "(\\])", + "captures": { + "1": { "name": "entity.name.function" }, + "2": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { + "begin": "(\\|)?(?![#\\-:!?.@*/&%^+<=>|~$\\\\])[[:space:]]*", + "end": "(?=[;)}\\]]|\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\])|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#value-expression-constructor" }, + { + "match": "([:])|\\b(of)\\b|([&])", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "keyword.other" }, + "3": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + } + }, + { "include": "#value-expression-constructor-polymorphic" }, + { "include": "#type-expression" } + ] + } + ] + }, + "type-expression-record": { + "begin": "{", + "end": "}", + "patterns": [ + { "include": "#type-expression-record-item" } + ] + }, + "type-expression-record-field-sans-modifier": { + "begin": "\\b([_[:lower:]][[:word:]]*)\\b", + "end": "(,)|(?=[,}])", + "beginCaptures": { + "1": { "name": "markup.inserted constant.language support.property-value entity.name.filename" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#comment" }, + { + "begin": "(:)", + "end": "(?=[,}])", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#type-expression" } + ] + } + ] + }, + "type-expression-record-field": { + "patterns": [ + { + "begin": "\\b(mutable)\\b", + "end": "(?<=[,])|(?=})", + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation storage.modifier" } + }, + "patterns": [ + { "include": "#type-expression-record-field-sans-modifier" } + ] + }, + { "include": "#type-expression-record-field-sans-modifier" } + ] + }, + "type-expression-record-item": { + "patterns": [ + { "include": "#comment" }, + { "include": "#module-path-simple-prefix" }, + { "include": "#type-expression-record-field" } + ] + }, + "type-expression-variable": { + "match": "(')([_[:lower:]][[:word:]]*)\\b(?!\\.[[:upper:]])", + "captures": { + "1": { "name": "comment" }, + "2": { "name": "variable.parameter" } + } + }, + "value-expression": { + "patterns": [ + { "include": "#attribute" }, + { "include": "#comment" }, + { "include": "#extension-node" }, + { "include": "#jsx" }, + { "include": "#operator" }, + { "include": "#value-expression-builtin" }, + { "include": "#value-expression-if-then-else" }, + { "include": "#value-expression-atomic" }, + { "include": "#module-path-simple-prefix" }, + { + "match": "[:?]", + "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" + }, + { "include": "#record-path" } + ] + }, + "value-expression-atomic": { + "patterns": [ + { "include": "#value-expression-literal" }, + { "include": "#value-expression-literal-list-or-array" }, + { "include": "#value-expression-for" }, + { "include": "#value-expression-fun" }, + { "include": "#value-expression-block-or-record-or-object" }, + { "include": "#value-expression-label" }, + { "include": "#value-expression-parens" }, + { "include": "#value-expression-switch" }, + { "include": "#value-expression-try" }, + { "include": "#value-expression-while" } + ] + }, + "value-expression-atomic-with-paths": { + "patterns": [ + { "include": "#value-expression-atomic" }, + { "include": "#module-path-simple-prefix" }, + { "include": "#record-path-suffix" } + ] + }, + "value-expression-block": { + "begin": "{", + "end": "}", + "patterns": [ + { "include": "#value-expression-block-item" } + ] + }, + "value-expression-block-item": { + "patterns": [ + { "include": "#module-item-let" }, + { "include": "#value-expression" } + ] + }, + "value-expression-block-look": { + "begin": "(?![[:space:]]*($|\\.\\.\\.|([[:upper:]][[:word:]]*\\.)*([[:lower:]][[:word:]]*)[[:space:]]*(?:,|:(?![=]))))", + "end": "(?=})", + "patterns": [ + { "include": "#value-expression-block-item" } + ] + }, + "value-expression-block-or-record-or-object": { + "begin": "{", + "end": "}", + "patterns": [ + { "include": "#comment" }, + { "include": "#module-path-simple-prefix" }, + { "include": "#value-expression-object-look" }, + { "include": "#value-expression-record-look" }, + { "include": "#value-expression-block-look" } + ] + }, + "value-expression-builtin": { + "match": "\\b(assert|decr|failwith|fprintf|ignore|incr|land|lazy|lor|lsl|lsr|lxor|mod|new|not|printf|ref)\\b|\\b(raise)\\b", + "captures": { + "1": { "name": "keyword.control" }, + "2": { "name": "keyword.control.trycatch" } + } + }, + "value-expression-constructor": { + "match": "\\b([[:upper:]][[:word:]]*)\\b(?![[:space:]]*[\\.])", + "captures": { + "1": { "name": "constant.language" } + } + }, + "value-expression-constructor-polymorphic": { + "match": "(`)([[:alpha:]][[:word:]]*)\\b(?!\\.)", + "captures": { + "1": { "name": "constant.other.symbol keyword.control.less variable.parameter" }, + "2": { "name": "constant.language" } + } + }, + "value-expression-for": { + "begin": "(?=\\b(for)\\b)", + "end": "(?<=})|(?=[;]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { "include": "#value-expression-for-head" }, + { "include": "#value-expression-block" } + ] + }, + "value-expression-for-head": { + "begin": "(?=\\b(for)\\b)", + "end": "(?={)|(?=[;]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "patterns": [ + { + "begin": "\\b(for)\\b", + "end": "(?=\\b(in)\\b)|(?=[;]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.loop" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#pattern-variable" } + ] + }, + { + "begin": "\\b(in)\\b", + "end": "(?=\\b(to)\\b)|(?=[;]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.loop" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#value-expression-atomic-with-paths" } + ] + }, + { + "begin": "\\b(to)\\b", + "end": "(?={)|(?=[;]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.loop" } + }, + "patterns": [ + { "include": "#comment" }, + { "include": "#value-expression-atomic-with-paths" } + ] + }, + { "include": "#value-expression-block" } + ] + }, + "value-expression-fun": { + "begin": "\\b(fun)\\b", + "end": "(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control" } + }, + "patterns": [ + { "include": "#value-expression-fun-pattern-match-rule-lhs" }, + { "include": "#value-expression-fun-pattern-match-rule-rhs" } + ] + }, + "value-expression-fun-pattern-match-rule-lhs": { + "begin": "(?=\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))|(?<=fun)", + "end": "(\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))|(?==>)|(?=[;\\)}]|\\b(and|class|constraint|exception|external|include|inherit|let|method|module|nonrec|open|private|rec|type|val|with)\\b)", + "applyEndPatternLast": true, + "beginCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "endCaptures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" } + }, + "patterns": [ + { "include": "#pattern-guard" }, + { "include": "#pattern" } + ] + }, + "value-expression-fun-pattern-match-rule-rhs": { + "begin": "(=>)", + "end": "(?=[;\\)}]|\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\])|\\b(and)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#value-expression" } + ] + }, + "value-expression-if-then-else": { + "begin": "\\b(if)\\b", + "end": "(?=[;\\)\\]}])", + "applyEndPatternLast": true, + "beginCaptures": { + "1": { "name": "keyword.control.conditional" } + }, + "patterns": [ + { "include": "#comment" }, + { + "begin": "\\b(else)\\b", + "end": "(?=[;\\)\\]}])", + "beginCaptures": { + "1": { "name": "keyword.control.conditional" } + }, + "patterns": [ + { "include": "#value-expression" } + ] + }, + { "include": "#value-expression-atomic-with-paths" } + ] + }, + "value-expression-lazy": { + "comment": "FIXME", + "match": "\\b(lazy)\\b", + "captures": { + "1": { "name": "keyword.other" } + } + }, + "value-expression-label": { + "begin": "\\b([_[:lower:]][[:word:]]*)\\b[[:space:]]*(::)(\\?)?", + "end": "(?![[:space:]])", + "beginCaptures": { + "1": { "name": "markup.inserted constant.language support.property-value entity.name.filename" }, + "2": { "name": "keyword.control" }, + "3": { "name": "storage.type" } + }, + "patterns": [ + { "include": "#value-expression" } + ] + }, + "value-expression-literal": { + "patterns": [ + { "include": "#value-expression-literal-boolean" }, + { "include": "#value-expression-literal-character" }, + { "include": "#value-expression-constructor" }, + { "include": "#value-expression-constructor-polymorphic" }, + { "include": "#value-expression-lazy" }, + { "include": "#value-expression-literal-numeric" }, + { "include": "#value-expression-literal-string" }, + { "include": "#value-expression-literal-unit" } + ] + }, + "value-expression-literal-boolean": { + "match": "\\b(false|true)\\b", + "name": "constant.language" + }, + "value-expression-literal-character": { + "match": "(')([[:space:]]|[[:graph:]]|\\\\[\\\\\"'ntbr]|\\\\[[:digit:]][[:digit:]][[:digit:]]|\\\\x[[:xdigit:]][[:xdigit:]]|\\\\o[0-3][0-7][0-7])(')", + "name": "constant.character" + }, + "value-expression-literal-list-or-array": { + "begin": "(\\[\\|?)(?![@%])", + "end": "(\\|?\\])", + "beginCaptures": { + "1": { "name": "constant.language.list" } + }, + "endCaptures": { + "1": { "name": "constant.language.list" } + }, + "patterns": [ + { "include": "#value-expression-literal-list-or-array-separator" }, + { "include": "#value-expression" }, + { "include": "#value-expression-literal-list-or-array" } + ] + }, + "value-expression-literal-list-or-array-separator": { + "match": "(,)|(\\.\\.\\.)", + "captures": { + "1": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "2": { "name": "keyword.control" } + } + }, + "value-expression-literal-numeric": { + "patterns": [ + { + "match": "([-])?([[:digit:]][_[:digit:]]*)(?:(\\.)([_[:digit:]]*))?(?:([eE])([\\-\\+])?([[:digit:]][_[:digit:]]*))?(?![bBoOxX])", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "constant.numeric" }, + "3": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "4": { "name": "constant.numeric" }, + "5": { "name": "keyword.control.less" }, + "6": { "name": "keyword.control.less" }, + "7": { "name": "constant.numeric" } + } + }, + { + "match": "([-])?(0[xX])([[:xdigit:]][_[:xdigit:]]*)(?:(\\.)([_[:xdigit:]]*))?(?:([pP])([\\-\\+])?([[:digit:]][_[:digit:]]*))?", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "keyword.control.less" }, + "3": { "name": "constant.numeric" }, + "4": { "name": "variable.other.class.js variable.interpolation keyword.operator keyword.control" }, + "5": { "name": "constant.numeric" }, + "6": { "name": "keyword.control.less" }, + "7": { "name": "keyword.control.less" }, + "8": { "name": "constant.numeric" } + } + }, + { + "match": "([-])?(0[oO])([0-7][_0-7]*)", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "keyword.control.less" }, + "3": { "name": "constant.numeric" } + } + }, + { + "match": "([-])?(0[bB])([0-1][_0-1]*)", + "captures": { + "1": { "name": "keyword.control.less" }, + "2": { "name": "keyword.control.less" }, + "3": { "name": "constant.numeric" } + } + } + ] + }, + "value-expression-literal-string": { + "patterns": [ + { + "begin": "(?|~$\\\\]))", + "end": "(?==>|[;\\)}])", + "patterns": [ + { "include": "#pattern-guard" }, + { "include": "#pattern" } + ] + }, + "value-expression-switch-pattern-match-rule-rhs": { + "begin": "(=>)", + "end": "(?=}|\\|(?![#\\-:!?.@*/&%^+<=>|~$\\\\]))", + "beginCaptures": { + "1": { "name": "keyword.control.less" } + }, + "patterns": [ + { "include": "#value-expression-block-item" } + ] + }, + "value-expression-try": { + "begin": "\\b(try)\\b", + "end": "(?<=})|(?=[;\\)]|\\b(and|as|class|constraint|exception|external|include|inherit|let|method|nonrec|open|private|rec|type|val|with)\\b)", + "beginCaptures": { + "1": { "name": "keyword.control.trycatch" } + }, + "patterns": [ + { "include": "#value-expression-try-head" }, + { "include": "#value-expression-switch-body" } + ] + }, + "value-expression-try-head": { + "begin": "(?<=try)", + "end": "(?