# "?." means "?." or "." # Even though sometimes it doesn't seem like using the chaining operator would make any sense, it's still supported. # Example: Math?.PI # Negative look-behinds for "." should cover "?." 'scopeName': 'source.js' 'fileTypes': [ 'js' '_js' 'cjs' 'es' 'es6' 'gs' 'htc' 'jscad' 'jscript' 'jse' 'jslib' 'jsm' 'json5' 'jspre' 'mjs' 'pac' 'pjs' 'sjs' 'snap' 'xsjs' 'xsjslib' ] 'firstLineMatch': '''(?x) # Hashbang ^\\#!.*(?:\\s|\\/|(?<=!)\\b) (?:node|iojs|JavaScript) (?:$|\\s) | # Modeline (?i: # Emacs -\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*) (?:js|javascript) (?=[\\s;]|(?]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s*set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*= javascript (?=\\s|:|$) ) ''' 'name': 'JavaScript' 'patterns': [ { # ES6 import 'begin': '(? [expression|{statements}] 'begin': '''(?x) (?= (? ) ''' 'end': '''(?x) (?<=})| ((?! \\s*{| \\G\\(| \\G[\\w$]+| \\s*/\\*|\\s*// )(?=\\s*\\S)) ''' 'patterns': [ { 'include': '#comments' } { 'include': '#function_body' } { 'begin': '\\G' 'end': '(?<=(=>))' 'name': 'meta.function.arrow.js' 'patterns': [ { 'include': '#arrow_function_innards' } ] } ] } { # [?.]foo = ... => ... 'begin': '''(?x) (?= (\\?\\.|\\.)?[a-zA-Z_$][\\w$]* \\s*(=)\\s* ((\\(([^\\(\\)]*)?\\))|[\\w$]+) \\s*=> ) ''' 'end': '''(?x) (?<=})| ((?! \\s*{| \\G(\\?\\.|\\.)?[a-zA-Z_$][\\w$]*\\s*(=)\\s*\\(| \\G(\\?\\.|\\.)?[a-zA-Z_$][\\w$]*\\s*(=)\\s*[\\w$]+| \\s*/\\*|\\s*// )(?=\\s*\\S)) ''' 'patterns': [ { 'include': '#comments' } { 'include': '#function_body' } { 'begin': '\\G' 'end': '(?<=(=>))' 'name': 'meta.function.arrow.js' 'patterns': [ { 'match': '\\G(\\?\\.|\\.)?([a-zA-Z_$][\\w$]*)\\s*(=)' 'captures': '1': 'patterns': [ { 'include': '#period_or_illegal_optional_method' } ] '2': 'name': 'entity.name.function.js' '3': 'name': 'keyword.operator.assignment.js' } { 'include': '#arrow_function_innards' } ] } ] } { # foo: ... => ... 'begin': '''(?x) (?= \\b[a-zA-Z_$][\\w$]* \\s*:\\s* ((\\(([^\\(\\)]*)?\\))|[\\w$]+) \\s*=> ) ''' 'end': '''(?x) (?<=})| ((?! \\s*{| \\G[\\w$]+\\s*:| \\s*/\\*|\\s*// )(?=\\s*\\S)) ''' 'patterns': [ { 'include': '#comments' } { 'include': '#function_body' } { 'begin': '\\G' 'end': '(?<=(=>))' 'name': 'meta.function.arrow.json.js' 'patterns': [ { 'match': '\\b([a-zA-Z_$][\\w$]*)\\s*(:)\\s*' 'captures': '1': 'name': 'entity.name.function.js' '2': 'name': 'keyword.operator.assignment.js' } { 'include': '#arrow_function_innards' } ] } ] } { # "foo": ... => ... 'begin': '''(?x) (?= ((\'[^\']*?\')|("[^"]*?")) \\s*:\\s* ((\\(([^\\(\\)]*)?\\))|[\\w$]+) \\s*=> ) ''' 'end': '''(?x) (?<=})| ((?! \\G((\'[^\']*?\')|("[^"]*?"))| \\s*{| \\s*/\\*|\\s*// )(?=\\s*\\S)) ''' 'patterns': [ { 'include': '#comments' } { 'include': '#function_body' } { 'begin': '\\G' 'end': '(?<=(=>))' 'name': 'meta.function.arrow.json.js' 'patterns': [ { 'match': '(?:((\')([^\']*?)(\'))|((")([^"]*?)(")))\\s*(:)' 'captures': '1': 'name': 'string.quoted.single.js' '2': 'name': 'punctuation.definition.string.begin.js' '3': 'name': 'entity.name.function.js' '4': 'name': 'punctuation.definition.string.end.js' '5': 'name': 'string.quoted.double.js' '6': 'name': 'punctuation.definition.string.begin.js' '7': 'name': 'entity.name.function.js' '8': 'name': 'punctuation.definition.string.end.js' '9': 'name': 'keyword.operator.assignment.js' } { 'include': '#arrow_function_innards' } ] } ] } { 'match': '(=>)' 'captures': '0': 'name': 'meta.function.arrow.js' '1': 'name': 'storage.type.function.arrow.js' } { 'match': '''(?x) \\b(class) (?: (?:\\s+(extends)\\s+([a-zA-Z_$][\\w$]*)) | (?: (?:\\s+([a-zA-Z_$][\\w$]*)) (?:\\s+(extends)\\s+([a-zA-Z_$][\\w$]*))? ) ) ''' 'captures': '1': 'name': 'storage.type.class.js' '2': 'name': 'storage.modifier.js' '3': 'name': 'entity.other.inherited-class.js' '4': 'name': 'entity.name.type.class.js' '5': 'name': 'storage.modifier.js' '6': 'name': 'entity.other.inherited-class.js' 'name': 'meta.class.js' } { 'match': '(new)\\s+([\\w$]+(?:\\??\\.[\\w$]*)*)' 'name': 'meta.class.instance.constructor.js' 'captures': '1': 'name': 'keyword.operator.new.js' '2': 'name': 'entity.name.type.instance.js' 'patterns': [ { 'include': '#period_or_illegal_optional_property' } ] } { # console # console.log(arg1, "arg2", [...]) 'begin': '(?)' 'captures': '0': 'name': 'punctuation.definition.comment.html.js' '2': 'name': 'punctuation.definition.comment.html.js' 'name': 'comment.block.html.js' } { 'match': '(?|&&|\\|\\|)\\s*(/)(?![/*+?])(?=.*/)' 'beginCaptures': '1': 'name': 'punctuation.definition.string.begin.js' 'end': '(/)([gimsuy]*)' 'endCaptures': '1': 'name': 'punctuation.definition.string.end.js' '2': 'name': 'meta.flag.regexp' 'name': 'string.regexp.js' 'patterns': [ { 'include': 'source.js.regexp' } ] } { 'begin': '(?>=|>>>=' 'name': 'keyword.operator.assignment.compound.bitwise.shift.js' } # Bitwise shift to match >> instead of > # Then comparison to match != instead of ! { 'match': '<<|>>>|>>' 'name': 'keyword.operator.bitwise.shift.js' } { 'match': '!==|!=|<=|>=|===|==|<|>' 'name': 'keyword.operator.comparison.js' } { # One of: && !! ! || ?? 'match': '&&|!!|!|\\|\\||\\?\\?' 'name': 'keyword.operator.logical.js' } { 'match': '&|\\||\\^|~' 'name': 'keyword.operator.bitwise.js' } { 'match': '=|:' 'name': 'keyword.operator.assignment.js' } { 'match': '--' 'name': 'keyword.operator.decrement.js' } { 'match': '\\+\\+' 'name': 'keyword.operator.increment.js' } { 'match': '%|\\*\\*|\\*|/|-|\\+' 'name': 'keyword.operator.js' } ] 'strings': 'patterns': [ { 'begin': '\'' 'beginCaptures': '0': 'name': 'punctuation.definition.string.begin.js' 'end': '\'' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.single.js' 'patterns': [ { 'include': '#string_escapes' } ] } { 'begin': '"' 'beginCaptures': '0': 'name': 'punctuation.definition.string.begin.js' 'end': '"' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.double.js' 'patterns': [ { 'include': '#string_escapes' } ] } { 'begin': '((\\w+)?(html|HTML|Html))\\s*(`)' 'beginCaptures': '1': 'name': 'entity.name.function.js' '4': 'name': 'punctuation.definition.string.begin.js' 'end': '`' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.template.html.js' 'patterns': [ { 'include': '#string_escapes' } { 'include': '#interpolated_js' } { 'include': 'text.html.basic' } ] } { 'begin': '(?<=innerHTML)\\s*(\\+?=)\\s*(?=`)' 'beginCaptures': '1': 'name': 'keyword.operator.assignment.js' 'end': '(?<=`)' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'contentName': 'string.quoted.template.html.js' 'patterns': [ { 'begin': '`' 'beginCaptures': '0': 'name': 'punctuation.definition.string.begin.js' 'end': '`' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'patterns': [ { 'include': '#string_escapes' } { 'include': '#interpolated_js' } { 'include': 'text.html.basic' } ] } ] } { 'begin': '(Relay(\\?\\.|\\.)QL|gql)\\s*(`)' 'beginCaptures': '1': 'name': 'entity.name.function.js' '2': 'patterns': [ { 'include': '#period_or_optional_method' } ] '3': 'name': 'punctuation.definition.string.begin.js' 'end': '`' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.template.graphql.js' 'patterns': [ { 'include': '#string_escapes' } { 'include': '#interpolated_js' } { 'include': 'source.graphql' } ] } { 'begin': '(sql|SQL|Sql)\\s*(`)' 'beginCaptures': '1': 'name': 'entity.name.function.js' '2': 'name': 'punctuation.definition.string.begin.js' 'end': '`' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.template.sql.js' 'patterns': [ { 'include': '#string_escapes' } { 'include': '#interpolated_js' } { 'include': 'source.sql' } ] } { 'begin': '`' 'beginCaptures': '0': 'name': 'punctuation.definition.string.begin.js' 'end': '`' 'endCaptures': '0': 'name': 'punctuation.definition.string.end.js' 'name': 'string.quoted.template.js' 'patterns': [ { 'include': '#string_escapes' } { 'include': '#interpolated_js' } ] } ] 'string_escapes': 'patterns': [ { 'match': '\\\\u(?![A-Fa-f0-9]{4}|{[A-Fa-f0-9]+})[^\'"]*' 'name': 'invalid.illegal.unicode-escape.js' } { 'match': '\\\\u(?:[A-Fa-f0-9]{4}|({)([A-Fa-f0-9]+)(}))' 'name': 'constant.character.escape.js' 'captures': '1': 'name': 'punctuation.definition.unicode-escape.begin.bracket.curly.js' '2': 'patterns': [ { # Max codepoint: \u{10FFFF} 'match': '[A-Fa-f\\d]{7,}|(?!10)[A-Fa-f\\d]{6}' 'name': 'invalid.illegal.unicode-escape.js' } ] '3': 'name': 'punctuation.definition.unicode-escape.end.bracket.curly.js' } { 'match': '\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)' 'name': 'constant.character.escape.js' } ] 'function_params': 'patterns': [ { 'begin': '\\(' 'beginCaptures': '0': 'name': 'punctuation.definition.parameters.begin.bracket.round.js' 'end': '\\)' 'endCaptures': '0': 'name': 'punctuation.definition.parameters.end.bracket.round.js' 'name': 'meta.parameters.js' 'patterns': [ { 'match': '(\\.\\.\\.)([a-zA-Z_$][\\w$]*)' 'captures': '1': 'name': 'keyword.operator.rest.js' '2': 'name': 'variable.parameter.rest.function.js' } { 'include': '$self' } { 'match': '[a-zA-Z_$][\\w$]*' 'name': 'variable.parameter.function.js' } ] } { # Or starting with optional chaining 'begin': '(\\?\\.)(\\()' 'beginCaptures': '1': 'name': 'meta.delimiter.method.optional.js' '2': 'name': 'punctuation.definition.parameters.begin.bracket.round.js' 'end': '\\)' 'endCaptures': '0': 'name': 'punctuation.definition.parameters.end.bracket.round.js' 'name': 'meta.parameters.js' 'patterns': [ { 'match': '(\\.\\.\\.)([a-zA-Z_$][\\w$]*)' 'captures': '1': 'name': 'keyword.operator.rest.js' '2': 'name': 'variable.parameter.rest.function.js' } { 'include': '$self' } { 'match': '[a-zA-Z_$][\\w$]*' 'name': 'variable.parameter.function.js' } ] } ] 'function_body': 'patterns': [ { 'begin': '{' 'beginCaptures': '0': 'name': 'punctuation.definition.function.body.begin.bracket.curly.js' 'end': '}' 'endCaptures': '0': 'name': 'punctuation.definition.function.body.end.bracket.curly.js' 'patterns': [ { 'include': '$self' } ] } ] 'function_innards': 'patterns': [ { 'match': '(?:\\b(async)\\b\\s*)?\\b(function)\\b(?:\\s*(\\*))?' 'captures': '1': 'name': 'storage.modifier.async.js' '2': 'name': 'storage.type.function.js' '3': 'name': 'storage.modifier.generator.js' } { 'match': '[a-zA-Z_$][\\w$]*(?=\\s*\\()' 'name': 'entity.name.function.js' } { 'include': '#function_params' } { 'include': '#comments' } ] 'arrow_function_innards': 'patterns': [ { 'match': '=>' 'name': 'storage.type.function.arrow.js' } { 'include': '#function_params' } { 'match': '([a-zA-Z_$][\\w$]*)(?=\\s*=>)' 'captures': '0': 'name': 'meta.parameters.js' '1': 'name': 'variable.parameter.function.js' } { 'match': '(\\d[\\w$]*)' 'captures': '0': 'name': 'meta.parameters.js' '1': 'name': 'invalid.illegal.identifier.js' } ] 'arguments': 'patterns': [ { 'begin': '\\(' 'beginCaptures': '0': 'name': 'punctuation.definition.arguments.begin.bracket.round.js' 'end': '\\)' 'endCaptures': '0': 'name': 'punctuation.definition.arguments.end.bracket.round.js' 'name': 'meta.arguments.js' 'patterns': [ { 'include': '$self' } ] } ] 'method_calls': 'patterns': [ { # [?].methodCall(arg1, "arg2", [...]) 'begin': '(\\?\\.|\\.)\\s*([\\w$]+)\\s*(?=\\()' 'beginCaptures': '1': 'patterns': [ { 'include': '#period_or_optional_method' } ] '2': 'patterns': [ { 'include': '#method_names' } ] 'end': '(?<=\\))' 'name': 'meta.method-call.js' 'patterns': [ { 'include': '#arguments' } ] } { # [?].methodCall?.(arg1, "arg2", [...]) 'begin': '(\\?\\.|\\.)\\s*([\\w$]+)\\s*(\\?\\.)\\s*(?=\\()' 'beginCaptures': '1': 'patterns': [ { 'include': '#period_or_optional_method' } ] '2': 'patterns': [ { 'include': '#method_names' } ] '3': 'name': 'meta.delimiter.method.optional.js' 'end': '(?<=\\))' 'name': 'meta.method-call.js' 'patterns': [ { 'include': '#arguments' } ] } { # [array]?.(arg1, "arg2", [...]) # The array itself is not in the method-call scope, maybe later 'begin': '(?<=\\])\\s*(\\?\\.)\\s*(?=\\()' 'beginCaptures': '1': 'name': 'meta.delimiter.method.optional.js' 'end': '(?<=\\))' 'name': 'meta.method-call.js' 'patterns': [ { 'include': '#arguments' } ] } ] 'method_names': 'patterns': [ { 'match': '''(?x) \\bon(Rowsinserted|Rowsdelete|Rowenter|Rowexit|Resize|Resizestart|Resizeend|Reset| Readystatechange|Mouseout|Mouseover|Mousedown|Mouseup|Mousemove| Before(cut|deactivate|unload|update|paste|print|editfocus|activate)| Blur|Scrolltop|Submit|Select|Selectstart|Selectionchange|Hover|Help| Change|Contextmenu|Controlselect|Cut|Cellchange|Clock|Close|Deactivate| Datasetchanged|Datasetcomplete|Dataavailable|Drop|Drag|Dragstart|Dragover| Dragdrop|Dragenter|Dragend|Dragleave|Dblclick|Unload|Paste|Propertychange|Error| Errorupdate|Keydown|Keyup|Keypress|Focus|Load|Activate|Afterupdate|Afterprint|Abort)\\b ''' 'name': 'support.function.event-handler.js' } { 'match': '''(?x) \\b(catch|finally|then|shift|showModelessDialog|showModalDialog|showHelp|scroll|scrollX|scrollByPages| scrollByLines|scrollY|scrollTo|stop|strike|sizeToContent|sidebar|signText|sort| sup|sub|substr|substring|splice|split|send|set(Milliseconds|Seconds|Minutes|Hours| Month|Year|FullYear|Date|UTC(Milliseconds|Seconds|Minutes|Hours|Month|FullYear|Date)| Time|Hotkeys|Cursor|ZOptions|Active|Resizable|RequestHeader)|search|slice| savePreferences|small|home|handleEvent|navigate|char|charCodeAt|charAt|concat| contextual|confirm|compile|clear|captureEvents|call|createStyleSheet|createPopup| createEventObject|to(GMTString|UTCString|String|Source|UpperCase|LowerCase|LocaleString)| test|taint|taintEnabled|indexOf|italics|disableExternalCapture|dump|detachEvent|unshift| untaint|unwatch|updateCommands|join|javaEnabled|pop|push|plugins.refresh|paddings|parse|stringify| print|prompt|preference|enableExternalCapture|exec|execScript|valueOf|UTC|find|file| fileModifiedDate|fileSize|fileCreatedDate|fileUpdatedDate|fixed|fontsize|fontcolor| forward|fromCharCode|watch|link|load|lastIndexOf|anchor|attachEvent|atob|apply|alert| abort|routeEvents|resize|resizeBy|resizeTo|recalc|returnValue|replace|reverse|reload| releaseCapture|releaseEvents|go|get(Milliseconds|Seconds|Minutes|Hours|Month|Day|Year|FullYear| Time|Date|TimezoneOffset|UTC(Milliseconds|Seconds|Minutes|Hours|Day|Month|FullYear|Date)| Attention|Selection|ResponseHeader|AllResponseHeaders)|moveBy|moveBelow|moveTo| moveToAbsolute|moveAbove|mergeAttributes|match|margins|btoa|big|bold|borderWidths|blink|back)\\b ''' 'name': 'support.function.js' } { 'match': '''(?x) \\b(acceptNode|add|addEventListener|addTextTrack|adoptNode|after|animate|append| appendChild|appendData|before|blur|canPlayType|captureStream| caretPositionFromPoint|caretRangeFromPoint|checkValidity|clear|click| cloneContents|cloneNode|cloneRange|close|closest|collapse| compareBoundaryPoints|compareDocumentPosition|comparePoint|contains| convertPointFromNode|convertQuadFromNode|convertRectFromNode|createAttribute| createAttributeNS|createCaption|createCDATASection|createComment| createContextualFragment|createDocument|createDocumentFragment| createDocumentType|createElement|createElementNS|createEntityReference| createEvent|createExpression|createHTMLDocument|createNodeIterator| createNSResolver|createProcessingInstruction|createRange|createShadowRoot| createTBody|createTextNode|createTFoot|createTHead|createTreeWalker|delete| deleteCaption|deleteCell|deleteContents|deleteData|deleteRow|deleteTFoot| deleteTHead|detach|disconnect|dispatchEvent|elementFromPoint|elementsFromPoint| enableStyleSheetsForSet|entries|evaluate|execCommand|exitFullscreen| exitPointerLock|expand|extractContents|fastSeek|firstChild|focus|forEach|get| getAll|getAnimations|getAttribute|getAttributeNames|getAttributeNode| getAttributeNodeNS|getAttributeNS|getBoundingClientRect|getBoxQuads| getClientRects|getContext|getDestinationInsertionPoints|getElementById| getElementsByClassName|getElementsByName|getElementsByTagName| getElementsByTagNameNS|getItem|getNamedItem|getSelection|getStartDate| getVideoPlaybackQuality|has|hasAttribute|hasAttributeNS|hasAttributes| hasChildNodes|hasFeature|hasFocus|importNode|initEvent|insertAdjacentElement| insertAdjacentHTML|insertAdjacentText|insertBefore|insertCell|insertData| insertNode|insertRow|intersectsNode|isDefaultNamespace|isEqualNode| isPointInRange|isSameNode|item|key|keys|lastChild|load|lookupNamespaceURI| lookupPrefix|matches|move|moveAttribute|moveAttributeNode|moveChild| moveNamedItem|namedItem|nextNode|nextSibling|normalize|observe|open| parentNode|pause|play|postMessage|prepend|preventDefault|previousNode| previousSibling|probablySupportsContext|queryCommandEnabled| queryCommandIndeterm|queryCommandState|queryCommandSupported|queryCommandValue| querySelector|querySelectorAll|registerContentHandler|registerElement| registerProtocolHandler|releaseCapture|releaseEvents|remove|removeAttribute| removeAttributeNode|removeAttributeNS|removeChild|removeEventListener| removeItem|replace|replaceChild|replaceData|replaceWith|reportValidity| requestFullscreen|requestPointerLock|reset|scroll|scrollBy|scrollIntoView| scrollTo|seekToNextFrame|select|selectNode|selectNodeContents|set|setAttribute| setAttributeNode|setAttributeNodeNS|setAttributeNS|setCapture| setCustomValidity|setEnd|setEndAfter|setEndBefore|setItem|setNamedItem| setRangeText|setSelectionRange|setSinkId|setStart|setStartAfter|setStartBefore| slice|splitText|stepDown|stepUp|stopImmediatePropagation|stopPropagation| submit|substringData|supports|surroundContents|takeRecords|terminate|toBlob| toDataURL|toggle|toString|values|write|writeln)\\b ''' 'name': 'support.function.dom.js' } { 'match': "[a-zA-Z_$][\\w$]*" 'name': 'entity.name.function.js' } { 'match': '\\d[\\w$]*' 'name': 'invalid.illegal.identifier.js' } ] 'function_calls': 'patterns': [ { # functionCall(arg1, "arg2", [...]) 'begin': '([\\w$]+)\\s*(?=\\()' 'beginCaptures': '1': 'patterns': [ { 'match': '''(?x) \\b(isNaN|isFinite|eval|uneval|parseInt|parseFloat|decodeURI| decodeURIComponent|encodeURI|encodeURIComponent|escape|unescape| require|set(Interval|Timeout)|clear(Interval|Timeout))\\b ''' 'name': 'support.function.js' } { 'match': "[a-zA-Z_$][\\w$]*" 'name': 'entity.name.function.js' } { 'match': '\\d[\\w$]*' 'name': 'invalid.illegal.identifier.js' } ] 'end': '(?<=\\))' 'name': 'meta.function-call.js' 'patterns': [ { 'include': '#arguments' } ] } { # functionCall?.(arg1, "arg2", [...]) 'begin': '([\\w$]+)\\s*(\\?\\.)(?=\\()' 'beginCaptures': '1': 'patterns': [ { 'match': '''(?x) \\b(isNaN|isFinite|eval|uneval|parseInt|parseFloat|decodeURI| decodeURIComponent|encodeURI|encodeURIComponent|escape|unescape| require|set(Interval|Timeout)|clear(Interval|Timeout))\\b ''' 'name': 'support.function.js' } { 'match': "[a-zA-Z_$][\\w$]*" 'name': 'entity.name.function.js' } { 'match': '\\d[\\w$]*' 'name': 'invalid.illegal.identifier.js' } ] '2': 'name': 'meta.delimiter.method.optional.js' 'end': '(?<=\\))' 'name': 'meta.function-call.js' 'patterns': [ { 'include': '#arguments' } ] } ] 'objects': 'patterns': [ # "Obj." is already enough to prove objectness, # however "Obj.[8]" is impossible, and # "Obj?.()" is a function { # OBJ in OBJ.prop, OBJ.methodCall() 'match': '[A-Z][A-Z0-9_$]*(?=\\s*\\??\\.\\s*[a-zA-Z_$]\\w*)' 'name': 'constant.other.object.js' } { # obj in obj.prop, obj.methodCall() 'match': '[a-zA-Z_$][\\w$]*(?=\\s*\\??\\.\\s*[a-zA-Z_$]\\w*)' 'name': 'variable.other.object.js' } { # OBJ in OBJ[8], OBJ?.[8] 'match': '[A-Z][A-Z0-9_$]*(?=\\s*(\\?\\.)?\\s*\\[)' 'name': 'constant.other.object.js' } { # obj in obj[8], obj?.[8] 'match': '[a-zA-Z_$][\\w$]*(?=\\s*(\\?\\.)?\\s*\\[)' 'name': 'variable.other.object.js' } ] 'properties': 'patterns': [ # object.prop includes object?.prop { # Specifically ?.[], for example divArray?.[8] 'begin': '(\\?\\.)\\s*(\\[)' 'beginCaptures': '1': 'name': 'meta.delimiter.property.optional.js' '2': 'name': 'meta.brace.square.js' 'end': '\\]' 'endCaptures': '0': 'name': 'meta.brace.square.js' 'patterns': [ { 'include': '$self' } ] } { # PROP1 in obj.PROP1.prop2, func().PROP1.prop2 'match': '(\\?\\.|\\.)\\s*([A-Z][A-Z0-9_$]*\\b\\$*)(?=\\s*(\\?\\.|\\.)\\s*[a-zA-Z_$]\\w*)' 'captures': '1': 'patterns': [ { 'include': '#period_or_optional_property' } ] '2': 'name': 'constant.other.object.property.js' } { # prop1 in obj.prop1.prop2, func().prop1.prop2 'match': '(\\?\\.|\\.)\\s*(\\$*[a-zA-Z_$][\\w$]*)(?=\\s*(\\?\\.|\\.)\\s*[a-zA-Z_$]\\w*)' 'captures': '1': 'patterns': [ { 'include': '#period_or_optional_property' } ] '2': 'name': 'variable.other.object.property.js' } { # PROP in obj.PROP, func().PROP 'match': '(\\?\\.|\\.)\\s*([A-Z][A-Z0-9_$]*\\b\\$*)' 'captures': '1': 'patterns': [ { 'include': '#period_or_optional_property' } ] '2': 'name': 'constant.other.property.js' } { # prop in obj.prop, func().prop 'match': '(\\?\\.|\\.)\\s*(\\$*[a-zA-Z_$][\\w$]*)' 'captures': '1': 'patterns': [ { 'include': '#period_or_optional_property' } ] '2': 'name': 'variable.other.property.js' } { # 123illegal in obj.123illegal, func().123illegal 'match': '(\\?\\.|\\.)\\s*([0-9][\\w$]*)' 'captures': '1': 'patterns': [ { 'include': '#period_or_optional_property' } ] '2': 'name': 'invalid.illegal.identifier.js' } ] 'interpolated_js': 'patterns': [ { 'begin': '\\${' 'captures': '0': 'name': 'punctuation.section.embedded.js' 'end': '}' 'name': 'source.js.embedded.source' 'patterns': [ { 'begin': '{' 'beginCaptures': '0': 'name': 'meta.brace.curly.js' 'end': '}' 'endCaptures': '0': 'name': 'meta.brace.curly.js' 'patterns': [ { 'include': '$self' } ] } { 'include': '$self' } ] } ] 'comments': 'patterns': [ { 'captures': '1': 'name': 'punctuation.definition.comment.begin.js' '2': 'name': 'punctuation.definition.comment.end.js' 'match': '(/\\*)(\\*/)' 'name': 'comment.block.empty.js' } { 'begin': '/\\*\\*' 'beginCaptures': '0': 'name': 'punctuation.definition.comment.begin.js' 'end': '\\*/' 'endCaptures': '0': 'name': 'punctuation.definition.comment.end.js' 'name': 'comment.block.documentation.js' 'patterns': [ { 'include': 'source.jsdoc' } ] } { 'begin': '/\\*' 'beginCaptures': '0': 'name': 'punctuation.definition.comment.begin.js' 'end': '\\*/' 'endCaptures': '0': 'name': 'punctuation.definition.comment.end.js' 'name': 'comment.block.js' } { 'begin': '//' 'beginCaptures': '0': 'name': 'punctuation.definition.comment.js' 'end': '$' 'name': 'comment.line.double-slash.js' } ] 'switch_statement': 'patterns': [ { # switch(expression) {...} 'begin': '\\bswitch\\b' 'beginCaptures': '0': 'name': 'keyword.control.switch.js' 'end': '}' 'endCaptures': '0': 'name': 'punctuation.definition.section.switch-block.end.bracket.curly.js' 'name': 'meta.switch-statement.js' 'patterns': [ { 'begin': '\\(' 'beginCaptures': '0': 'name': 'punctuation.definition.switch-expression.begin.bracket.round.js' 'end': '\\)' 'endCaptures': '0': 'name': 'punctuation.definition.switch-expression.end.bracket.round.js' 'patterns': [ 'include': '$self' ] } { 'begin': '{' 'beginCaptures': '0': 'name': 'punctuation.definition.section.switch-block.begin.bracket.curly.js' 'end': '(?=})' 'patterns': [ { 'begin': '\\bcase\\b' 'beginCaptures': '0': 'name': 'keyword.control.case.js' 'end': ':' 'endCaptures': '0': 'name': 'punctuation.definition.section.case-statement.js' 'patterns': [ { 'include': '#prevent_object_keys_matching' } { 'include': '$self' } ] } { 'match': '(?:^\\s*)?\\b(default)\\b\\s*(:)' 'captures': '1': 'name': 'keyword.control.default.js' '2': 'name': 'punctuation.definition.section.case-statement.js' } { 'include': '$self' } ] } ] } ] 'prevent_object_keys_matching': 'patterns': [ { # e.g. don't treat null as an object key in # ? null : # case null: 'match': '(\\w+)(?=\\s*:)' 'captures': '1': 'patterns': [ 'include': '$self' ] } ] 'period_or_illegal_optional_property': 'patterns': [ { 'match': '\\.' 'name': 'meta.delimiter.property.period.js' } { 'match': '\\?\\.' 'name': 'invalid.illegal.meta.delimiter.property.optional.js' } ] 'period_or_illegal_optional_method': 'patterns': [ { 'match': '\\.' 'name': 'meta.delimiter.method.period.js' } { 'match': '\\?\\.' 'name': 'invalid.illegal.meta.delimiter.method.optional.js' } ] 'period_or_optional_property': 'patterns': [ { 'match': '\\.' 'name': 'meta.delimiter.property.period.js' } { 'match': '\\?\\.' 'name': 'meta.delimiter.property.optional.js' } ] 'period_or_optional_method': 'patterns': [ { 'match': '\\.' 'name': 'meta.delimiter.method.period.js' } { 'match': '\\?\\.' 'name': 'meta.delimiter.method.optional.js' } ]