%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*=>' method_name: >- (?x)(?: {{identifier}} | '(?:[^\\']|\\.)*' | "(?:[^\\"]|\\.)*" | \[ {{identifier}} (?:\.{{identifier}})* \] ) line_continuation_lookahead: >- (?x) (?! \+\+ | -- ) (?= != | [ -+*/% ><= &|^ \[( ;,.:? ] ) contexts: main: - include: comments - include: comments-top-level - include: keywords-top-level - include: statements prototype: - include: comments comments: - match: /\*\*(?!/) scope: punctuation.definition.comment.js push: - meta_include_prototype: false - meta_scope: comment.block.documentation.js - match: \*/ scope: punctuation.definition.comment.js pop: true - match: /\* scope: punctuation.definition.comment.js push: - meta_include_prototype: false - meta_scope: comment.block.js - match: \*/ scope: punctuation.definition.comment.js pop: true - match: // scope: punctuation.definition.comment.js push: - meta_include_prototype: false - meta_scope: comment.line.double-slash.js - match: \n pop: true comments-top-level: - match: ^(#!).*$\n? scope: comment.line.shebang.js captures: 1: punctuation.definition.comment.js else-pop: - match: (?=\S) pop: true immediately-pop: - match: '' pop: true comma-separator: - match: ',' scope: punctuation.separator.comma.js keywords-top-level: - match: \bimport\b scope: keyword.control.import-export.js push: - import-meta - import-export-final - import-extended - match: \bexport\b scope: keyword.control.import-export.js push: - export-meta - export-extended - match: \b(export|default|from|as)\b scope: keyword.control.import-export.js import-meta: - meta_scope: meta.import.js - include: immediately-pop import-export-alias: - match: \bas\b scope: keyword.control.import-export.js set: - match: \bdefault\b scope: keyword.control.import-export.js pop: true - match: '{{identifier}}' scope: variable.other.readwrite.js pop: true - include: else-pop - include: else-pop import-export-final: - match: '\bfrom\b' scope: keyword.control.import-export.js - match: (?=['"]) push: literal-string - include: else-pop import-extended: - match: (?='|") pop: true - match: (?=\S) set: - import-list - import-export-alias - import-item import-list: - match: ',' scope: punctuation.separator.comma.js push: - import-export-alias - import-item - include: else-pop import-item: - match: '\{' scope: punctuation.section.block.js set: import-brace - match: '{{identifier}}' scope: variable.other.readwrite.js pop: true - match: '\*' scope: constant.other.js pop: true - include: else-pop import-brace: - meta_scope: meta.block.js - include: comma-separator - match: '\}' scope: punctuation.section.block.js pop: true - match: '{{identifier}}' scope: variable.other.readwrite.js push: import-export-alias - match: '\*' scope: constant.other.js push: import-export-alias - include: else-pop export-meta: - meta_scope: meta.export.js - include: immediately-pop export-extended: - include: variable-declaration - match: '\bdefault\b' scope: keyword.control.import-export.js set: - match: (?=\bclass\b) set: class - match: (?=\bfunction\b) set: function-declaration - include: expression - match: (?=\S) set: - import-export-final - export-list - import-export-alias - export-item export-list: - match: ',' scope: punctuation.separator.comma.js push: - import-export-alias - export-item - include: else-pop export-item: - match: '\{' scope: punctuation.section.block.js set: - export-brace - match: '{{identifier}}' scope: variable.other.readwrite.js pop: true - match: '\*' scope: constant.other.js pop: true - include: else-pop export-brace: - meta_scope: meta.block.js - include: comma-separator - match: '\}' scope: punctuation.section.block.js pop: true - match: '{{identifier}}' scope: variable.other.readwrite.js push: import-export-alias - match: '\*' scope: constant.other.js push: import-export-alias - include: else-pop statements: - match: \; scope: punctuation.terminator.statement.js - 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: variable-declaration - match: \bthrow\b scope: keyword.control.trycatch.js push: restricted-production - 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: restricted-production - match: \b(await|return)\b scope: keyword.control.flow.js push: restricted-production - include: function-or-class-declaration - match: (?=\S) push: expression-statement variable-declaration: - match: \b(const|let|var)\b scope: storage.type.js push: expression-statement function-or-class-declaration: - match: (?=\bclass\b) push: class - match: (?=\bfunction\b) push: function-declaration expression-statement: - match: (?=\S) set: [ expression-statement-end, expression-begin ] expression-statement-end: - match: \n set: - match: '{{line_continuation_lookahead}}' set: expression-statement-end - include: else-pop - include: expression-end restricted-production: - match: \n pop: true - match: (?=\S) set: expression-statement expect-case-colon: - match: ':' scope: punctuation.separator.js pop: true - include: else-pop conditional: - match: \bswitch\b scope: keyword.control.switch.js push: - meta_scope: meta.switch.js - match: (?=\() push: parenthesized-expression - 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: \b(case)\b scope: keyword.control.switch.js push: - expect-case-colon - expression - match: \b(default)\b scope: keyword.control.switch.js push: - expect-case-colon - include: statements - match: \bdo\b scope: keyword.control.loop.js push: - meta_scope: meta.do-while.js - 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 - match: (?=\S) push: expression - 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 - match: ; scope: punctuation.terminator.statement.js - match: \b(const|let|var)\b scope: storage.type.js - include: expression-list - include: block-scope block-scope: - 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 - include: else-pop block-meta: - meta_scope: meta.block.js - include: immediately-pop expression-break: - match: (?=[;})\]]) pop: true expression: - match: (?=\S) set: [ expression-end, expression-begin ] expression-no-comma: - match: (?=\S) set: [ expression-end-no-comma, expression-begin ] expression-list: - include: expression-break - include: comma-separator - match: (?=\S) push: expression-no-comma expression-end: - include: expression-break - include: postfix-operators - include: binary-operators - include: ternary-operator - include: property-access - include: function-call - include: fallthrough - include: else-pop expression-end-no-comma: - match: (?=,) pop: true - include: expression-end expression-begin: - match: \) scope: invalid.illegal.stray-bracket-end.js pop: true - include: expression-break - include: literal-prototype - include: regexp-complete - include: literal-string - include: literal-string-template - include: constructor - include: prefix-operators - include: class - include: constants - include: function-assignment - include: either-function-declaration - include: object-literal - include: parenthesized-expression - include: array-literal - include: literal-number - include: literal-call - include: literal-variable - include: else-pop fallthrough: # If an arrow function has the ( and ) on different lines, we won't have matched - match: => scope: storage.type.function.arrow.js literal-string: - match: "'" scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: string.quoted.single.js - match: (')|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content - match: '"' captures: 0: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: string.quoted.double.js - match: (")|(\n) captures: 1: punctuation.definition.string.end.js 2: invalid.illegal.newline.js pop: true - include: string-content literal-string-template: - match: '({{identifier}})?(`)' captures: 1: variable.function.tagged-template.js 2: punctuation.definition.string.template.begin.js set: - meta_include_prototype: false - meta_scope: string.template.js - match: "`" scope: punctuation.definition.string.template.end.js pop: true - 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 - match: (?=\S) push: expression - 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: '/' scope: punctuation.definition.string.begin.js set: regexp regexp: - meta_include_prototype: false - meta_scope: string.regexp.js - match: "(/)([gimyu]*)" captures: 1: punctuation.definition.string.end.js 2: keyword.other.js pop: true - match: '(?=.|\n)' push: - meta_include_prototype: false - match: '(?=/)' pop: true - include: scope:source.regexp.js constructor: - match: '\bnew\b' scope: keyword.operator.word.new.js set: - constructor-meta - constructor-body constructor-meta: - meta_scope: meta.instance.constructor.js - include: immediately-pop constructor-body: - match: '' set: - constructor-body-meta - constructor-body-expect-arguments - constructor-body-expect-property-access - constructor-body-expect-class constructor-body-meta: - meta_scope: meta.function-call.constructor.js - include: immediately-pop constructor-body-expect-arguments: - match: '(?=\()' set: function-call-params - include: else-pop constructor-body-expect-property-access: - include: property-access - include: else-pop constructor-body-expect-class: - include: expression-break - include: regexp-complete - include: literal-string - include: literal-string-template - include: class - include: constants - include: either-function-declaration - include: object-literal - include: parenthesized-expression - include: array-literal - include: literal-number - 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 pop: true - include: else-pop prefix-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 - match: \+|\- scope: keyword.operator.arithmetic.js - match: \bnew\b scope: keyword.operator.word.new.js - match: \b(?:delete|typeof|void)\b scope: keyword.operator.js binary-operators: - match: \binstanceof\b scope: keyword.operator.js push: expression-begin - match: \b(in|of)\b scope: keyword.operator.js push: expression-begin - match: '&&|\|\|' scope: keyword.operator.logical.js push: expression-begin - match: '=(?![=>])' scope: keyword.operator.assignment.js push: expression-begin - 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: expression-begin - 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: expression-begin - 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: expression-begin - 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: expression-begin - 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: expression-begin - match: ',' scope: punctuation.separator.comma.js # TODO: Change to keyword.operator.comma.js ? push: expression-begin ternary-operator: - match: '\?' scope: keyword.operator.ternary.js set: - ternary-operator-expect-colon - expression-no-comma ternary-operator-expect-colon: - match: ':' scope: keyword.operator.ternary.js set: expression-no-comma - include: else-pop postfix-operators: - match: '--' scope: keyword.operator.arithmetic.js - match: '\+\+' scope: keyword.operator.arithmetic.js class: - match: \bclass\b scope: storage.type.class.js set: - 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 - include: else-pop - match: '{{identifier}}' scope: entity.name.class.js class-body: - meta_scope: meta.class.js meta.block.js - match: '\}' scope: punctuation.section.block.js pop: true - include: method-declaration constants: - match: \btrue\b scope: constant.language.boolean.true.js pop: true - match: \bfalse\b scope: constant.language.boolean.false.js pop: true - match: \bnull\b scope: constant.language.null.js pop: true - match: \bundefined\b scope: constant.language.undefined.js pop: true - match: \bNaN\b scope: constant.language.nan.js pop: true 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 set: - meta_scope: meta.function.declaration.js - match: '=' scope: keyword.operator.assignment.js - match: '(?={{func_lookahead}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration - include: else-pop - 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 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}})(\.)(prototype)\b' scope: meta.prototype.access.js captures: 1: support.class.js 2: punctuation.accessor.js 3: support.constant.prototype.js pop: true function-assignment: - match: '(?=(({{identifier}})\s*(\.)\s*)+({{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-identifiers - 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-single-identifier function-declaration-identifiers: - match: '(?={{identifier}}\s*\.)' push: - function-declaration-identifiers-expect-dot - function-declaration-identifiers-expect-class - include: function-declaration-final-identifier function-declaration-identifiers-expect-dot: - match: '\.' scope: punctuation.accessor.js pop: true - include: else-pop function-declaration-identifiers-expect-class: - 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 - include: else-pop 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}})' set: function-declaration - match: '(?={{arrow_func_lookahead}})' set: arrow-function-declaration function-declaration: - match: '' set: - function-declaration-expect-body - function-declaration-meta - function-declaration-expect-parameters - function-declaration-expect-name - function-declaration-expect-function-keyword - function-declaration-expect-async function-declaration-expect-body: - match: (?=\S) set: function-block function-declaration-meta: - meta_scope: meta.function.declaration.js - include: immediately-pop function-declaration-expect-parameters: - include: function-declaration-parameters - include: else-pop function-declaration-expect-name: - match: '{{identifier}}' scope: entity.name.function.js pop: true - include: else-pop function-declaration-expect-function-keyword: - match: \b(function)\b\s*(\*)? captures: 1: storage.type.function.js 2: keyword.generator.asterisk.js pop: true - include: else-pop function-declaration-expect-async: - match: '\basync\b' scope: storage.type.js pop: true - include: else-pop arrow-function-declaration: - match: '' set: - arrow-function-expect-body - function-declaration-meta - arrow-function-expect-arrow - arrow-function-expect-parameters - function-declaration-expect-async arrow-function-expect-body: - match: (?=\{) set: function-block - match: (?=\S) set: - block-meta - expression-no-comma arrow-function-expect-arrow: - match: '=>' scope: storage.type.function.arrow.js pop: true - include: else-pop arrow-function-expect-parameters: - match: '{{identifier}}' scope: variable.parameter.function.js pop: true - include: function-declaration-parameters - include: else-pop 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 - include: else-pop function-declaration-parameters: - match: \s+ scope: meta.function.declaration.js - match: \( scope: punctuation.section.group.begin.js push: - 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 - match: (?=\S) push: expression-no-comma - 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 - match: (?=\S) push: expression-no-comma label: - match: '({{identifier}})\s*(:)' captures: 1: entity.name.label.js 2: punctuation.separator.js object-literal: - match: '\{' scope: punctuation.section.block.js set: - meta_scope: meta.object-literal.js - match: '\}' scope: punctuation.section.block.js pop: true - match: >- (?x)(?= {{method_name}}\s*: (?: {{func_lookahead}} | {{arrow_func_lookahead}} ) ) push: - either-function-declaration - function-declaration-meta - object-literal-expect-colon - object-literal-meta-key - method-name - include: method-declaration - match: '{{identifier}}(?=\s*(?:[},]|$|//|/\*))' scope: variable.other.readwrite.js - match: \[ scope: punctuation.section.brackets.js push: - match: \] scope: punctuation.section.brackets.js pop: true - match: (?=\S) push: expression - match: "(?=\"|')" push: - object-literal-meta-key - literal-string - 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_scope: meta.object-literal.key.js - include: literal-number - include: comma-separator - match: ':' scope: punctuation.separator.key-value.js push: expression-no-comma object-literal-meta-key: - meta_scope: meta.object-literal.key.js - include: else-pop object-literal-expect-colon: - match: ':' scope: punctuation.separator.key-value.js - include: else-pop method-name: - match: '(\$)[_$[:alnum:]]*' scope: meta.object-literal.key.dollar.js entity.name.function.js captures: 1: punctuation.dollar.js pop: true - match: '{{identifier}}' scope: entity.name.function.js pop: true - match: "'" scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - 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 set: - meta_include_prototype: false - 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}}(?:\.{{identifier}}|\.)*)?(\])?' captures: 1: punctuation.definition.symbol.begin.js 2: entity.name.function.js 3: punctuation.definition.symbol.end.js pop: true - include: else-pop method-declaration: - match: |- (?x)(?= \b(?: get|set|async|static )\b | \* | {{method_name}} \s* \( ) push: - function-declaration-expect-body - function-declaration-meta - function-declaration-expect-parameters - method-name - method-declaration-expect-prefix method-declaration-expect-prefix: - match: \* scope: keyword.generator.asterisk.js - match: \b(get|set)\b(?!\s*\() scope: storage.type.accessor.js - match: \bstatic\b scope: storage.type.js - include: else-pop parenthesized-expression: - match: \( scope: punctuation.section.group.js set: - meta_scope: meta.group.js - match: \) scope: punctuation.section.group.js pop: true - match: (?=\S) push: expression - match: \) scope: invalid.illegal.stray-bracket-end.js pop: true function-call: - match: \( scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: \) scope: punctuation.section.group.js pop: true - match: (?=\S) push: expression array-literal: - match: '\[' scope: punctuation.section.brackets.js set: - meta_scope: meta.sequence.js - match: '\]' scope: punctuation.section.brackets.js pop: true - include: expression-list property-access: - match: '\[' scope: punctuation.section.brackets.js push: - meta_scope: meta.brackets.js - match: '\]' scope: punctuation.section.brackets.js pop: true - match: (?=\S) push: expression - 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 literal-number: - match: '(?i)(?:\B[-+]|\b)0x[0-9a-f]*\.(\B|\b[0-9]+)' scope: invalid.illegal.numeric.hex.js pop: true - match: '(?:\B[-+]|\b)0[0-9]+\.(\B|\b[0-9]+)' scope: invalid.illegal.numeric.octal.js pop: true - 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 pop: true - match: '(?:\B[-+]|\b)(Infinity)\b' scope: constant.language.infinity.js pop: true literal-call: - match: (\$)(?=\s*\() scope: variable.function.js variable.other.dollar.only.js punctuation.dollar.js set: - 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 set: - meta_scope: meta.function-call.js - include: function-call-params - match: '({{identifier}})(?=\s*\()' scope: variable.function.js set: - meta_scope: meta.function-call.js - include: function-call-params - match: '(?={{identifier}}\s*\.\s*{{identifier}}\s*\()' set: - 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 set: - 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 set: - meta_scope: meta.function-call.method.js - include: function-call-params - match: '({{identifier}})\s*(?=\()' scope: variable.function.js set: - meta_scope: meta.function-call.method.js - include: function-call-params function-call-params: - match: '\)' scope: meta.group.js punctuation.section.group.js pop: true - match: '\(' scope: punctuation.section.group.js push: - meta_scope: meta.group.js - match: '(?=\))' pop: true # 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 - match: (?=\S) push: expression-no-comma - include: else-pop literal-variable: - include: well-known-identifiers - include: language-identifiers - include: dollar-identifiers - include: support - match: '\b[[:upper:]][_$[:alnum:]]*(?=\s*[\[.])' scope: support.class.js pop: true - match: '{{identifier}}(?=\s*[\[.])' scope: variable.other.object.js pop: true - 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 pop: true - match: \b((Eval|Range|Reference|Syntax|Type|URI)?Error)\b scope: support.class.error.js pop: true - match: \b(document|window|navigator)\b scope: support.type.object.dom.js pop: true - 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 pop: true language-identifiers: - match: \b(arguments)\b scope: variable.language.arguments.js pop: true - match: \b(super)\b scope: variable.language.super.js pop: true - match: \b(this)\b scope: variable.language.this.js pop: true - match: \b(self)\b scope: variable.language.self.js pop: true dollar-identifiers: - match: '{{dollar_only_identifier}}' scope: variable.other.dollar.only.js punctuation.dollar.js pop: true - match: '{{dollar_identifier}}' scope: variable.other.dollar.js captures: 1: punctuation.dollar.js pop: true simple-identifiers: - match: '{{constant_identifier}}' scope: variable.other.constant.js pop: true - match: '{{identifier}}' scope: variable.other.readwrite.js pop: true support: - match: \bdebugger\b scope: keyword.other.js pop: true - 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 pop: true - 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 pop: true - 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 pop: true - 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 pop: true - match: \b(global|GLOBAL|root|__dirname|__filename)\b scope: support.type.object.node.js pop: true object-property: - match: \b__proto__\b scope: variable.language.proto.js pop: true - match: \bconstructor\b scope: variable.language.constructor.js pop: true - match: \bprototype\b scope: variable.language.prototype.js pop: true - match: '{{dollar_only_identifier}}' scope: meta.property.object.dollar.only.js punctuation.dollar.js pop: true - match: '{{dollar_identifier}}' scope: meta.property.object.dollar.js captures: 1: punctuation.dollar.js pop: true - match: '{{identifier}}' scope: meta.property.object.js pop: true - 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 pop: true - match: '(?=.|\n)' pop: true