%YAML 1.2 --- # Derived from JavaScript Next: https://github.com/Benvie/JavaScriptNext.tmLanguage name: JavaScript file_extensions: - js - htc first_line_match: ^#!\s*/.*\b(node|js)\b scope: source.js variables: identifier: '[_$[:alpha:]][_$[:alnum:]]*' constant_identifier: '[[:upper:]][_$[:digit:][:upper:]]*\b' dollar_only_identifier: '\$(?![_$[:alnum:]])' dollar_identifier: '(\$)[_$[:alnum:]]+' func_lookahead: '\s*\b(async\s+)?function\b' arrow_func_lookahead: '\s*(\basync\s*)?([_$[:alpha:]][_$[:alnum:]]*|\(([^()]|\([^()]*\))*\))\s*=>' contexts: main: - include: comments-top-level - include: keywords-top-level - include: statements keywords-top-level: - match: \bimport\b scope: meta.import.js keyword.control.import-export.js push: import-extended - match: \bexport\b scope: meta.export.js keyword.control.import-export.js push: export-extended - match: \b(export|default|from|as)\b scope: keyword.control.import-export.js import-escape: - match: '(?=;|function|var|class)' pop: true - match: "(?='|\"|\\bfrom\\b)" set: import-final import-extended: - meta_content_scope: meta.import.js - include: import-escape - include: comments - match: '\{' scope: meta.block.js punctuation.section.block.js set: import-brace - match: '{{identifier}}' scope: variable.other.readwrite.js set: import-extended-as - match: '\*' scope: constant.other.js set: import-extended-as - match: '(?=\S)' pop: true import-extended-as: - meta_content_scope: meta.import.js - include: import-escape - match: '\b(as)(?:\s+({{identifier}}))?' captures: 1: keyword.control.import-export.js 2: variable.other.readwrite.js - match: '(?=\S)' set: import-extended-continue import-extended-continue: - meta_scope: meta.import.js - include: import-escape - include: comments - match: ',' scope: punctuation.separator.comma.js set: import-extended - match: '(?=\S)' pop: true import-brace: - meta_content_scope: meta.import.js meta.block.js - include: import-escape - include: comments - match: '\}' scope: punctuation.section.block.js set: import-extended-as - match: '{{identifier}}' scope: variable.other.readwrite.js set: import-brace-as - match: '\*' scope: constant.other.js set: import-brace-as - match: '(?=\S)' pop: true import-brace-as: - meta_content_scope: meta.import.js meta.block.js - include: import-escape - match: '\b(as)\b(\s+(?:{{identifier}}))?' captures: 1: keyword.control.import-export.js 2: variable.other.readwrite.js - match: '(?=\S)' set: import-brace-continue import-brace-continue: - meta_scope: meta.import.js meta.block.js - include: import-escape - include: comments - match: '(?=\})' set: import-brace - match: ',' scope: punctuation.separator.comma.js set: import-brace - match: '(?=\S)' pop: true import-final: - meta_scope: meta.import.js - include: comments - match: '\bfrom\b' scope: keyword.control.import-export.js - include: literal-string - match: '(?=\S)' pop: true export-escape: - match: '(?=;|function|var|class)' pop: true - match: "(?='|\"|\\bfrom\\b)" set: export-final export-extended: - meta_content_scope: meta.export.js - match: '(?=\b(let|const|var)\b)' set: - meta_content_scope: meta.export.js - match: '(?=;|\n)' pop: true - include: expressions - include: export-escape - include: comments - match: '\bdefault\b' scope: keyword.control.import-export.js set: - meta_content_scope: meta.export.js - match: '(?=;|\n)' pop: true - include: expressions - match: '\{' scope: meta.block.js punctuation.section.block.js set: export-brace - match: '\*' scope: constant.other.js set: export-extended-as - match: '(?=\S)' pop: true export-extended-as: - meta_content_scope: meta.export.js - include: export-escape - match: '\b(as)(?:\s+({{identifier}}))?' captures: 1: keyword.control.import-export.js 2: variable.other.readwrite.js - match: '(?=\S)' set: export-extended-continue export-extended-continue: - meta_scope: meta.export.js - include: export-escape - include: comments - match: ',' scope: punctuation.separator.comma.js set: export-extended - match: '(?=\S)' pop: true export-brace: - meta_content_scope: meta.export.js meta.block.js - include: export-escape - include: comments - match: '\}' scope: punctuation.section.block.js set: export-extended-as - match: '{{identifier}}' scope: variable.other.readwrite.js set: export-brace-as - match: '\*' scope: constant.other.js set: export-brace-as - match: '(?=\S)' pop: true export-brace-as: - meta_content_scope: meta.export.js meta.block.js - include: export-escape - match: \b(as)\s+(default)\b captures: 1: keyword.control.import-export.js 2: keyword.control.import-export.js - match: '\b(as)\b(\s+(?:{{identifier}}))?' captures: 1: keyword.control.import-export.js 2: variable.other.readwrite.js - match: '(?=\S)' set: export-brace-continue export-brace-continue: - meta_scope: meta.export.js meta.block.js - include: export-escape - include: comments - match: '(?=\})' set: export-brace - match: ',' scope: punctuation.separator.comma.js set: export-brace - match: '(?=\S)' pop: true export-final: - meta_scope: meta.export.js - include: comments - match: '\bfrom\b' scope: keyword.control.import-export.js - include: literal-string - match: '(?=\S)' pop: true comments-top-level: - match: ^(#!).*$\n? scope: comment.line.shebang.js captures: 1: punctuation.definition.comment.js statements: - include: conditional - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: statements - include: label - include: expressions conditional: - match: \bswitch\b scope: keyword.control.switch.js push: - meta_scope: meta.switch.js - include: round-brackets - match: '\}' scope: meta.block.js punctuation.section.block.js pop: true - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '(?=\})' pop: true - match: ':' push: - match: '(?=(\bcase\b|\bdefault\b|\}))' pop: true - include: statements - match: \b(case|default)\b scope: keyword.control.switch.js - include: expressions - match: \bdo\b scope: keyword.control.loop.js push: - meta_scope: meta.do-while.js - include: comments - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: statements - match: \bwhile\b scope: keyword.control.loop.js - match: '\(' scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: '(?=\))' pop: true - include: expressions - match: '\)' scope: meta.group.js punctuation.section.group.js pop: true - match: \bfor\b scope: keyword.control.loop.js push: - meta_scope: meta.for.js - include: parens-block-scope - match: \bwhile\b scope: keyword.control.loop.js push: - meta_scope: meta.while.js - include: parens-block-scope - match: \bwith\b scope: keyword.control.with.js push: - meta_scope: meta.with.js - include: parens-block-scope - match: \b(else\s+if|if)\b scope: keyword.control.conditional.js push: - meta_scope: meta.conditional.js - include: parens-block-scope - match: \belse\b scope: keyword.control.conditional.js push: - meta_scope: meta.conditional.js - include: block-scope - match: \btry\b scope: keyword.control.trycatch.js push: - meta_scope: meta.try.js - include: block-scope - match: \bfinally\b scope: keyword.control.trycatch.js push: - meta_scope: meta.finally.js - include: block-scope - match: \bcatch\b scope: keyword.control.trycatch.js push: - meta_scope: meta.catch.js - include: parens-block-scope parens-block-scope: - match: '\(' scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: '\)' scope: punctuation.section.group.js pop: true - include: expressions - include: block-scope block-scope: - include: comments - match: '\}' scope: meta.block.js punctuation.section.block.js pop: true - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '(?=\})' pop: true - include: statements - match: '(?=\S)' pop: true expressions: - include: comments - include: regexp-complete - include: literal-string - include: literal-string-template - include: constructor - include: unary-operators - include: binary-operators - include: class - include: keywords - include: constants - include: literal-prototype - include: named-function - include: anonymous-function - include: object-literal - include: brackets - include: literal-number - include: literal-call - include: literal-variable - include: literal-punctuation - include: fallthrough fallthrough: # If an arrow function has the ( and ) on different lines, we won't have matched - match: => scope: storage.type.function.arrow.js after-operator: # Prevent matching "{" as a block, but instead always treat as an object # literal. This is needed since in the "statements" context, a "{" starts # an anonymous block, not an object literal. - match: '(?=\{)' push: - include: object-literal - match: '(?=.|\n)' pop: true # When following an operator, a single / is the beginning of a regexp, # not a division operator - match: '/(?=[^/*])' scope: punctuation.definition.string.begin.js push: regexp - include: constants - match: '(?=[\S])' pop: true after-identifier: # When following an identifier or closing )/], a single / is a division # operator, not the beginning of a regexp - match: '/(?=[^/*])' scope: keyword.operator.arithmetic.js set: after-operator - match: '(?=[\S\n])' pop: true comments: - match: /\*\*(?!/) scope: punctuation.definition.comment.js push: - meta_scope: comment.block.documentation.js - match: \*/ scope: punctuation.definition.comment.js pop: true - match: /\* scope: punctuation.definition.comment.js push: - meta_scope: comment.block.js - match: \*/ scope: punctuation.definition.comment.js pop: true - match: // scope: punctuation.definition.comment.js push: - meta_scope: comment.line.double-slash.js - match: \n pop: true literal-string: - match: "'" scope: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.single.js - match: (')|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js set: after-identifier - include: string-content - match: '"' captures: 0: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.double.js - match: (")|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js set: after-identifier - include: string-content literal-string-template: - match: '({{identifier}})?(`)' captures: 1: variable.function.tagged-template.js 2: punctuation.definition.string.template.begin.js push: - meta_scope: string.template.js - match: "`" scope: punctuation.definition.string.template.end.js set: after-identifier - match: '\$\{' captures: 0: punctuation.definition.template-expression.begin.js push: - clear_scopes: 1 - meta_scope: meta.template.expression.js - meta_content_scope: source.js.embedded.expression - match: '\}' scope: punctuation.definition.template-expression.end.js pop: true - include: expressions - include: string-content string-content: - match: \\\s*\n scope: constant.character.escape.newline.js - match: '\\(x[\da-fA-F][\da-fA-F]|u[\da-fA-F][\da-fA-F][\da-fA-F][\da-fA-F]|.)' scope: constant.character.escape.js regexp-complete: - match: '/(?=(?:[^/\\\[]|\\.|\[([^\]\\]|\\.)+\])+/(?![/*])[gimyu]*(?!\s*[a-zA-Z0-9_$]))' scope: punctuation.definition.string.begin.js push: regexp regexp: - meta_scope: string.regexp.js - match: "(/)([gimyu]*)" captures: 1: punctuation.definition.string.end.js 2: keyword.other.js set: after-identifier - match: '(?=.|\n)' push: - match: '(?=/)' pop: true - include: scope:source.regexp.js constructor: - match: '\b(new)\b\s+(?=({{identifier}}|\())' scope: meta.instance.constructor.js captures: 1: keyword.operator.word.new.js push: constructor-name constructor-name: - match: '(?=function\b)' set: - meta_scope: meta.instance.constructor.js - match: '(?=function\b)' push: function-declaration - match: '(?=\()' set: constructor-params - match: '(?=\S)' pop: true - match: '(?=class\b)' set: - meta_scope: meta.instance.constructor.js - include: class - match: '(?=\()' set: constructor-params - match: '(?=\S)' pop: true - match: '(?={{identifier}})' set: - meta_scope: meta.instance.constructor.js meta.function-call.constructor.js - include: well-known-identifiers - include: language-identifiers - match: '{{dollar_only_identifier}}' scope: variable.type.dollar.only.js punctuation.dollar.js - match: '{{dollar_identifier}}' scope: variable.type.dollar.js captures: 1: punctuation.dollar.js - match: '{{identifier}}' scope: variable.type.js - match: '\.' scope: punctuation.accessor.js - include: square-brackets - match: '(?=\()' set: constructor-params - match: '(?=\S|$)' pop: true - match: '\(' scope: punctuation.section.group.js set: - meta_scope: meta.instance.constructor.js meta.function-call.constructor.js meta.group.js - match: '\)' scope: punctuation.section.group.js set: constructor-params - include: expressions - match: '(?=\S)' pop: true constructor-params: - meta_content_scope: meta.instance.constructor.js - match: '(?=\()' push: - meta_scope: meta.function-call.constructor.js - include: function-call-params - match: '(?=\S)' pop: true unary-operators: - match: '~' scope: keyword.operator.bitwise.js - match: '!(?!=)' scope: keyword.operator.logical.js - match: '--' scope: keyword.operator.arithmetic.js - match: '\+\+' scope: keyword.operator.arithmetic.js - match: \.\.\. scope: keyword.operator.spread.js binary-operators: - match: \bnew\b scope: keyword.operator.word.new.js - match: \b(delete|instanceof)\b scope: keyword.operator.js - match: \b(in|of|typeof|void)\b scope: keyword.operator.js push: after-operator - match: '&&|\|\|' scope: keyword.operator.logical.js push: after-operator - match: '=(?![=>])' scope: keyword.operator.assignment.js push: after-operator - match: |- (?x) %= | # assignment right-to-left both &= | # assignment right-to-left both \*= | # assignment right-to-left both \+= | # assignment right-to-left both -= | # assignment right-to-left both /= | # assignment right-to-left both \^= | # assignment right-to-left both \|= | # assignment right-to-left both <<= | # assignment right-to-left both >>= | # assignment right-to-left both >>>= # assignment right-to-left both scope: keyword.operator.assignment.augmented.js push: after-operator - match: |- (?x) << | # bitwise-shift left-to-right both >>> | # bitwise-shift left-to-right both >> | # bitwise-shift left-to-right both & | # bitwise-and left-to-right both \^ | # bitwise-xor left-to-right both \| # bitwise-or left-to-right both scope: keyword.operator.bitwise.js push: after-operator - match: |- (?x) <= | # relational left-to-right both >= | # relational left-to-right both < | # relational left-to-right both > # relational left-to-right both scope: keyword.operator.relational.js push: after-operator - match: |- (?x) === | # equality left-to-right both !== | # equality left-to-right both == | # equality left-to-right both != # equality left-to-right both scope: keyword.operator.comparison.js push: after-operator - match: |- (?x) / | # division left-to-right both % | # modulus left-to-right both \* | # multiplication left-to-right both \+ | # addition left-to-right both - # subtraction left-to-right both scope: keyword.operator.arithmetic.js push: after-operator - match: '\?|:' scope: keyword.operator.ternary.js push: after-operator class: - match: \bclass\b scope: storage.type.class.js push: - meta_scope: meta.class.js - match: '\{' scope: punctuation.section.block.js set: class-body - match: '\b(extends)\b\s+(?={{identifier}})' captures: 1: storage.modifier.extends.js push: - match: '{{identifier}}' scope: entity.other.inherited-class.js - match: '\.' scope: punctuation.accessor.js - match: '(?=\S)' pop: true - match: '{{identifier}}' scope: entity.name.class.js - include: comments class-body: - meta_scope: meta.class.js meta.block.js - include: comments - match: '\}' scope: punctuation.section.block.js pop: true - include: method-declaration keywords: - match: ^\s*\b(?:(throw)|(yield|return))\b\s*$ captures: # these keywords are restricted productions and implicitly end at the end of the line, so we don't push the after-operator scope 1: keyword.control.trycatch.js 2: keyword.control.flow.js - match: \bthrow\b scope: keyword.control.trycatch.js push: after-operator - match: \b(break|continue|goto)\b scope: keyword.control.loop.js - match: \b(yield)\b(?:\s*(\*))? captures: 1: keyword.control.flow.js 2: keyword.generator.asterisk.js push: after-operator - match: \b(await|return)\b scope: keyword.control.flow.js push: after-operator - match: \b(const|let|var)\b scope: storage.type.js constants: - match: \btrue\b scope: constant.language.boolean.true.js push: after-identifier - match: \bfalse\b scope: constant.language.boolean.false.js push: after-identifier - match: \bnull\b scope: constant.language.null.js push: after-identifier - match: \bundefined\b scope: constant.language.undefined.js push: after-identifier - match: \bNaN\b scope: constant.language.nan.js push: after-identifier literal-prototype: - match: '({{identifier}})\s*(\.)\s*(prototype)(?=\s*=\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' scope: meta.prototype.declaration.js captures: 1: support.class.js 2: punctuation.accessor.js 3: support.constant.prototype.js push: - meta_scope: meta.function.declaration.js - match: '\s*(=)\s*' captures: 1: keyword.operator.assignment.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - match: '(?=.|\n)' pop: true - match: '({{identifier}})\s*(\.)\s*(prototype)\s*(\.)\s*(?={{identifier}}\s*=\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' captures: 1: support.class.js 2: punctuation.accessor.js 3: support.constant.prototype.js 4: punctuation.accessor.js push: - meta_scope: meta.function.declaration.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - include: function-declaration-final-identifier - match: '({{identifier}})(\.)(prototype)\b' scope: meta.prototype.access.js captures: 1: support.class.js 2: punctuation.accessor.js 3: support.constant.prototype.js named-function: - match: '(?=(({{identifier}})\s*(\.)\s*)+({{identifier}})\s*(=)\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' push: - meta_scope: meta.function.declaration.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - include: function-declaration-identifiers - match: '(?=({{identifier}})\s*(=)\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' push: - meta_scope: meta.function.declaration.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - include: function-declaration-single-identifier - match: '(?={{func_lookahead}}(\s*\*)?\s+{{identifier}})' push: function-declaration anonymous-function: - match: '(?={{func_lookahead}})' push: - meta_content_scope: meta.function.anonymous.js - include: function-declaration - match: '(?={{arrow_func_lookahead}})' push: - meta_content_scope: meta.function.anonymous.js - include: arrow-function-declaration function-declaration-identifiers: - match: '(?={{identifier}}\s*\.)' push: - match: '\bprototype\b' scope: support.constant.prototype.js - include: language-identifiers - match: '{{dollar_only_identifier}}' scope: support.class.dollar.only.js punctuation.dollar.js - match: '{{dollar_identifier}}' scope: support.class.dollar.js captures: 1: punctuation.dollar.js - match: '{{identifier}}' scope: support.class.js - match: '\.' scope: punctuation.accessor.js pop: true - include: function-declaration-final-identifier function-declaration-final-identifier: - match: '(?={{identifier}}\s*(=)\s*)' push: - match: '{{dollar_only_identifier}}' scope: meta.property.object.dollar.only.js punctuation.dollar.js entity.name.function.js - match: '{{dollar_identifier}}' scope: meta.property.object.dollar.js entity.name.function.js captures: 1: punctuation.dollar.js - match: '{{identifier}}' scope: meta.property.object.js entity.name.function.js - match: '\s*(=)\s*' captures: 1: keyword.operator.assignment.js pop: true function-declaration-single-identifier: - match: '\s*(=)\s*' captures: 1: keyword.operator.assignment.js - match: '(?={{identifier}})' push: # These matches have to be duplicated to get entity.name.function # on the end of the scope stack since most color schemes require it - match: '{{dollar_only_identifier}}' scope: variable.other.dollar.only.js punctuation.dollar.js entity.name.function.js - match: '{{dollar_identifier}}' scope: variable.other.dollar.js entity.name.function.js captures: 1: punctuation.dollar.js - match: '{{constant_identifier}}' scope: variable.other.constant.js entity.name.function.js - match: '{{identifier}}' scope: variable.other.readwrite.js entity.name.function.js - match: (?=.) pop: true either-function-declaration: - match: '(?={{func_lookahead}})' push: function-declaration - match: '(?={{arrow_func_lookahead}})' push: arrow-function-declaration function-declaration: - include: comments - match: '\b(async)\b\s*' scope: meta.function.declaration.js captures: 1: storage.type.js - match: \b(function)\b(\*)?\s* scope: meta.function.declaration.js captures: 1: storage.type.function.js 2: keyword.generator.asterisk.js - match: '{{identifier}}' scope: meta.function.declaration.js entity.name.function.js - include: function-declaration-parameters - match: '(?=\s*\{)' set: function-block arrow-function-declaration: - match: '\s*(=>)\s*(?=\n|//|/*)' scope: meta.function.declaration.js captures: 1: storage.type.function.arrow.js set: arrow-function-declaration-continuation - match: '\s*(=>)(?=\s*\{)' scope: meta.function.declaration.js captures: 1: storage.type.function.arrow.js set: function-block - match: '(\s*(=>))\s*(?=\S)' captures: 1: meta.function.declaration.js 2: storage.type.function.arrow.js set: arrow-function-concise-body - match: '\b(async)\b\s*' scope: meta.function.declaration.js captures: 1: storage.type.js - match: '{{identifier}}' scope: meta.function.declaration.js variable.parameter.function.js - include: function-declaration-parameters arrow-function-declaration-continuation: - meta_content_scope: meta.function.declaration.js - include: comments - match: '(?=\{)' set: function-block - match: '(?=\S)' set: arrow-function-concise-body arrow-function-concise-body: - meta_content_scope: meta.block.js - match: '(?=[);}\],])' pop: true - match: '\n' set: arrow-function-concise-continuation # This custom comment match is required so that we move to the # arrow-function-concise-continuation context to try and continue the # body. Previously we didn't match the \n in the comments context, but that # caused completions to appear at the end of a single-line comment. - match: // scope: punctuation.definition.comment.js set: - meta_scope: comment.line.double-slash.js - match: \n set: arrow-function-concise-continuation - include: expressions arrow-function-concise-continuation: # Allow newlines in a concise body if the next line is a continuation # of the previous via method chaining - match: '(?=^\s*(\.|/[/*]))' set: arrow-function-concise-body - match: '(?=.|\n)' pop: true function-block: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - match: '\{' scope: punctuation.section.block.js push: - match: '(?=\})' pop: true - include: statements function-declaration-parameters: - match: \( scope: punctuation.section.group.begin.js push: - meta_scope: meta.function.declaration.js - match: \) scope: punctuation.section.group.end.js pop: true # Destructuring - match: \{ scope: punctuation.section.block.begin.js push: - meta_scope: meta.block.js - match: \} scope: punctuation.section.block.end.js pop: true - match: '{{identifier}}' scope: variable.parameter.function.js - match: ',' scope: punctuation.separator.parameter.function.js - match: '=' scope: keyword.operator.assignment.js push: - meta_scope: meta.parameter.optional.js - match: "(?=[,)}])" pop: true - include: expressions - match: \.\.\. scope: keyword.operator.spread.js - match: '{{identifier}}' scope: variable.parameter.function.js - match: ',' scope: punctuation.separator.parameter.function.js - match: '=' scope: keyword.operator.assignment.js push: - meta_scope: meta.parameter.optional.js - match: "(?=[,)])" pop: true - include: expressions - include: comments label: - match: '^\s*((?!default){{identifier}})\s*(:)' captures: 1: entity.name.label.js 2: punctuation.separator.js object-literal: - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.object-literal.js - match: '\}' scope: punctuation.section.block.js set: after-identifier - include: comments - match: \[ scope: punctuation.section.brackets.js push: - match: \] scope: punctuation.section.brackets.js pop: true - include: expressions - match: '({{identifier}})\s*(\})' captures: 1: variable.other.readwrite.js 2: punctuation.section.block.js pop: true - match: '({{identifier}})\s*(,)' captures: 1: variable.other.readwrite.js 2: punctuation.separator.comma.js - match: '({{identifier}})[ \t]*($\n?|(?=//|/\*))' captures: 1: variable.other.readwrite.js - match: '((\$)[$\w]*)\s*(:)\s*(?=({{func_lookahead}}|{{arrow_func_lookahead}}))' scope: meta.function.declaration.js captures: 1: meta.object-literal.key.dollar.js entity.name.function.js 2: punctuation.dollar.js 3: punctuation.separator.key-value.js push: - match: ':' scope: meta.function.declaration.js punctuation.separator.key-value.js - include: either-function-declaration - match: '(?=\S)' pop: true - match: "(?=('.*'|\".*\"|{{identifier}})\\s*:({{func_lookahead}}|{{arrow_func_lookahead}}))" push: - meta_content_scope: meta.object-literal.key.js meta.function.declaration.js - match: "'" scope: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.single.js - meta_content_scope: entity.name.function.js - match: (')|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content - match: '"' scope: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.double.js - meta_content_scope: entity.name.function.js - match: (")|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content - match: '{{identifier}}' scope: entity.name.function.js - match: '(?=:)' set: - match: '(:)\s*' scope: meta.function.declaration.js captures: 1: punctuation.separator.key-value.js - include: either-function-declaration - match: '(?=\S)' pop: true - include: method-declaration - match: "(?=\"|')" push: - meta_scope: meta.object-literal.key.js - include: literal-string - match: '(?=.|\n)' pop: true - match: '(\$)[$\w]*(?=\s*:)' scope: meta.object-literal.key.dollar.js captures: 1: punctuation.dollar.js - match: '{{identifier}}(?=\s*:)' scope: meta.object-literal.key.js - match: (?=[-+]?(?:\.[0-9]|0[bxo]|\d)) push: - meta_content_scope: meta.object-literal.key.js - include: literal-number - match: '' pop: true - match: ':' scope: punctuation.separator.key-value.js push: - match: "(?=\\}|,|('[^']*'|\"[^\"]*\"|{{identifier}})\\s*:)" pop: true - include: expressions - include: comments method-declaration: - match: \b(get|set)\b(?!\s*\()\s* scope: meta.function.declaration.js captures: 1: storage.type.accessor.js - match: (\*)\s* scope: meta.function.declaration.js captures: 1: keyword.generator.asterisk.js - match: \b(static)\b\s* scope: meta.function.declaration.js captures: 1: storage.type.js - match: '(\[)({{identifier}}(?:\.{{identifier}}|\.)*)?(\])?\s*(?=$|\()' scope: meta.function.declaration.js captures: 1: punctuation.definition.symbol.begin.js 2: entity.name.function.js 3: punctuation.definition.symbol.end.js push: - include: function-declaration-parameters - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: statements - include: comments - match: '(?=\S)' pop: true - match: (?=('[^\\]*'|"[^\\]*")\s*\() push: - meta_content_scope: meta.function.declaration.js - match: "'" scope: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.single.js - meta_content_scope: entity.name.function.js - match: (')|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content - match: '"' scope: punctuation.definition.string.begin.js push: - meta_scope: string.quoted.double.js - meta_content_scope: entity.name.function.js - match: (")|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content - match: \s* - include: function-declaration-parameters - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: statements - include: comments - match: '(?=\S)' pop: true - match: '({{identifier}})\s*(?=\()' scope: meta.function.declaration.js captures: 1: entity.name.function.js push: - include: function-declaration-parameters - match: '\{' scope: punctuation.section.block.js push: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: statements - include: comments - match: '(?=\S)' pop: true brackets: - include: round-brackets - include: square-brackets round-brackets: - match: \( scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: \) scope: punctuation.section.group.js set: after-identifier - include: expressions - match: \) scope: invalid.illegal.stray-bracket-end.js square-brackets: - match: '\[' scope: punctuation.section.brackets.js push: - meta_scope: meta.brackets.js - match: '\]' scope: punctuation.section.brackets.js set: after-identifier - include: expressions literal-number: - match: '(?i)(?:\B[-+]|\b)0x[0-9a-f]*\.(\B|\b[0-9]+)' scope: invalid.illegal.numeric.hex.js - match: '(?:\B[-+]|\b)0[0-9]+\.(\B|\b[0-9]+)' scope: invalid.illegal.numeric.octal.js - match: |- (?xi) (?:\B[-+])? (?: \b0b[0-1]*| # binary \b0o[0-7]*| # octal \b0x[0-9a-f]*| # hex ( \B\.[0-9]+| # e.g. .999 \b[0-9]+(\.[0-9]*)? # e.g. 999.999, 999. or 999 )(e[-+]?[0-9]+)? # e.g. e+123, E-123 ) scope: constant.numeric.js push: after-identifier - match: '(?:\B[-+]|\b)(Infinity)\b' scope: constant.language.infinity.js push: after-identifier literal-call: - match: (\$)(?=\s*\() scope: variable.function.js variable.other.dollar.only.js punctuation.dollar.js push: - meta_scope: meta.function-call.js - include: function-call-params - match: \b(clearTimeout|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|parseFloat|parseInt|setTimeout|super|unescape)\b(?=\() scope: support.function.js push: - meta_scope: meta.function-call.js - include: function-call-params - match: '({{identifier}})(?=\s*\()' scope: variable.function.js push: - meta_scope: meta.function-call.js - include: function-call-params - match: '(?={{identifier}}\s*\.\s*{{identifier}}\s*\()' push: - match: \b(console)(?:(\.)(warn|info|log|error|time|timeEnd|assert|count|dir|group|groupCollapsed|groupEnd|profile|profileEnd|table|trace|timeStamp))?\b captures: 1: support.type.object.console.js 2: punctuation.accessor.js 3: support.function.console.js set: - meta_scope: meta.function-call.method.js - include: function-call-params - match: \b(process)(?:(\.)(abort|chdir|cwd|disconnect|exit|[sg]ete?[gu]id|send|[sg]etgroups|initgroups|kill|memoryUsage|nextTick|umask|uptime|hrtime))?\b captures: 1: support.type.object.process.js 2: punctuation.accessor.js 3: support.function.process.js set: - meta_scope: meta.function-call.method.js - include: function-call-params - match: '(?={{identifier}}\s*\.)' push: - include: well-known-identifiers - include: language-identifiers - match: '{{dollar_only_identifier}}' scope: variable.other.object.dollar.only.js punctuation.dollar.js - match: '{{dollar_identifier}}' scope: variable.other.object.dollar.js captures: 1: punctuation.dollar.js - match: '{{identifier}}' scope: variable.other.object.js - match: \. scope: punctuation.accessor.js pop: true - match: \. scope: punctuation.accessor.js - include: method-call - match: '(?=[^ ])' pop: true method-call: - match: \b(shift|sort|splice|unshift|pop|push|reverse|copyWithin|fill)\b(?=\() scope: support.function.mutator.js push: - meta_scope: meta.function-call.method.js - include: function-call-params - match: \b(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)\b(?=\() scope: support.function.dom.js push: - meta_scope: meta.function-call.method.js - include: function-call-params - match: '({{identifier}})\s*(?=\()' scope: variable.function.js push: - meta_scope: meta.function-call.method.js - include: function-call-params function-call-params: - match: '\)' scope: meta.group.js punctuation.section.group.js set: after-identifier - match: '\(' scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: '(?=\))' set: after-identifier # Consume comma plus any whitespace to prevent whitespace from # getting meta scopes when they don't really apply - match: '(,)\s+' captures: 1: punctuation.separator.comma.js - include: expressions literal-variable: - match: '(?={{identifier}})' push: # Once we've consumed an identifier, switch to the special context that # property handles ambiguous tokens including "/" - match: '(?!{{identifier}})' set: after-identifier - include: well-known-identifiers - include: language-identifiers - include: dollar-identifiers - include: support - match: '\b[[:upper:]][_$[:alnum:]]*(?=\s*[\[.])' scope: support.class.js - match: '{{identifier}}(?=\s*[\[.])' scope: variable.other.object.js - include: simple-identifiers well-known-identifiers: - match: \b(Array|Boolean|Date|Function|Map|Math|Number|Object|Promise|Proxy|RegExp|Set|String|WeakMap|XMLHttpRequest)\b scope: support.class.builtin.js - match: \b((Eval|Range|Reference|Syntax|Type|URI)?Error)\b scope: support.class.error.js - match: \b(document|window|navigator)\b scope: support.type.object.dom.js - match: \b(Buffer|EventEmitter|Server|Pipe|Socket|REPLServer|ReadStream|WriteStream|Stream|Inflate|Deflate|InflateRaw|DeflateRaw|GZip|GUnzip|Unzip|Zip)\b scope: support.class.node.js language-identifiers: - match: \b(arguments)\b scope: variable.language.arguments.js - match: \b(super)\b scope: variable.language.super.js - match: \b(this)\b scope: variable.language.this.js - match: \b(self)\b scope: variable.language.self.js dollar-identifiers: - match: '{{dollar_only_identifier}}' scope: variable.other.dollar.only.js punctuation.dollar.js - match: '{{dollar_identifier}}' scope: variable.other.dollar.js captures: 1: punctuation.dollar.js simple-identifiers: - match: '{{constant_identifier}}' scope: variable.other.constant.js - match: '{{identifier}}' scope: variable.other.readwrite.js support: - match: \bdebugger\b scope: keyword.other.js - match: |- (?x) \b( ELEMENT_NODE|ATTRIBUTE_NODE|TEXT_NODE|CDATA_SECTION_NODE|ENTITY_REFERENCE_NODE|ENTITY_NODE|PROCESSING_INSTRUCTION_NODE|COMMENT_NODE| DOCUMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_FRAGMENT_NODE|NOTATION_NODE|INDEX_SIZE_ERR|DOMSTRING_SIZE_ERR|HIERARCHY_REQUEST_ERR| WRONG_DOCUMENT_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR|NOT_SUPPORTED_ERR|INUSE_ATTRIBUTE_ERR )\b scope: support.constant.dom.js - match: \b(assert|buffer|child_process|cluster|constants|crypto|dgram|dns|domain|events|fs|http|https|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|timers|tls|tty|url|util|vm|zlib)\b scope: support.module.node.js - match: \b(process)(?:(\.)(arch|argv|config|connected|env|execArgv|execPath|exitCode|mainModule|pid|platform|release|stderr|stdin|stdout|title|version|versions))?\b captures: 1: support.type.object.process.js 2: punctuation.accessor.js 3: support.type.object.process.js - match: \b(exports|module(?:(\.)(exports|id|filename|loaded|parent|children)))?\b captures: 1: support.type.object.module.js 2: punctuation.accessor.js 3: support.type.object.module.js - match: \b(global|GLOBAL|root|__dirname|__filename)\b scope: support.type.object.node.js object-property: - match: \b__proto__\b scope: variable.language.proto.js - match: \bconstructor\b scope: variable.language.constructor.js - match: \bprototype\b scope: variable.language.prototype.js - match: '{{dollar_only_identifier}}' scope: meta.property.object.dollar.only.js punctuation.dollar.js - match: '{{dollar_identifier}}' scope: meta.property.object.dollar.js captures: 1: punctuation.dollar.js - match: '{{identifier}}' scope: meta.property.object.js - match: \b(s(hape|ystemId|c(heme|ope|rolling)|ta(ndby|rt)|ize|ummary|pecified|e(ctionRowIndex|lected(Index)?)|rc)|h(space|t(tpEquiv|mlFor)|e(ight|aders)|ref(lang)?)|n(o(Resize|tation(s|Name)|Shade|Href|de(Name|Type|Value)|Wrap)|extSibling|ame)|c(h(ildNodes|Off|ecked|arset)?|ite|o(ntent|o(kie|rds)|de(Base|Type)?|l(s|Span|or)|mpact)|ell(s|Spacing|Padding)|l(ear|assName)|aption)|t(ype|Bodies|itle|Head|ext|a(rget|gName)|Foot)|i(sMap|ndex|d|m(plementation|ages))|o(ptions|wnerDocument|bject)|d(i(sabled|r)|o(c(type|umentElement)|main)|e(clare|f(er|ault(Selected|Checked|Value)))|at(eTime|a))|useMap|p(ublicId|arentNode|r(o(file|mpt)|eviousSibling))|e(n(ctype|tities)|vent|lements)|v(space|ersion|alue(Type)?|Link|Align)|URL|f(irstChild|orm(s)?|ace|rame(Border)?)|width|l(ink(s)?|o(ngDesc|wSrc)|a(stChild|ng|bel))|a(nchors|c(ce(ssKey|pt(Charset)?)|tion)|ttributes|pplets|l(t|ign)|r(chive|eas)|xis|Link|bbr)|r(ow(s|Span|Index)|ules|e(v|ferrer|l|adOnly))|m(ultiple|e(thod|dia)|a(rgin(Height|Width)|xLength))|b(o(dy|rder)|ackground|gColor))\b scope: support.constant.dom.js - match: '(?=.|\n)' set: after-identifier literal-punctuation: - match: \. scope: punctuation.accessor.js push: # All of these matches use set (or effectively a set via the final # include/match/pop construct) instead of push so that we escape this # accessor state once a match has been made. Otherwise identifiers # following method definitions or method calls will be scoped as # properties. - match: '(?=({{identifier}})\s*(=)\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' set: - meta_scope: meta.function.declaration.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - include: function-declaration-final-identifier - match: '(?={{identifier}}\s*\()' set: - include: method-call - match: '(?=.|\n)' pop: true - include: object-property - match: \; scope: punctuation.terminator.statement.js - match: "," scope: punctuation.separator.comma.js