Permalink
Fetching contributors…
Cannot retrieve contributors at this time
1433 lines (1347 sloc) 47.9 KB
%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.definition.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.definition.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.definition.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.definition.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: (<!--|-->)
scope: comment.block.html.js punctuation.definition.comment.js
- match: ^(#!).*$\n?
scope: comment.line.shebang.js
captures:
1: punctuation.definition.comment.js
statements:
- include: conditional
- match: '\{(?!\{)'
scope: punctuation.definition.block.js
push:
- meta_scope: meta.block.js
- match: '\}'
scope: punctuation.definition.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.definition.block.js
pop: true
- match: '\{'
scope: punctuation.definition.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.definition.block.js
push:
- meta_scope: meta.block.js
- match: '\}'
scope: punctuation.definition.block.js
pop: true
- include: statements
- match: \bwhile\b
scope: keyword.control.loop.js
- match: '\('
scope: punctuation.definition.group.js
push:
- meta_scope: meta.group.js
- match: '(?=\))'
pop: true
- include: expressions
- match: '\)'
scope: meta.group.js punctuation.definition.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.definition.group.js
push:
- meta_scope: meta.group.js
- match: '\)'
scope: punctuation.definition.group.js
pop: true
- include: expressions
- include: block-scope
block-scope:
- include: comments
- match: '\}'
scope: meta.block.js punctuation.definition.block.js
pop: true
- match: '\{'
scope: punctuation.definition.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: mustache
- 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
- 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:
- include: special-comments-conditional-compilation
- 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
special-comments-conditional-compilation:
- match: /\*(?=@)
scope: punctuation.definition.comment.js
push:
- meta_scope: comment.block.conditional.js
- match: \*/
scope: punctuation.definition.comment.js
pop: true
- match: /\*
scope: punctuation.definition.comment.js
- include: main
- match: (@)(if|elif|else|end|ifdef|endif|cc_on|set)\b
scope: keyword.control.conditional.js
captures:
1: punctuation.definition.keyword.js
- match: '(@)(_win32|_win16|_mac|_alpha|_x86|_mc680x0|_PowerPC|_jscript_build|_jscript_version|_jscript|_debug|_fast|[a-zA-Z]\w+)'
scope: variable.other.conditional.js
captures:
1: punctuation.definition.variable.js
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:
- 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.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.definition.group.js
set:
- meta_scope: meta.instance.constructor.js meta.function-call.constructor.js meta.group.js
- match: '\)'
scope: punctuation.definition.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.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.definition.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.definition.block.js
pop: true
- include: method-declaration
keywords:
- 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.definition.block.js
pop: true
- match: '\{'
scope: punctuation.definition.block.js
push:
- match: '(?=\})'
pop: true
- include: statements
function-declaration-parameters:
- match: \(
scope: punctuation.definition.parameters.begin.js
push:
- meta_scope: meta.function.declaration.js
- match: \)
scope: punctuation.definition.parameters.end.js
pop: true
# Destructuring
- match: \{
scope: punctuation.definition.block.begin.js
push:
- meta_scope: meta.block.js
- match: \}
scope: punctuation.definition.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
mustache:
- match: '\{\{'
push:
- meta_scope: meta.tag.mustache.js
- match: '\}\}'
pop: true
object-literal:
- match: '\{'
scope: punctuation.definition.block.js
push:
- meta_scope: meta.object-literal.js
- match: '\}'
scope: punctuation.definition.block.js
set: after-identifier
- include: comments
- match: \[
scope: punctuation.definition.brackets.js
push:
- match: \]
scope: punctuation.definition.brackets.js
pop: true
- include: expressions
- match: '({{identifier}})\s*(\})'
captures:
1: variable.other.readwrite.js
2: punctuation.definition.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
- 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: method-declaration
- 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.definition.block.js
push:
- meta_scope: meta.block.js
- match: '\}'
scope: punctuation.definition.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.definition.block.js
push:
- meta_scope: meta.block.js
- match: '\}'
scope: punctuation.definition.block.js
pop: true
- include: statements
- include: comments
- match: '(?=\S)'
pop: true
brackets:
- include: round-brackets
- include: square-brackets
round-brackets:
- match: \(
scope: punctuation.definition.group.js
push:
- meta_scope: meta.group.js
- match: \)
scope: punctuation.definition.group.js
set: after-identifier
- include: expressions
- match: \)
scope: invalid.illegal.stray-bracket-end.js
square-brackets:
- match: '\['
scope: punctuation.definition.brackets.js
push:
- meta_scope: meta.brackets.js
- match: '\]'
scope: punctuation.definition.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.definition.group.js
set: after-identifier
- match: '\('
scope: punctuation.definition.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)\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