diff --git a/SyntaxKit.xcodeproj/project.pbxproj b/SyntaxKit.xcodeproj/project.pbxproj index cf5ed1c..eb2ab12 100644 --- a/SyntaxKit.xcodeproj/project.pbxproj +++ b/SyntaxKit.xcodeproj/project.pbxproj @@ -87,6 +87,10 @@ 21F28DDB1B7AC7F8009DD1E9 /* X.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21F28DDA1B7AC7F8009DD1E9 /* X.framework */; }; 21F28DDD1B7AC802009DD1E9 /* X.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21F28DDC1B7AC802009DD1E9 /* X.framework */; }; 21F28DDF1B7AC80B009DD1E9 /* X.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21F28DDE1B7AC80B009DD1E9 /* X.framework */; }; + 92EC79D41CC9060600E058ED /* JavaScript.tmLanguage in Resources */ = {isa = PBXBuildFile; fileRef = 92EC79D31CC9060600E058ED /* JavaScript.tmLanguage */; }; + 92EC79D51CC9060600E058ED /* JavaScript.tmLanguage in Resources */ = {isa = PBXBuildFile; fileRef = 92EC79D31CC9060600E058ED /* JavaScript.tmLanguage */; }; + 92EC79D71CC9061D00E058ED /* test.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 92EC79D61CC9061D00E058ED /* test.js.txt */; }; + 92EC79D81CC9061D00E058ED /* test.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 92EC79D61CC9061D00E058ED /* test.js.txt */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -182,6 +186,8 @@ 21F28DDA1B7AC7F8009DD1E9 /* X.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = X.framework; path = Carthage/Build/iOS/X.framework; sourceTree = ""; }; 21F28DDC1B7AC802009DD1E9 /* X.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = X.framework; path = Carthage/Build/Mac/X.framework; sourceTree = ""; }; 21F28DDE1B7AC80B009DD1E9 /* X.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = X.framework; path = Carthage/Build/watchOS/X.framework; sourceTree = ""; }; + 92EC79D31CC9060600E058ED /* JavaScript.tmLanguage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = JavaScript.tmLanguage; sourceTree = ""; }; + 92EC79D61CC9061D00E058ED /* test.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.js.txt; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -284,6 +290,8 @@ 210BF26C1B37C04E008AA4F0 /* test.rb.txt */, 2119897E1B2EAF0900F0D786 /* Tomorrow.tmTheme */, 2119897F1B2EAF0900F0D786 /* YAML.tmLanguage */, + 92EC79D31CC9060600E058ED /* JavaScript.tmLanguage */, + 92EC79D61CC9061D00E058ED /* test.js.txt */, ); path = Fixtures; sourceTree = ""; @@ -628,8 +636,10 @@ files = ( 210BF2711B37C0A2008AA4F0 /* Ruby.tmLanguage in Resources */, 211989C91B2EC40900F0D786 /* Tomorrow.tmTheme in Resources */, + 92EC79D81CC9061D00E058ED /* test.js.txt in Resources */, 210BF26E1B37C04E008AA4F0 /* test.rb.txt in Resources */, 211989CA1B2EC40900F0D786 /* YAML.tmLanguage in Resources */, + 92EC79D51CC9060600E058ED /* JavaScript.tmLanguage in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -646,8 +656,10 @@ files = ( 210BF2701B37C0A2008AA4F0 /* Ruby.tmLanguage in Resources */, 211989801B2EAF0900F0D786 /* Tomorrow.tmTheme in Resources */, + 92EC79D71CC9061D00E058ED /* test.js.txt in Resources */, 210BF26D1B37C04E008AA4F0 /* test.rb.txt in Resources */, 211989811B2EAF0900F0D786 /* YAML.tmLanguage in Resources */, + 92EC79D41CC9060600E058ED /* JavaScript.tmLanguage in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SyntaxKit/Parser.swift b/SyntaxKit/Parser.swift index 9b8fed0..4500b8a 100644 --- a/SyntaxKit/Parser.swift +++ b/SyntaxKit/Parser.swift @@ -74,7 +74,7 @@ public class Parser { beginRange = beginResults.range else { continue } let location = NSMaxRange(beginRange) - let endBounds = NSMakeRange(location, bounds.length - location - bounds.location) + let endBounds = NSMakeRange(location, NSMaxRange(bounds) - location) guard let endResults = parse(string, inRange: endBounds, expression: end, captures: pattern.endCaptures), endRange = endResults.range else { /* TODO: Rewind? */ continue } diff --git a/SyntaxKit/Tests/ParserTests.swift b/SyntaxKit/Tests/ParserTests.swift index 8d0e4a4..49c0483 100644 --- a/SyntaxKit/Tests/ParserTests.swift +++ b/SyntaxKit/Tests/ParserTests.swift @@ -59,4 +59,10 @@ class ParserTests: XCTestCase { let input = fixture("test.rb", "txt") parser.parse(input, match: { _, _ in return }) } + + func testJavaScript() { + let parser = Parser(language: language("JavaScript")) + let input = fixture("test.js", "txt") + parser.parse(input, match: { _, _ in return }) + } } diff --git a/SyntaxKit/Tests/Resources/Fixtures/JavaScript.tmLanguage b/SyntaxKit/Tests/Resources/Fixtures/JavaScript.tmLanguage new file mode 100644 index 0000000..3fd1b4f --- /dev/null +++ b/SyntaxKit/Tests/Resources/Fixtures/JavaScript.tmLanguage @@ -0,0 +1,676 @@ + + + + + comment + JavaScript Syntax: version 2.0 + fileTypes + + js + htc + jsx + + injections + + source.js - meta.ternary-if.js - string - comment + + patterns + + + match + (?<!\w)[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?=\s*:\s*function\b) + name + entity.name.function.js + + + match + (?<!\w)[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?=\s*:) + name + entity.name.attribute-name.js + + + + + keyEquivalent + ^~J + name + JavaScript + patterns + + + captures + + 1 + + name + punctuation.definition.comment.js + + + comment + Match the shebang for JavaScript executables + match + \A(#!).*$\n + name + comment.line.number-sign.shebang.js + + + begin + (?x) + (?: + (?<!\w) # Ensure word boundry + ([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*) # Identifier + \s*(=)\s* + )? # Optional + \b(function) + (?:\s* + (\*) # Optional generator notation + )? # (ECMAScript 6) + (?:\s* + (?<=[\s\*]) + ([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*) # Optional Name + )? + \s*(\() + + beginCaptures + + 1 + + name + meta.function.variable.js + + 2 + + name + keyword.operator.js + + 3 + + name + storage.type.function.js + + 4 + + name + storage.modifier.js + + 5 + + name + entity.name.function.js + + 6 + + name + punctuation.definition.parameters.begin.js + + + comment + Match function, optional function name and optional function arguments + end + (\)) + endCaptures + + 1 + + name + punctuation.definition.parameters.end.js + + + name + meta.function.js + patterns + + + include + #function-params + + + + + match + \b0[xX]\h+\b + name + constant.numeric.hex.js + + + match + (?x) + (?<!\w) # Ensure word boundry + (?> + ( + (0|[1-9][0-9]*)(\.[0-9]*)? # 0 or 1 or 1. or 1.0 + | \.[0-9]+ # .1 + ) + ([eE][+-]?[0-9]+)? # Exponent + ) + (?!\w) # Ensure word boundry + + name + constant.numeric.js + + + begin + ' + beginCaptures + + 0 + + name + punctuation.definition.string.begin.js + + + end + ' + endCaptures + + 0 + + name + punctuation.definition.string.end.js + + + name + string.quoted.single.js + patterns + + + match + \\(x\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.) + name + constant.character.escape.js + + + + + begin + " + beginCaptures + + 0 + + name + punctuation.definition.string.begin.js + + + end + " + endCaptures + + 0 + + name + punctuation.definition.string.end.js + + + name + string.quoted.double.js + patterns + + + match + \\(x\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.) + name + constant.character.escape.js + + + + + begin + /\* + captures + + 0 + + name + punctuation.definition.comment.js + + + end + \*/ + name + comment.block.js + + + begin + (^[ \t]+)?(?=//) + beginCaptures + + 1 + + name + punctuation.whitespace.comment.leading.js + + + end + (?!\G) + patterns + + + begin + // + beginCaptures + + 0 + + name + punctuation.definition.comment.js + + + end + \n + name + comment.line.double-slash.js + + + + + match + (?<!\.|\$)\b(let|var)\b(?!\$) + name + storage.type.js + + + match + (?<!\.|\$)\b(get|set)\b(?!\$) + name + storage.modifier.js + + + match + (?<!\.|\$)\b(break|case|catch|continue|default|do|else|finally|for|if|return|switch|throw|try|while|yield)\b(?!\$) + name + keyword.control.js + + + match + (?<!\.|\$)\b(delete|in|instanceof|new|typeof|void|with)\b(?!\$) + name + keyword.operator.js + + + match + !|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^= + name + keyword.operator.js + + + match + (?<!\.|\$)\b(debugger)\b(?!\$) + name + keyword.other.js + + + match + (?<!\.|\$)\b(Array|Boolean|Date|Error|EvalError|Function|Number|Object|RangeError|ReferenceError|RegExp|String|SyntaxError|TypeError|URIError)\b(?!\$) + name + support.class.js + + + comment + DOM Core Level 4 (http://www.w3.org/TR/domcore/) and DOM Events Level 3 (http://www.w3.org/TR/DOM-Level-3-Events/) + match + (?<!\.|\$)\b(Attr|CharacterData|Comment|CompositionEvent|CustomEvent|Document|DocumentFragment|DocumentType|DOMError|DOMException|DOMImplementation|DOMParser|DOMString|DOMTimestamp|DOMSettableTokenList|DOMStringList|DOMTokenList|Element|Event|EventTarget|FocusEvent|HTMLCollection|KeyboardEvent|MouseEvent|MutationObserver|MutationRecord|Node|NodeFilter|NodeIterator|NodeList|ProcessingInstruction|Range|Text|TextEvent|TreeWalker|UIEvent|WheelEvent|XMLDocument)\b(?!\$) + name + support.class.dom.js + + + comment + DOM Core Level 4 (http://www.w3.org/TR/domcore/) and DOM Events Level 3 (http://www.w3.org/TR/DOM-Level-3-Events/) + match + (?<!\.|\$)\b(CDATASection|DOMConfiguration|DOMErrorHandler|DOMImplementationList|DOMImplementationSource|DOMLocator|DOMObject|DOMUserData|Entity|EntityReference|MutationEvent|NamedNodeMap|NameList|Notation|TypeInfo|UserDataHandler)\b(?!\$) + name + invalid.deprecated.dom.js + + + comment + TypedArray specification used by HTML 5 (http://www.khronos.org/registry/typedarray/specs/latest/) + match + (?<!\.|\$)\b(ArrayBuffer|DataView|Float32Array|Float64Array|Int8Array|Int16Array|Int32Array|TypedArray|Uint8Array|Uint16Array|Uint32Array|Uint8ClampedArray)\b(?!\$) + name + support.class.dom.js + + + comment + File specification used by HTML 5 (http://dev.w3.org/2006/webapi/FileAPI/) + match + (?<!\.|\$)\b(Blob|File|FileList|FileReader)\b(?!\$) + name + support.class.dom.js + + + comment + XMLHttpRequest specification used by HTML 5 (http://xhr.spec.whatwg.org/) + match + (?<!\.|\$)\b(FormData|ProgressEvent|XMLHttpRequest|XMLHttpRequestUpload)\b(?!\$) + name + support.class.dom.js + + + comment + EventSource specification used by HTML 5 (http://www.w3.org/TR/eventsource/) + match + (?<!\.|\$)\b(EventSource)\b(?!\$) + name + support.class.dom.js + + + comment + CSSOM specification used by HTML 5 (http://dev.w3.org/csswg/cssom/) + match + (?<!\.|\$)\b(CSS|CSSCharsetRule|CSSImportRule|CSSPageRule|CSSRule|CSSRuleList|CSSStyleDeclaration|CSSStyleRule|CSSStyleSheet|MediaList|Stylesheet|StyleSheetList)\b(?!\$) + name + support.class.dom.js + + + comment + CSSOM View specification used by HTML 5 (http://dev.w3.org/csswg/cssom-view/) + match + (?<!\.|\$)\b(Screen)\b(?!\$) + name + support.class.dom.js + + + comment + CSS Font specification used by HTML 5 (http://dev.w3.org/csswg/css-fonts/) + match + (?<!\.|\$)\b(CSSFontFaceRule)\b(?!\$) + name + support.class.dom.js + + + comment + SVG specification used by HTML 5 (http://www.w3.org/TR/SVG/single-page.html) + match + (?<!\.|\$)\b(SVGAElement|SVGAltGlyphDefElement|SVGAltGlyphElement|SVGAltGlyphItemElement|SVGAngle|SVGAnimateColorElement|SVGAnimateElement|SVGAnimateMotionElement|SVGAnimateTransformElement|SVGAnimatedAngle|SVGAnimatedBoolean|SVGAnimatedEnumeration|SVGAnimatedInteger|SVGAnimatedLength|SVGAnimatedLengthList|SVGAnimatedNumber|SVGAnimatedNumberList|SVGAnimatedPreserveAspectRatio|SVGAnimatedRect|SVGAnimatedString|SVGAnimatedTransformList|SVGAnimationElement|SVGCircleElement|SVGClipPathElement|SVGColor|SVGComponentTransferFunctionElement|SVGCursorElement|SVGDefsElement|SVGDescElement|SVGDocument|SVGElement|SVGElementInstance|SVGElementInstanceList|SVGEllipseElement|SVGFEBlendElement|SVGFEColorMatrixElement|SVGFEComponentTransferElement|SVGFECompositeElement|SVGFEConvolveMatrixElement|SVGFEDiffuseLightingElement|SVGFEDisplacementMapElement|SVGFEDistantLightElement|SVGFEFloodElement|SVGFEFuncAElement|SVGFEFuncBElement|SVGFEFuncGElement|SVGFEFuncRElement|SVGFEGaussianBlurElement|SVGFEImageElement|SVGFEMergeElement|SVGFEMergeNodeElement|SVGFEMorphologyElement|SVGFEOffsetElement|SVGFEPointLightElement|SVGFESpecularLightingElement|SVGFESpotLightElement|SVGFETileElement|SVGFETurbulenceElement|SVGFilterElement|SVGFontElement|SVGFontFaceElement|SVGFontFaceFormatElement|SVGFontFaceNameElement|SVGFontFaceSrcElement|SVGFontFaceUriElement|SVGForeignObjectElement|SVGGElement|SVGGlyphElement|SVGGlyphRefElement|SVGGradientElement|SVGHKernElement|SVGImageElement|SVGLength|SVGLengthList|SVGLineElement|SVGLinearGradientElement|SVGMPathElement|SVGMarkerElement|SVGMaskElement|SVGMatrix|SVGMetadataElement|SVGMissingGlyphElement|SVGNumber|SVGNumberList|SVGPaint|SVGPathElement|SVGPathSeg|SVGPathSegArcAbs|SVGPathSegArcRel|SVGPathSegClosePath|SVGPathSegCurvetoCubicAbs|SVGPathSegCurvetoCubicRel|SVGPathSegCurvetoCubicSmoothAbs|SVGPathSegCurvetoCubicSmoothRel|SVGPathSegCurvetoQuadraticAbs|SVGPathSegCurvetoQuadraticRel|SVGPathSegCurvetoQuadraticSmoothAbs|SVGPathSegCurvetoQuadraticSmoothRel|SVGPathSegLinetoAbs|SVGPathSegLinetoHorizontalAbs|SVGPathSegLinetoHorizontalRel|SVGPathSegLinetoRel|SVGPathSegLinetoVerticalAbs|SVGPathSegLinetoVerticalRel|SVGPathSegList|SVGPathSegMovetoAbs|SVGPathSegMovetoRel|SVGPatternElement|SVGPoint|SVGPointList|SVGPolygonElement|SVGPolylineElement|SVGPreserveAspectRatio|SVGRadialGradientElement|SVGRect|SVGRectElement|SVGRenderingIntent|SVGSVGElement|SVGScriptElement|SVGSetElement|SVGStopElement|SVGStringList|SVGStyleElement|SVGSwitchElement|SVGSymbolElement|SVGTRefElement|SVGTSpanElement|SVGTextContentElement|SVGTextElement|SVGTextPathElement|SVGTextPositioningElement|SVGTitleElement|SVGTransform|SVGTransformList|SVGUnitTypes|SVGUseElement|SVGUseElement|SVGVKernElement|SVGViewElement|SVGViewSpec|SVGZoomEvent)\b(?!\$) + name + support.class.dom.js + + + comment + WebGL specification used by HTML 5 (http://www.khronos.org/registry/webgl/specs/latest/1.0/) + match + (?<!\.|\$)\b(WebGLActiveInfo|WebGLBuffer|WebGLContextEvent|WebGLFramebuffer|WebGLProgram|WebGLRenderbuffer|WebGLRenderingContext|WebGLShader|WebGLShaderPrecisionFormat|WebGLTexture|WebGLUniformLocation)\b(?!\$) + name + support.class.dom.js + + + comment + HTML 5 (http://www.w3.org/TR/html5/single-page.html) + match + (?<!\.|\$)\b(Audio|BarProp|DOMStringMap|ErrorEvent|FileError|HTMLAllCollection|HTMLAnchorElement|HTMLAppletElement|HTMLAreaElement|HTMLAudioElement|HTMLBRElement|HTMLBaseElement|HTMLBodyElement|HTMLButtonElement|HTMLCanvasElement|HTMLDListElement|HTMLDataElement|HTMLDataListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLEmbedElement|HTMLFieldSetElement|HTMLFontElement|HTMLFormControlsCollection|HTMLFormElement|HTMLFrameElement|HTMLFrameSetElement|HTMLHRElement|HTMLHeadElement|HTMLHeadingElement|HTMLHtmlElement|HTMLIFrameElement|HTMLImageElement|HTMLInputElement|HTMLKeygenElement|HTMLLIElement|HTMLLabelElement|HTMLLegendElement|HTMLLinkElement|HTMLMapElement|HTMLMarqueeElement|HTMLMediaElement|HTMLMetaElement|HTMLMeterElement|HTMLModElement|HTMLOListElement|HTMLObjectElement|HTMLOptGroupElement|HTMLOptionElement|HTMLOptionsCollection|HTMLOutputElement|HTMLParagraphElement|HTMLParamElement|HTMLPreElement|HTMLProgressElement|HTMLQuoteElement|HTMLScriptElement|HTMLSelectElement|HTMLSour|HTMLSpanElement|HTMLStyleElement|HTMLTableCaptionElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableDataCellElement|HTMLTableElement|HTMLTableHeaderCellElement|HTMLTableRowElement|HTMLTableSectionElement|HTMLTextAreaElement|HTMLTimeElement|HTMLTitleElement|HTMLTrackElement|HTMLUListElement|HTMLUnknownElement|HTMLVideoElement|HashChangeEvent|History|Image|Location|MediaController|MediaError|MouseEvent|Navigator|Option|PageTransitionEvent|PopStateEvent|TextTrack|TextTrackCue|TextTrackCueList|TextTrackList|TimeRanges|TrackEvent|UIEvent|ValidityState|Window)\b(?!\$) + name + support.class.dom.js + + + comment + HTML 5 (http://www.w3.org/TR/html5/single-page.html#window) + match + (?<!\.|\$)\b(applicationCache|closed|console|crypto|document|external|frameElement|frames|history|innerHeight|innerWidth|length|location|locationbar|menubar|name|navigator|offscreenBuffering|onabort|onafterprint|onbeforeprint|onbeforeunload|onblur|oncancel|oncanplay|oncanplaythrough|onchange|onclick|onclose|oncuechange|ondblclick|ondrag|ondragend|ondragenter|ondragexit|ondragleave|ondragover|ondragstart|ondrop|ondurationchange|onemptied|onended|onerror|onfocus|onhashchange|oninput|oninvalid|onkeydown|onkeypress|onkeyup|onload|onloadeddata|onloadedmetadata|onloadstart|onmessage|onmousedown|onmouseenter|onmouseleave|onmousemove|onmouseout|onmouseover|onmouseup|onmousewheel|onoffline|ononline|onpagehide|onpageshow|onpause|onplay|onplaying|onpopstate|onprogress|onratechange|onreset|onresize|onscroll|onseeked|onseeking|onselect|onshow|onstalled|onstorage|onsubmit|onsuspend|ontimeupdate|onunload|onvolumechange|onwaiting|opener|outerHeight|outerWidth|pageXOffset|pageYOffset|parent|personalbar|postMessage|screen|screenX|screenY|scrollbars|scrollX|scrollY|self|status|statusbar|toolbar|top|window)\b(?!\$) + name + support.constant.dom.js + + + comment + HTML 5 (http://www.w3.org/TR/html5/single-page.html#window) + match + (?<!\.|\$)\b(addEventListener|alert|atob|blur|btoa|clearInterval|clearTimeout|close|confirm|dispatchEvent|doNotTrack|find|focus|getComputedStyle|getMatchedCSSRules|getSelection|matchMedia|moveBy|moveTo|open|openDatabase|print|prompt|removeEventListener|resizeBy|resizeTo|scroll|scrollBy|scrollTo|setInterval|setTimeout|showModalDialog|stop)\b(?!\$) + name + support.function.dom.js + + + match + (?<!\.|\$)\b(captureEvents|defaultStatus|defaultstatus|releaseEvents)\b(?!\$) + name + invalid.deprecated.dom.js + + + match + (?<!\.|\$)\b(JSON|Math)\b(?!\$) + name + support.constant.js + + + match + (?<!\.|\$)\b(decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|uneval)\b(?!\$) + name + support.function.js + + + comment + Keywords reserved for future use but now are unused. + match + (?<!\.|\$)\b(class|const|enum|export|extends|import|super)\b(?!\$) + name + invalid.illegal.js + + + comment + Keywords reserved for future use in strict mode but now are unused. + match + (?<!\.|\$)\b(implements|interface|package|private|protected|public|static)\b(?!\$) + name + invalid.deprecated.js + + + match + \b(false|Infinity|NaN|null|true|undefined)\b + name + constant.language.js + + + match + (?<!\.|\$)\b(this)\b(?!\$) + name + variable.language.js + + + begin + (?<=[=(:,]|^|return|&&|\|\||!|\?)\s*(?=/[^/*+?]) + comment + Dont scope preceding whitespace as string.regex + end + (?<=[/igm]) + patterns + + + begin + / + beginCaptures + + 1 + + name + punctuation.definition.string.begin.js + + + end + (/)[igm]* + endCaptures + + 1 + + name + punctuation.definition.string.end.js + + + name + string.regexp.js + patterns + + + include + source.js.regexp + + + + + + + match + \; + name + punctuation.terminator.statement.js + + + captures + + 1 + + name + punctuation.section.scope.begin.js + + 2 + + name + punctuation.section.scope.end.js + + + comment + Allows the special return snippet to fire. + match + (\{)(\}) + + + captures + + 1 + + name + punctuation.section.scope.begin.js + + 2 + + name + punctuation.section.scope.end.js + + + comment + Allows the special return snippet to fire. + match + (\()(\)) + + + captures + + 1 + + name + punctuation.section.scope.begin.js + + 2 + + name + punctuation.section.scope.end.js + + + comment + Allows the special return snippet to fire. + match + (\[)(\]) + + + match + \{|\} + name + meta.brace.curly.js + + + match + \(|\) + name + meta.brace.round.js + + + match + \[|\] + name + meta.brace.square.js + + + begin + \? + end + : + name + meta.ternary-if.js + patterns + + + include + $self + + + + + comment + Match classes based on the usage of the "new" operator. + match + (?<=new )([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*)(?!\w) + name + support.class.js + + + comment + Match classes based on the usage of the "instanceof" operator. + match + (?<= instanceof )([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*)(?!\w) + name + support.class.js + + + comment + Match classes based on the usage of the "prototype" property. + match + (?<!\w)([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*)(?=\.prototype\b) + name + support.class.js + + + comment + Matches the "prototype" keyword. Even though it is not a valid keyword, it is a special constant of sorts. + match + (?<=\.)(prototype)\b + name + keyword.other.js + + + comment + Matches the function calls. + match + (?<!\w)([\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*)(?=\() + name + meta.function-call.js + + + repository + + function-params + + patterns + + + begin + (?=[\p{L}\p{Nl}$_]) + comment + Matches valid argument, function and variable names. To be thorough: https://github.com/mathiasbynens/mothereff.in/tree/master/js-variables + end + (?=[,)]) + patterns + + + match + \G[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]* + name + variable.parameter.function.js + + + + + + + scopeName + source.js + uuid + 93E017CC-6F27-11D9-90EB-000D93589AF6 + + \ No newline at end of file diff --git a/SyntaxKit/Tests/Resources/Fixtures/test.js.txt b/SyntaxKit/Tests/Resources/Fixtures/test.js.txt new file mode 100644 index 0000000..a92c267 --- /dev/null +++ b/SyntaxKit/Tests/Resources/Fixtures/test.js.txt @@ -0,0 +1,21 @@ +var global = "test"; + +function foo() { + var a = 1; + + if (a != null) { + bar(a); + } + + for (var i = 0; i < 10; i++) { + // Comment + } +} + +function bar(abc) { + var b = abc; + + while (true) { + doSomething(); + } +} \ No newline at end of file