diff --git a/JavaScript/JavaScript.sublime-syntax b/JavaScript/JavaScript.sublime-syntax index 8649005e42..3c80c8cecb 100644 --- a/JavaScript/JavaScript.sublime-syntax +++ b/JavaScript/JavaScript.sublime-syntax @@ -9,6 +9,9 @@ first_line_match: ^#!/.*\b(node|js)$\n? 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*=>' @@ -259,7 +262,7 @@ contexts: - include: constants - include: literal-prototype - include: named-function - - include: arrow-function + - include: anonymous-function - include: label - include: mustache - include: object-literal @@ -560,12 +563,36 @@ contexts: scope: constant.language.nan.js literal-prototype: - - match: '({{identifier}})(\.)(prototype)\s*=\s*' + - match: '({{identifier}})\s*(\.)\s*(prototype)(?=\s*=\s*)' 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: @@ -574,42 +601,90 @@ contexts: 3: support.constant.prototype.js named-function: - - match: '(?=(({{identifier}})\s*(\.)\s*)+({{identifier}})\s*(=)\s*{{func_lookahead}})' + - match: '(?=(({{identifier}})\s*(\.)\s*)+({{identifier}})\s*(=)\s*({{func_lookahead}}|{{arrow_func_lookahead}}))' push: - meta_scope: meta.function.declaration.js - - include: function-declaration-identifiers - match: '(?={{func_lookahead}})' set: function-declaration - - match: '(?={{func_lookahead}})' - push: function-declaration - - arrow-function: - - match: '(?=(({{identifier}})\s*(\.)\s*)+({{identifier}})\s*(=)\s*{{arrow_func_lookahead}})' + - 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 - - include: function-declaration-identifiers + - 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: arrow-function-declaration + push: + - meta_content_scope: meta.function.anonymous.js + - include: arrow-function-declaration function-declaration-identifiers: - - match: '(prototype)\s*(\.)' - captures: - 1: support.constant.prototype - 2: punctuation.accessor.js - - match: '(this)\s*(\.)' - captures: - 1: variable.language.this - 2: punctuation.accessor.js - - match: '({{identifier}})\s*(\.)' - captures: - 1: support.class.js - 2: punctuation.accessor.js - - match: '({{identifier}})\s*(=)\s*' + - 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: entity.name.function.js - 2: keyword.operator.assignment.js + 1: keyword.operator.assignment.js + - match: '(?={{identifier}})' + push: + # These matches have to be deplicated 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}})' @@ -904,6 +979,13 @@ contexts: - 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: \. @@ -941,40 +1023,23 @@ contexts: push: - 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: meta.delimiter.comma.js - include: expressions literal-variable: - include: well-known-identifiers + - include: language-identifiers + - include: dollar-identifiers - include: support - - match: '[A-Z][_$\dA-Z]*\b' - scope: variable.other.constant.js - - match: '(\$)\s*(=)\s*(?=({{func_lookahead}}|{{arrow_func_lookahead}}))' - scope: meta.function.declaration.js - captures: - 1: variable.other.dollar.only.js punctuation.dollar.js entity.name.function.js - 2: keyword.operator.assignment.js - - match: \$(?=\.|\s) - scope: variable.other.dollar.only.js punctuation.dollar.js - - match: '(\$)[$\w]*' - scope: variable.other.dollar.js - captures: - 1: punctuation.dollar.js - - match: '({{identifier}})(\.)(?={{identifier}})' - captures: - 1: variable.other.object.js - 2: punctuation.accessor.js - push: object-property - - match: '\b[A-Z][$\w]*(?=\s*\.)' + - match: '\b[[:upper:]][_$[:alnum:]]*(?=\s*[\[.])' scope: support.class.js - - match: '({{identifier}})\s*(=)\s*(?=({{func_lookahead}}|{{arrow_func_lookahead}}))' - scope: meta.function.declaration.js - captures: - 1: variable.other.readwrite.js entity.name.function.js - 2: keyword.operator.assignment.js - - match: '{{identifier}}(?=\s*[\[\.])' + - match: '{{identifier}}(?=\s*[\[.])' scope: variable.other.object.js - - match: '{{identifier}}' - scope: variable.other.readwrite.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 @@ -985,6 +1050,8 @@ contexts: 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 @@ -994,6 +1061,20 @@ contexts: - 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 @@ -1027,6 +1108,12 @@ contexts: 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 @@ -1043,18 +1130,14 @@ contexts: # 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}})' - scope: meta.function.declaration.js - captures: - 1: entity.name.function.js - 2: keyword.operator.assignment.js - set: function-declaration - - match: '({{identifier}})\s*(=)\s*(?={{arrow_func_lookahead}})' - scope: meta.function.declaration.js - captures: - 1: entity.name.function.js - 2: keyword.operator.assignment.js - set: arrow-function-declaration + - 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 diff --git a/JavaScript/Symbol List Banned.tmPreferences b/JavaScript/Symbol List Banned.tmPreferences index 3a5eeb15f2..b689a7d5d1 100644 --- a/JavaScript/Symbol List Banned.tmPreferences +++ b/JavaScript/Symbol List Banned.tmPreferences @@ -5,7 +5,7 @@ name Symbol List Banned scope - source.js meta.function-call, source.js meta.instance.constructor + source.js meta.function.anonymous settings showInIndexedSymbolList diff --git a/JavaScript/syntax_test_js.js b/JavaScript/syntax_test_js.js index 8169baf504..042bfb26be 100644 --- a/JavaScript/syntax_test_js.js +++ b/JavaScript/syntax_test_js.js @@ -44,14 +44,14 @@ function foo() { // <- meta.function.declaration // <- meta.function.declaration // <- meta.function.declaration -// ^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ storage.type.function // ^ entity.name.function } // <- meta.block var bar = function() { -// ^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- storage.type // ^ variable.other.readwrite entity.name.function // ^ storage.type.function @@ -61,7 +61,7 @@ baz = function*() // <- meta.function.declaration // <- meta.function.declaration // <- meta.function.declaration -// ^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- variable.other.readwrite entity.name.function // ^ storage.type.function // ^ keyword.generator.asterisk @@ -125,7 +125,7 @@ var obj = { // <- meta.object-literal.key.dollar punctuation.dollar // <- meta.object-literal.key.dollar - punctuation.dollar $keyFunc: function() { -// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- meta.object-literal.key.dollar entity.name.function punctuation.dollar // <- meta.object-literal.key.dollar entity.name.function - punctuation.dollar } @@ -138,54 +138,54 @@ var obj = { // ^ punctuation.separator.key-value - string funcKey: function() { -// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key entity.name.function }, func2Key: function func2Key() { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key entity.name.function }, funcKeyArrow: () => { -// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key entity.name.function }, "funcStringKey": function funcStringKey() -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key string.quoted.double entity.name.function { }, 'funcStringKey': function() { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key string.quoted.single entity.name.function }, 'funcStringKeyArrow': () => { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key string.quoted.single entity.name.function }, "func\\String2KeyArrow": (foo) => { -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.object-literal.key string.quoted.double entity.name.function // ^ constant.character.escape } qux() -// ^^^^^ meta.function.declaration +// ^^^^^ meta.function.declaration - meta.function.anonymous // <- entity.name.function {} static foo(bar) { -// ^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ storage.type // ^entity.name.function } *baz(){ -// ^^^^^^ meta.function.declaration +// ^^^^^^ meta.function.declaration - meta.function.anonymous // <- keyword.generator.asterisk // ^ entity.name.function } @@ -193,7 +193,7 @@ var obj = { // <- meta.object-literal - meta.block var $ = function(baz) { -// ^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ variable.other.dollar.only punctuation.dollar entity.name.function } @@ -303,7 +303,7 @@ class MyClass extends TheirClass { // ^^^^^^^ entity.name.type.class // ^ meta.block constructor(el) -// ^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ entity.name.function { // ^ meta.class meta.block meta.block meta.brace.curly @@ -313,7 +313,7 @@ class MyClass extends TheirClass { // ^ meta.class meta.block meta.block meta.brace.curly get foo() -// ^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- storage.type.accessor // ^ entity.name.function { @@ -321,19 +321,19 @@ class MyClass extends TheirClass { } static foo(baz) { -// ^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ storage.type // ^ entity.name.function } qux() -// ^^^^^ meta.function.declaration +// ^^^^^ meta.function.declaration - meta.function.anonymous { } // ^ meta.class meta.block meta.block meta.brace.curly get bar () { -// ^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ meta.class meta.block meta.block meta.brace.curly // <- storage.type.accessor // ^ entity.name.function @@ -341,7 +341,7 @@ class MyClass extends TheirClass { } baz() { return null } -// ^^^^^ meta.function.declaration +// ^^^^^ meta.function.declaration - meta.function.anonymous // <- entity.name.function } // <- meta.block @@ -355,45 +355,44 @@ class Foo extends React.Component { () => {} // <- meta.function.declaration punctuation.definition.parameters // <- meta.function.declaration punctuation.definition.parameters -//^^^ meta.function.declaration +//^^^ meta.function.anonymous meta.function.declaration // ^^ meta.block meta.brace.curly MyClass.foo = function() {} -// ^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ support.class // ^ entity.name.function MyClass.foo = () => {} -// ^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ support.class // ^ entity.name.function xhr.onload = function() {} -// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- support.class.js // ^ entity.name.function xhr.onload = () => {} -// ^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // <- support.class.js // ^ entity.name.function var simpleArrow = foo => bar -// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ entity.name.function // ^ variable.parameter.function // ^ storage.type.function.arrow var Proto = () => { -// ^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ entity.name.function // ^ storage.type.function.arrow this._var = 1; } Proto.prototype.getVar = () => this._var -// ^^^^^^^^^^^^ meta.prototype.access -// ^^^^^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ support.class // ^ support.constant.prototype // ^ entity.name.function @@ -401,7 +400,7 @@ Proto.prototype.getVar = () => this._var Class3.prototype = function() { // ^^^^^^^^^^^^^ meta.prototype.declaration -// ^^^^^^^^^^ meta.function.declaration +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function.anonymous // ^ support.class // ^ support.constant.prototype } @@ -428,7 +427,7 @@ var Constructor = function() { // ^ variable.language.this this._method = function() {} // ^ variable.language.this - // ^ entity.name.function + // ^ entity.name.function - meta.function.anonymous } // Tests to ensure the new keyword is highlighted properly even when the @@ -512,3 +511,43 @@ var angle = 2*π / count /* angle between circles */ a = /foo\/bar/g // Ensure handling of escape / in regex detection // ^ string.regexp // ^ constant.character.escape + +define(['common'], function(common) { +// ^ meta.function.anonymous meta.function.declaration + var namedFunc = function() { +// ^ meta.function.declaration - meta.function.anonymous + } +}); + +new FooBar(function(){ +// ^ meta.function.anonymous meta.function.declaration + var namedFunc2 = function() { +// ^ meta.function.declaration - meta.function.anonymous + } +}) + +['foo'].bar = function() { +// ^ meta.property.object entity.name.function - meta.function.anonymous +} + +['foo'].$ = function() { +// ^ meta.property.object.dollar.only entity.name.function - meta.function.anonymous +} + +['foo'].$bar = function() { +// ^ meta.property.object.dollar entity.name.function - meta.function.anonymous +} + +$.each() +// <- variable.other.object.dollar.only punctuation.dollar + +$varname.method() +// <- variable.other.object.dollar punctuation.dollar - variable.other.object.dollar.only +// ^ variable.other.object.dollar + +$.fn.new_plugin = function() {} +// <- support.class.dollar.only punctuation.dollar + +$var.fn.name = () => {} +// <- support.class.dollar punctuation.dollar - support.class.dollar.only +// ^ support.class.dollar - punctuation.dollar