diff --git a/.gitattributes b/.gitattributes index eec6973..7f91ba8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,11 @@ -/.github/ export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/tests export-ignore \ No newline at end of file +# git +.github/ export-ignore +.git export-ignore +.gitattributes export-ignore +.gitignore export-ignore +# development +tests/ export-ignore +*.cmd export-ignore +# other +logo.* export-ignore +preview.* export-ignore diff --git a/.github/workflows/ci-syntax-tests.yml b/.github/workflows/ci-syntax-tests.yml new file mode 100644 index 0000000..3e88d64 --- /dev/null +++ b/.github/workflows/ci-syntax-tests.yml @@ -0,0 +1,71 @@ +name: CI Syntax Tests + +on: + push: + branches: + - 'master' + tags-ignore: + - '**' + paths: + - '.github/workflows/ci-syntax-tests.yml' + - '**.sublime-syntax' + - '**/syntax_test_*' + - '**.tmPreferences' + pull_request: + paths: + - '.github/workflows/ci-syntax-tests.yml' + - '**.sublime-syntax' + - '**/syntax_test_*' + - '**.tmPreferences' + workflow_dispatch: + +jobs: + syntax_tests: + name: Sublime Text ${{ matrix.build }} + runs-on: ubuntu-latest + timeout-minutes: 15 # default is 6 hours! + strategy: + fail-fast: false + matrix: + include: + # Stable ST4 builds + - build: 4143 + default_packages: v4143 + - build: 4152 + default_packages: v4152 + - build: 4169 + default_packages: v4169 + - build: 4180 + default_packages: v4180 + - build: 4200 + default_packages: v4200 + # Latest dev build + # - build: latest + # default_packages: master + steps: + - name: Checkout Default Packages + uses: actions/checkout@v6 + with: + repository: sublimehq/Packages + ref: ${{ matrix.default_packages }} + path: st_syntax_tests/Data/Packages + + - name: Delete default package tests + run: | + find st_syntax_tests/Data/Packages/*/ -type f -name 'syntax_test*' -exec rm -v '{}' \; + + - name: Checkout CoffeeScript + uses: actions/checkout@v6 + with: + path: st_syntax_tests/Data/Packages/CoffeeScript + + - name: Run Syntax Tests for Sublime Text ${{ matrix.build }} + run: | + if [[ "${{ matrix.build }}" == "latest" ]]; then + wget -O st_syntax_tests.tar.xz https://download.sublimetext.com/latest/dev/linux/x64/syntax_tests + else + wget -O st_syntax_tests.tar.xz https://download.sublimetext.com/st_syntax_tests_build_${{ matrix.build }}_x64.tar.xz + fi + tar xf st_syntax_tests.tar.xz + cd st_syntax_tests + ./syntax_tests diff --git a/.github/workflows/syntax-tests.yml b/.github/workflows/syntax-tests.yml deleted file mode 100644 index aa1f57d..0000000 --- a/.github/workflows/syntax-tests.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: CI Syntax Tests - -on: - push: - branches: - - '**' - tags-ignore: - - '**' - paths: - - '.github/workflows/syntax-tests.yml' - - '**.sublime-syntax' - - '**/syntax_test_*' - - '**.tmPreferences' - workflow_dispatch: - -jobs: - syntax_tests: - name: Sublime Text ${{ matrix.build }} - runs-on: ubuntu-latest - timeout-minutes: 15 # default is 6 hours! - strategy: - matrix: - include: - - build: 3211 - default_packages: v3211 - - build: 4107 - default_packages: v4107 - - build: 4180 - default_packages: v4180 - - build: latest - default_packages: master - steps: - - uses: actions/checkout@v4 - - uses: SublimeText/syntax-test-action@v2 - with: - build: ${{ matrix.build }} - default_packages: ${{ matrix.default_packages }} diff --git a/CoffeeScript Literate.sublime-syntax b/CoffeeScript Literate.sublime-syntax index c058105..a237c94 100644 --- a/CoffeeScript Literate.sublime-syntax +++ b/CoffeeScript Literate.sublime-syntax @@ -3,6 +3,9 @@ # http://www.sublimetext.com/docs/syntax.html name: CoffeeScript (Literate) scope: source.litcoffee +version: 2 + +extends: Packages/Markdown/Markdown.sublime-syntax file_extensions: - litcoffee @@ -10,474 +13,90 @@ file_extensions: - coffee.md contexts: - main: - - match: |- - (?x)^ - (?= ([ ]{4}|\t)(?!$)) - push: - - meta_scope: markup.raw.block.markdown - - match: |- - (?x)^ - (?! ([ ]{4}|\t)) - pop: true - - include: block_raw - # We could also use an empty end match and set - # applyEndPatternLast, but then we must be sure that the begin - # pattern will only match stuff matched by the sub-patterns. - - match: |- - (?x)^ - (?= [ ]{,3}>. - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - push: - - meta_scope: meta.block-level.markdown - - match: |- - (?x)^ - (?! [ ]{,3}>. - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - pop: true - - include: block_quote - - include: heading - - include: separator - - match: '^[ ]{0,3}([*+-])(?=\s)' - captures: - 1: punctuation.definition.list_item.markdown - push: - - meta_scope: markup.list.unnumbered.markdown - - match: ^(?=\S) - captures: - 1: punctuation.definition.list_item.markdown - pop: true - - include: list-paragraph - - match: '^[ ]{0,3}([0-9]+\.)(?=\s)' - captures: - 1: punctuation.definition.list_item.markdown - push: - - meta_scope: markup.list.numbered.markdown - - match: ^(?=\S) - captures: - 1: punctuation.definition.list_item.markdown - pop: true - - include: list-paragraph - # Markdown formatting is disabled inside block-level tags. - - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b)(?!.*?)' - push: - - meta_scope: meta.disable-markdown - - match: (?<=^$\n) - pop: true - - include: scope:text.html.basic - # Same rule but for one line disables. - - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b)' - push: - - meta_scope: meta.disable-markdown - - match: $\n? - pop: true - - include: scope:text.html.basic + + markdown: + - meta_prepend: true + - meta_scope: text.html.markdown.litcoffee + - include: coffee-indented-code-blocks + + list-block-content: + - meta_prepend: true + - include: coffee-indented-code-blocks + + coffee-indented-code-blocks: + - match: '{{indented_code_block}}' + scope: meta.embedded.litcoffee source.coffee.embedded.markdown + embed: scope:source.coffee + embed_scope: meta.embedded.litcoffee source.coffee.embedded.markdown + escape: ^(?=\s*$) + +###[ FENCED CODE BLOCKS (NEW STYLE) ]########################################### + + fenced-code-block-body: + # requires: https://github.com/sublimehq/Packages/pull/4430 + - meta_prepend: true - match: |- - (?x: - \s* # Leading whitespace - (\[)(.+?)(\])(:) # Reference name - [ \t]* # Optional whitespace - (?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in quotes… - | ((").+?(")) # or in parens. - )? # Title is optional - \s* # Optional whitespace - $ - ) - scope: meta.link.reference.def.markdown - captures: - 1: punctuation.definition.constant.markdown - 2: constant.other.reference.link.markdown - 3: punctuation.definition.constant.markdown - 4: punctuation.separator.key-value.markdown - 5: punctuation.definition.link.markdown - 6: markup.underline.link.markdown - 7: punctuation.definition.link.markdown - 8: string.other.link.description.title.markdown - 9: punctuation.definition.string.begin.markdown - 10: punctuation.definition.string.end.markdown - 11: string.other.link.description.title.markdown - 12: punctuation.definition.string.begin.markdown - 13: punctuation.definition.string.end.markdown - - match: '^(?=\S)(?![=-]{3,}(?=$))' - push: - - meta_scope: meta.paragraph.markdown - - match: '^(?:\s*$|(?=[ ]{,3}>.))|(?=[ \t]*\n)(?<=^===|^====|=====|^---|^----|-----)[ \t]*\n|(?=^#)' - pop: true - - include: inline - - include: scope:text.html.basic - - match: '^(={3,})(?=[ \t]*$)' - scope: markup.heading.1.markdown - captures: - 1: punctuation.definition.heading.markdown - - match: '^(-{3,})(?=[ \t]*$)' - scope: markup.heading.2.markdown - captures: - 1: punctuation.definition.heading.markdown - ampersand: - - match: '&(?!([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)' - comment: | - Markdown will convert this for us. We match it so that the - HTML grammar will not mark it up as invalid. - scope: meta.other.valid-ampersand.markdown - block_quote: - # We terminate the block quote when seeing an empty line, a - # separator or a line with leading > characters. The latter is - # to “reset” the quote level for quoted lines. - - match: '\G[ ]{,3}(>)(?!$)[ ]?' + (?xi) + [ \t]* + (coffee(?:script)?|cjsx|cson|iced) + (?=[ \t\n;:]) captures: - 1: punctuation.definition.blockquote.markdown + 1: constant.other.language-name.markdown push: - - meta_scope: markup.quote.markdown - - match: |- - (?x)^ - (?= \s*$ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - | [ ]{,3}>. - ) - pop: true - - match: |- - (?x)\G - (?= [ ]{,3}>. - ) - push: - - match: ^ - pop: true - - include: block_quote - - match: |- - (?x)\G - (?= ([ ]{4}|\t) - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - push: - - include: heading - - include: separator - - match: ^ - pop: true - - match: |- - (?x)\G - (?! $ - | [ ]{,3}>. - | ([ ]{4}|\t) - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - push: - - match: $|(?<=\n) - pop: true - - include: inline - block_raw: - - include: scope:source.coffee#script - bold: + - fenced-code-block-coffee-content + - fenced-code-block-coffee-infostring + + fenced-code-block-coffee-infostring: + - meta_include_prototype: false + - meta_scope: meta.code-fence.definition.begin.markdown-gfm + - meta_content_scope: comment.line.infostring.markdown + - match: \s*$\n? + scope: meta.fold.code-fence.begin.markdown + pop: 1 + - match: \{ + scope: punctuation.definition.attributes.begin.markdown + push: fenced-code-block-coffee-infostring-attributes + + fenced-code-block-coffee-infostring-attributes: + - meta_scope: meta.attributes.markdown + - include: tag-attributes + + fenced-code-block-coffee-content: + - meta_include_prototype: false + - match: ^ + embed: scope:source.coffee + embed_scope: + meta.code-fence.body.markdown-gfm + markup.raw.code-fence.coffee.markdown-gfm + source.coffee + escape: (?!) + +###[ FENCED CODE BLOCKS (OLD STYLE) ]########################################### + + fenced-syntaxes: + # required until ST4202 + - meta_append: true - match: |- (?x) - (\*\*|__)(?=\S) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?`+)([^`]|(?!(?(?!`))`)*+\k - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (? # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - ? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | (?!(?<=\S)\1). # Everything besides - # style closer - )++ - (?<=\S)\1 # Close - ) - captures: - 1: punctuation.definition.bold.markdown - push: - - meta_scope: markup.bold.markdown - - match: (?<=\S)(\1) - captures: - 1: punctuation.definition.bold.markdown - pop: true - - match: '(?=<[^>]*?>)' - push: - - include: scope:text.html.basic - - match: (?<=>) - pop: true - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: italic - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - bracket: - # Markdown will convert this for us. We match it so that the - # HTML grammar will not mark it up as invalid. - - match: '<(?![a-z/?\$!])' - scope: meta.other.valid-bracket.markdown - escape: - - match: '\\[-`*_#+.!(){}\[\]\\>]' - scope: constant.character.escape.markdown - heading: - - match: '\G(#{1,6})(?!#)\s*(?=\S)' + [ \t]* # leading whitespace + ( (`)``+(?![^`]*`) | (~)~~+ ) # punctuation + ((?i:coffee(?:script)?|cjsx|cson|iced)) # language identifier + (?: (?: \s+ | (?=[:;]) ) (\S.*?) )? # remaining infostring + (\s*$\n?) # fold marker captures: - 1: punctuation.definition.heading.markdown - push: - - meta_scope: markup.heading.markdown - - meta_content_scope: entity.name.section.markdown - - match: \s*(#*)$\n? - captures: - 1: punctuation.definition.heading.markdown - pop: true - - include: inline - image-inline: - - match: |- - (?x: - \! # Images start with ! - (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) - # Match the link text. - ([ ])? # Space not allowed - (\() # Opening paren for url - (<?)(\S+?)(>?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in parens… - | ((").+?(")) # or in quotes. - )? # Title is optional - \s* # Optional whitespace - (\)) - ) - scope: meta.image.inline.markdown - captures: - 1: punctuation.definition.string.begin.markdown - 2: string.other.link.description.markdown - 3: punctuation.definition.string.end.markdown - 5: invalid.illegal.whitespace.markdown - 6: punctuation.definition.metadata.markdown - 7: punctuation.definition.link.markdown - 8: markup.underline.link.image.markdown - 9: punctuation.definition.link.markdown - 10: string.other.link.description.title.markdown - 11: punctuation.definition.string.markdown - 12: punctuation.definition.string.markdown - 13: string.other.link.description.title.markdown - 14: punctuation.definition.string.markdown - 15: punctuation.definition.string.markdown - 16: punctuation.definition.metadata.markdown - image-ref: - - match: '\!(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)(.*?)(\])' - scope: meta.image.reference.markdown - captures: - 1: punctuation.definition.string.begin.markdown - 2: string.other.link.description.markdown - 4: punctuation.definition.string.begin.markdown - 5: punctuation.definition.constant.markdown - 6: constant.other.reference.link.markdown - 7: punctuation.definition.constant.markdown - inline: - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: bold - - include: italic - - include: line-break - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - italic: - - match: |- + 0: meta.code-fence.definition.begin.markdown-gfm + 1: punctuation.definition.raw.code-fence.begin.markdown + 4: constant.other.language-name.markdown + 5: comment.line.infostring.markdown + 6: meta.fold.code-fence.begin.markdown + embed: scope:source.coffee + embed_scope: markup.raw.code-fence.markdown-gfm source.coffee + escape: |- (?x) - (\*|_)(?=\S) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (?<square> # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g<square>*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - <?(.*?)>? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?<title>['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | \1\1 # Must be bold closer - | (?!(?<=\S)\1). # Everything besides - # style closer - )++ - (?<=\S)\1 # Close - ) - captures: - 1: punctuation.definition.italic.markdown - push: - - meta_scope: markup.italic.markdown - - match: (?<=\S)(\1)((?!\1)|(?=\1\1)) - captures: - 1: punctuation.definition.italic.markdown - pop: true - - match: '(?=<[^>]*?>)' - push: - - include: scope:text.html.basic - - match: (?<=>) - pop: true - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: bold - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - line-break: - - match: ' {2,}$' - scope: meta.dummy.line-break - link-email: - - match: '(<)((?:mailto:)?[-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(>)' - scope: meta.link.email.lt-gt.markdown - captures: - 1: punctuation.definition.link.markdown - 2: markup.underline.link.markdown - 4: punctuation.definition.link.markdown - link-inet: - - match: (<)((?:https?|ftp)://.*?)(>) - scope: meta.link.inet.markdown - captures: - 1: punctuation.definition.link.markdown - 2: markup.underline.link.markdown - 3: punctuation.definition.link.markdown - link-inline: - - match: |- - (?x: - (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) - # Match the link text. - ([ ])? # Space not allowed - (\() # Opening paren for url - (<?)(.*?)(>?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in parens… - | ((").+?(")) # or in quotes. - )? # Title is optional - \s* # Optional whitespace - (\)) - ) - scope: meta.link.inline.markdown - captures: - 1: punctuation.definition.string.begin.markdown - 2: string.other.link.title.markdown - 4: punctuation.definition.string.end.markdown - 5: invalid.illegal.whitespace.markdown - 6: punctuation.definition.metadata.markdown - 7: punctuation.definition.link.markdown - 8: markup.underline.link.markdown - 9: punctuation.definition.link.markdown - 10: string.other.link.description.title.markdown - 11: punctuation.definition.string.begin.markdown - 12: punctuation.definition.string.end.markdown - 13: string.other.link.description.title.markdown - 14: punctuation.definition.string.begin.markdown - 15: punctuation.definition.string.end.markdown - 16: punctuation.definition.metadata.markdown - link-ref: - - match: '(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)([^\]]*+)(\])' - scope: meta.link.reference.markdown - captures: - 1: punctuation.definition.string.begin.markdown - 2: string.other.link.title.markdown - 4: punctuation.definition.string.end.markdown - 5: punctuation.definition.constant.begin.markdown - 6: constant.other.reference.link.markdown - 7: punctuation.definition.constant.end.markdown - link-ref-literal: - - match: '(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)(\])' - scope: meta.link.reference.literal.markdown - captures: - 1: punctuation.definition.string.begin.markdown - 2: string.other.link.title.markdown - 4: punctuation.definition.string.end.markdown - 5: punctuation.definition.constant.begin.markdown - 6: punctuation.definition.constant.end.markdown - list-paragraph: - - match: \G\s+(?=\S) - push: - - meta_scope: meta.paragraph.list.markdown - - match: ^\s*$ - pop: true - - include: inline - - match: '^\s*([*+-]|[0-9]+\.)' - comment: Match the list punctuation - captures: - 1: punctuation.definition.list_item.markdown - numeric: - - match: '(?<!\$)\b((0([box])[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b' - scope: constant.numeric.coffee - raw: - - match: '(`+)([^`]|(?!(?<!`)\1(?!`))`)*+(\1)' - scope: markup.raw.inline.markdown - captures: - 1: punctuation.definition.raw.markdown - 3: punctuation.definition.raw.markdown - separator: - - match: '\G[ ]{,3}([-*_])([ ]{,2}\1){2,}[ \t]*$\n?' - scope: meta.separator.markdown + ^[ \t]* # leading whitespace + ( \1 (?:(?:\2)*|(?:\3)*) ) # punctuation + (\s*$\n?) # fold marker + escape_captures: + 0: meta.code-fence.definition.end.markdown-gfm + 1: punctuation.definition.raw.code-fence.end.markdown + 2: meta.fold.code-fence.end.markdown diff --git a/CoffeeScript.sublime-settings b/CoffeeScript.sublime-settings index bd6df7e..1f33dab 100644 --- a/CoffeeScript.sublime-settings +++ b/CoffeeScript.sublime-settings @@ -1,4 +1,6 @@ { + "word_separators": "./\\()\"'-:,.;<>~!@#%^&*|+=[]{}`~?", + /* The directories you would like to include in $PATH environment variable. Use this if your node installation is at a seperate location and getting errors such as `cannot find node executable` diff --git a/CoffeeScript.sublime-syntax b/CoffeeScript.sublime-syntax index 9eaf4d3..af41781 100644 --- a/CoffeeScript.sublime-syntax +++ b/CoffeeScript.sublime-syntax @@ -1,9 +1,10 @@ %YAML 1.2 --- -# http://www.sublimetext.com/docs/syntax.html -# CoffeeScript Syntax: version 1 +# https://coffeescript.org/ +# https://www.sublimetext.com/docs/syntax.html name: CoffeeScript scope: source.coffee +version: 2 file_extensions: - coffee @@ -14,8 +15,8 @@ file_extensions: first_line_match: |- (?xi: - ^ \#! .* \b(coffee(-script)?)\b # shebang - | ^ \s* \# .*? -\*- .*? \bcoffee(-script)?\b .*? -\*- # editorconfig + ^ \#! .* \b(coffee(-script)?(?:\d(?:\.\d+)?)?)\b # shebang + | ^ \s* \# .*? -\*- .*? \bcoffee(-script)?(?:\d(?:\.\d+)?)?\b .*? -\*- # editorconfig ) ############################################################################## @@ -28,13 +29,14 @@ contexts: push: [script, shebang] script: - - include: classes - - include: keywords - include: functions + - include: classes + - include: jsx-tags - include: expressions expressions: - include: comments + - include: keywords - include: constants - include: function-calls - include: patterns @@ -45,9 +47,8 @@ contexts: - include: triple-single-quoted-strings - include: double-quoted-strings - include: single-quoted-strings - - include: instance-variables - include: numbers - - include: objects + - include: variables ###[ COMMENTS ]############################################################### @@ -63,7 +64,7 @@ contexts: - meta_scope: comment.block.coffee - match: \###(?!#) scope: punctuation.definition.comment.coffee - pop: true + pop: 1 - match: (@)\w* scope: variable.annotation.coffee captures: @@ -72,7 +73,7 @@ contexts: line-comment-body: - meta_scope: comment.line.number-sign.coffee - match: $\n? - pop: true + pop: 1 shebang: - meta_include_prototype: false @@ -80,27 +81,61 @@ contexts: scope: punctuation.definition.comment.coffee set: shebang-body - match: ^|(?=\S) # Note: Ensure to highlight shebang if Python is embedded. - pop: true + pop: 1 shebang-body: - meta_include_prototype: false - meta_scope: comment.line.shebang.coffee # Note: Keep sync with first_line_match! - - match: coffee(?:\d(?:\.\d+)?)?\b + - match: coffee(-script)?(?:\d(?:\.\d+)?)?{{break}} scope: constant.language.shebang.coffee - match: $\n? - pop: true + pop: 1 ###[ CLASS DECLARATIONS ]##################################################### classes: - - match: (class\b)\s+((?!extends)@?[a-zA-Z\$_][\w\.]*)?(?:\s*(extends)\s+(@?[a-zA-Z\$\._][\w\.]*))? - scope: meta.class.coffee + - match: class{{break}} + scope: meta.class.coffee keyword.declaration.class.coffee + push: + - class-extends + - class-name + + class-name: + - match: (?=extends{{break}}) + pop: 1 + - match: ({{identifier}})(\.) + captures: + 1: support.class.coffee + 2: punctuation.accessor.dot.coffee + - match: '{{identifier}}' + scope: entity.name.class.coffee + pop: 1 + - include: comments + - include: else-pop + - include: eol-pop + + class-extends: + - meta_content_scope: meta.class.identifier.coffee + - match: extends{{break}} + scope: storage.modifier.extends.coffee + set: class-extends-name + - include: comments + - include: else-pop + - include: eol-pop + + class-extends-name: + - meta_scope: meta.class.extends.coffee + - match: ({{identifier}})(\.) captures: - 1: storage.type.class.coffee - 2: entity.name.type.class.coffee - 3: keyword.control.inheritance.coffee - 4: entity.other.inherited-class.coffee + 1: support.class.coffee + 2: punctuation.accessor.dot.coffee + - match: '{{identifier}}' + scope: entity.other.inherited-class.coffee + pop: 1 + - include: comments + - include: else-pop + - include: eol-pop ###[ FUNCTION DECLARATIONS ]################################################## @@ -110,39 +145,85 @@ contexts: push: - meta_scope: meta.function.symbols.coffee - match: $ - pop: true + pop: 1 - include: script # anonymous functions - - match: (?=\([^()]*?\)\s*[=-]>) - push: function-parameter-list + - match: (?=\() + branch_point: anonymous + branch: + - group + - anonymous-parameter-list # named functions - - match: |- - (?x) - \s* - ( [a-zA-Z\$_@] [\w\$:.]* ) \s* - (?=[:=](?: \s*.\( $ | (?: \s*\(.*\) )? \s* [=-]> ) ) - scope: meta.function.identifier.coffee - captures: - 1: entity.name.function.coffee - push: function-parameter-list + - match: (?=(?:(?!and=|or=)){{identifier}}\s*[:=][^>]) + branch_point: function + branch: + - function-name + - variable - match: '[=-]>' scope: keyword.declaration.function.coffee - function-parameter-list: + anonymous-parameter-list: + - match: \( + scope: punctuation.section.parameters.begin.coffee + set: + - anonymous-body + - function-parameter-list-body + - include: comments + - include: else-pop + + anonymous-body: - meta_content_scope: meta.function.coffee + - match: '[=-]>' + scope: meta.function.coffee keyword.declaration.function.coffee + pop: 1 + + group: + - match: \( + scope: punctuation.section.group.begin.coffee + set: group-body + + group-body: + - meta_scope: meta.group.coffee + - match: \) + scope: punctuation.section.group.end.coffee + set: group-check + - include: expressions + + group-check: + - match: (?=[=-]>) + fail: anonymous + - include: else-pop + + function-name: + - meta_include_prototype: false + - match: '{{identifier}}' + scope: meta.function.identifier.coffee entity.name.function.coffee + push: + - function-body + - function-parameter-list + - function-assignment + - include: immediately-pop + + function-assignment: + - meta_include_prototype: false - match: '[:=](?!>)' scope: keyword.operator.assignment.coffee + pop: 1 + - include: else-pop + + function-parameter-list: - match: \( scope: punctuation.section.parameters.begin.coffee set: function-parameter-list-body - - match: (?=\S) - set: function-body + - include: comments + - include: else-pop function-parameter-list-body: + - clear_scopes: 1 - meta_scope: meta.function.parameters.coffee - match: \) scope: punctuation.section.parameters.end.coffee - set: function-body + pop: 1 - match: '[:=]' scope: keyword.operator.assignment.coffee push: parameter-value @@ -155,15 +236,17 @@ contexts: parameter-value: - match: (?=[,)]) - pop: true + pop: 1 - include: expressions function-body: - meta_content_scope: meta.function.coffee - match: '[=-]>' scope: meta.function.coffee keyword.declaration.function.coffee - pop: true - - include: else-pop + pop: 2 + # any non-whitespace char or end of file + - match: (?=\S|\Z) + fail: function ###[ FUNCTION CALLS ]######################################################### @@ -171,18 +254,18 @@ contexts: - match: |- (?x) ( decodeURI(?: Component)? | encodeURI(?: Component)? | eval - | parse(?: Float | Int ) | require )\b + | parse(?: Float | Int ) | require ){{break}} scope: support.function.coffee - match: |- (?x) (console) (?: (\.) - ( assert | debug | dir | error | info | log | time | timeEnd | warn )\b + ( assert | debug | dir | error | info | log | time | timeEnd | warn ){{break}} )? scope: meta.path.coffee captures: - 1: variable.language.console.coffee + 1: support.class.console.coffee 2: punctuation.accessor.dot.coffee 3: support.function.console.coffee - match: |- @@ -191,7 +274,7 @@ contexts: ( apply | call | concat | every | filter | forEach | from | hasOwnProperty | indexOf | isPrototypeOf | join | lastIndexOf | map | of | pop | propertyIsEnumerable | push | reduce(?:Right)? | reverse | shift | slice - | some | sort | splice | to(?:Locale)?String | unshift | valueOf )\b + | some | sort | splice | to(?:Locale)?String | unshift | valueOf ){{break}} scope: meta.path.coffee captures: 1: punctuation.accessor.dot.coffee @@ -201,7 +284,7 @@ contexts: (Array) (?: (\.) - ( isArray )\b + ( isArray ){{break}} )? scope: meta.path.coffee captures: @@ -215,7 +298,7 @@ contexts: (\.) ( create | definePropert(?: ies | y ) | freeze | getOwnProperty(?: Descriptors? | Names ) | getProperty(Descriptor | Names) | getPrototypeOf | is(?: Extensible | Frozen | Sealed)? - | isnt | keys | preventExtensions | seal )\b + | isnt | keys | preventExtensions | seal ){{break}} )? scope: meta.path.coffee captures: @@ -230,7 +313,7 @@ contexts: ( abs | acos | acosh | asin | asinh | atan | atan2 | atanh | ceil | cos | cosh | exp | expm1 | floor | hypot | log | log10 | log1p | log2 | max | min | pow | random | round | sign | sin | sinh | sqrt | tan | tanh - | trunc )\b + | trunc ){{break}} )? scope: meta.path.coffee captures: @@ -242,7 +325,7 @@ contexts: (Number) (?: (\.) - ( is(?: Finite | Integer | NaN ) | toInteger )\b + ( is(?: Finite | Integer | NaN ) | toInteger ){{break}} )? scope: meta.path.coffee captures: @@ -252,10 +335,10 @@ contexts: # other classes - match: |- (?x) - \b( ArrayBuffer | Blob | Boolean | Date | document | event + ( ArrayBuffer | Blob | Boolean | Date | document | event | Float(?: 32 | 64)Array | Function | Int(?: 8 | 16 | 32 | 64)Array | Map | Proxy | RegExp | Set | String | WeakMap | window - | Uint(?: 8 | 16 | 32 | 64)Array | XMLHttpRequest | Symbol )\b + | Uint(?: 8 | 16 | 32 | 64)Array | XMLHttpRequest | Symbol ){{break}} scope: support.class.coffee # user function calls - match: '{{identifier}}(?=\()' @@ -271,58 +354,85 @@ contexts: - meta_scope: meta.function-call.arguments.coffee - match: \) scope: punctuation.section.group.end.coffee - pop: true + pop: 1 - include: script ###[ KEYWORDS ]############################################################### keywords: # export/import - - match: export(?!\s*:)\b + - match: export{{break}} scope: keyword.control.export.coffee - - match: (?:import|from)(?!\s*:)\b + - match: (?:import|from){{break}} scope: keyword.control.import.coffee - # excpetion - - match: (?:catch|finally|try)(?!\s*:)\b - scope: keyword.control.exception.coffee # conditional - - match: if(?!\s*:)\b + - match: if{{break}} scope: keyword.control.conditional.if.coffee - - match: else(?!\s*:)\b + - match: else{{break}} scope: keyword.control.conditional.else.coffee - - match: switch(?!\s*:)\b + - match: switch{{break}} scope: keyword.control.conditional.switch.coffee - - match: then(?!\s*:)\b + - match: then{{break}} scope: keyword.control.conditional.then.coffee - - match: unless(?!\s*:)\b + - match: unless{{break}} scope: keyword.control.conditional.unless.coffee - - match: when(?!\s*:)\b + - match: when{{break}} scope: keyword.control.conditional.when.coffee + # exceptions + - match: catch{{break}} + scope: keyword.control.exception.catch.coffee + - match: finally{{break}} + scope: keyword.control.exception.finally.coffee + - match: try{{break}} + scope: keyword.control.exception.try.coffee # loop - - match: by(?!\s*:)\b + - match: by{{break}} scope: keyword.control.loop.by.coffee - - match: do(?!\s*:)\b - scope: keyword.control.loop.do.coffee - - match: for(?:\s+own)?(?!\s*:)\b + - match: for(?:\s+own)?{{break}} scope: keyword.control.loop.for.coffee - - match: loop(?!\s*:)\b - scope: keyword.control.loop.loopcoffee - - match: until(?!\s*:)\b + push: for-args + - match: loop{{break}} + scope: keyword.control.loop.loop.coffee + - match: until{{break}} scope: keyword.control.loop.until.coffee - - match: while(?!\s*:)\b + - match: while{{break}} scope: keyword.control.loop.while.coffee # flow - - match: (?:break|continue|return|throw|yield(?:\s+from)?)(?!\s*:)\b - scope: keyword.control.flow.coffee + - match: await{{break}} + scope: keyword.control.flow.await.coffee + - match: break{{break}} + scope: keyword.control.flow.break.coffee + - match: continue{{break}} + scope: keyword.control.flow.continue.coffee + - match: do{{break}} + scope: keyword.control.flow.do.coffee + - match: return{{break}} + scope: keyword.control.flow.return.coffee + - match: throw{{break}} + scope: keyword.control.flow.throw.coffee + - match: yield(?:\s+from)?{{break}} + scope: keyword.control.flow.yield.coffee # other - - match: (?:debugger\b|\\) - scope: keyword.other.coffee + - match: (?:debugger{{break}}|\\) + scope: keyword.control.coffee + + for-args: + - match: in{{break}} + scope: keyword.control.loop.in.coffee + pop: 1 + - match: of{{break}} + scope: keyword.control.loop.of.coffee + pop: 1 + - match: ',' + scope: punctuation.separator.sequence.coffee + - include: variables + - include: else-pop operators: # symbolic - match: (?:and|or|<<|>>>?|[-+*/%&|^])= scope: keyword.operator.assignment.augmented.coffee - - match: \+\+?|\-\-?|[*/%] + - match: \+\+?|\-\-?|\*\*?|//?|%%? scope: keyword.operator.arithmetic.coffee - match: '[=!]==?|[<>]=?' scope: keyword.operator.comparison.coffee @@ -335,22 +445,22 @@ contexts: - match: \.{2,3} scope: keyword.operator.variadic.coffee # alphanumeric - - match: (?:as)\b + - match: as{{break}} scope: keyword.operator.word.coffee keyword.operator.assignment.as.coffee - - match: (?:in|of)\b - scope: keyword.operator.word.coffee keyword.operator.iterator.coffee - - match: (?:and|or|is|isnt|not)\b + - match: (?:in|is(?:nt| not)?|of){{break}} + scope: keyword.operator.word.coffee keyword.operator.comparison.coffee + - match: (?:and|or|not){{break}} scope: keyword.operator.word.coffee keyword.operator.logical.coffee - - match: (?:new)\b + - match: new{{break}} scope: keyword.operator.word.coffee keyword.operator.object.new.coffee push: maybe-class - - match: (?:delete)\b + - match: delete{{break}} scope: keyword.operator.word.coffee keyword.operator.object.delete.coffee - - match: (?:super)\b - scope: keyword.operator.word.coffee keyword.operator.object.super.coffee - - match: (?:instanceof|typeof)\b + - match: instanceof{{break}} scope: keyword.operator.word.coffee keyword.operator.comparison.type.coffee push: maybe-class + - match: typeof{{break}} + scope: keyword.operator.word.coffee keyword.operator.object.typeof.coffee maybe-class: - match: ({{identifier}})?(\.) @@ -359,47 +469,21 @@ contexts: 2: punctuation.accessor.dot.coffee - match: '{{identifier}}' scope: support.class.coffee - pop: true + set: maybe-class-arguments - include: else-pop -###[ OBJECTS ]################################################################ - - objects: - - match: (?:this|extends)(?!\s*[:=])\b - scope: variable.language.coffee - - match: ({{identifier}})?(\.) - captures: - 1: variable.other.object.coffee - 2: punctuation.accessor.dot.coffee - push: member - - match: '{{identifier}}' - scope: variable.other.readwrite.coffee + maybe-class-arguments: + - match: \( + scope: punctuation.section.group.begin.coffee + set: class-arguments-body + - include: else-pop - member: - - meta_scope: meta.path.coffee - # member objects - - match: ({{identifier}})(\.) - captures: - 1: variable.other.object.coffee - 2: punctuation.accessor.dot.coffee - # method - - match: '{{identifier}}(?=\()' - scope: meta.function-call.identifier.coffee variable.function.coffee - set: function-call-argument-list - # member variable - - match: '{{identifier}}' - scope: variable.other.member.coffee + class-arguments-body: + - meta_scope: meta.group.coffee + - match: \) + scope: punctuation.section.group.end.coffee pop: 1 - - include: immediately-pop - - variables: - # member objects - - match: ({{identifier}})(\.) - captures: - 1: variable.other.object.coffee - 2: punctuation.accessor.dot.coffee - - match: '{{identifier}}' - scope: variable.other.member.coffee + - include: script ###[ OPERATORS ]############################################################## @@ -424,67 +508,77 @@ contexts: - match: \, scope: punctuation.separator.sequence.coffee -###[ REGULAR EXPRESSIONS ]##################################################### - - patterns: - - match: /{3} - scope: punctuation.definition.string.begin.coffee - push: heredoc-pattern-body - - match: (/)((?![\s=/*+{}?])(?:\\.|.)*?)(/)([igmy]{0,4}(?![a-zA-Z0-9])) - scope: meta.string.regexp.coffee - captures: - 1: punctuation.definition.string.begin.coffee - 2: string.regexp.coffee - 3: punctuation.definition.string.end.coffee - 4: constant.language.flags.coffee - - heredoc-pattern-body: - - meta_scope: meta.string.heredoc.coffee - - meta_content_scope: string.regexp.coffee - - match: (/{3})([imgy]{0,4}) - captures: - 1: punctuation.definition.string.end.coffee - 2: constant.language.flags.coffee - pop: true - - include: comments - - include: string-escapes - - include: string-interpolations - ###[ LITERALS ]################################################################ constants: - - match: (?:Infinity|NaN|undefined)\b - scope: constant.language.coffee - - match: (?:true|on|yes)(?!\s*[:=])\b + - match: (?:true|on|yes)(?!\s*[:=]){{break}} scope: constant.language.boolean.true.coffee - - match: (?:false|off|no)(?!\s*[:=])\b + - match: (?:false|off|no)(?!\s*[:=]){{break}} scope: constant.language.boolean.false.coffee - - match: null(?!\s*[:=])\b + - match: Infinity(?!\s*[:=]){{break}} + scope: constant.language.infinity.coffee + - match: NaN(?!\s*[:=]){{break}} + scope: constant.language.nan.coffee + - match: undefined(?!\s*[:=]){{break}} + scope: constant.language.coffee + - match: null(?!\s*[:=]){{break}} scope: constant.language.null.coffee numbers: - - match: \b(0b)([01]+)\b + - match: (0b)({{bin_digit}}+){{break}} scope: meta.number.integer.binary.coffee captures: 1: constant.numeric.base.coffee 2: constant.numeric.value.coffee - - match: \b(0o)([0-7]+)\b + - match: (0o)({{oct_digit}}+){{break}} scope: meta.number.integer.octal.coffee captures: 1: constant.numeric.base.coffee 2: constant.numeric.value.coffee - - match: \b(0x)(\h+)\b + - match: (0x)({{hex_digit}}+){{break}} scope: meta.number.integer.hexadecimal.coffee captures: 1: constant.numeric.base.coffee 2: constant.numeric.value.coffee - - match: \b\d+(?:(\.)\d*(?:e[-+]?\d+)?|(?:e[-+]?\d+))\b + # floats + - match: |- + (?x: + # 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1 | 1e1, 1e-1 + {{dec_integer}} (?: (\.) {{dec_digit}}* (?:{{dec_exponent}})? | {{dec_exponent}} ) + # .1, .1e1, .1e-1 + | (\.) {{dec_digit}}+ (?:{{dec_exponent}})? + ){{break}} scope: meta.number.float.decimal.coffee constant.numeric.value.coffee captures: 1: punctuation.separator.decimal.coffee - - match: \b\d+\b + 2: punctuation.separator.decimal.coffee + - match: '{{dec_integer}}{{break}}' scope: meta.number.integer.decimal.coffee constant.numeric.value.coffee + patterns: + - match: /{3} + scope: punctuation.definition.string.begin.coffee + push: heredoc-pattern-body + - match: (/)((?![\s=/*+{}?])(?:\\.|.)*?)(/)([igmy]{0,4}(?![a-zA-Z0-9])) + scope: meta.string.regexp.coffee + captures: + 1: punctuation.definition.string.begin.coffee + 2: string.regexp.coffee + 3: punctuation.definition.string.end.coffee + 4: constant.language.flags.coffee + + heredoc-pattern-body: + - meta_scope: meta.string.heredoc.coffee + - meta_content_scope: string.regexp.coffee + - match: (/{3})([imgy]{0,4}) + captures: + 1: punctuation.definition.string.end.coffee + 2: constant.language.flags.coffee + pop: 1 + - include: comments + - include: string-escapes + - include: string-interpolations + triple-double-quoted-strings: - match: \"{3} scope: punctuation.definition.string.begin.coffee @@ -494,7 +588,7 @@ contexts: - meta_scope: meta.string.heredoc.coffee string.quoted.double.coffee - match: \"{3} scope: punctuation.definition.string.end.coffee - pop: true + pop: 1 - match: \\. scope: constant.character.escape.coffee - include: string-interpolations @@ -508,19 +602,23 @@ contexts: - meta_scope: meta.string.heredoc.coffee string.quoted.single.coffee - match: \'{3} scope: punctuation.definition.string.end.coffee - pop: true + pop: 1 backtick-quoted-strings: + - match: \`{3} + scope: meta.string.heredoc.coffee string.quoted.script.coffee punctuation.definition.string.begin.coffee + embed: scope:source.jsx + embed_scope: meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee + escape: '{{no_escape_behind}}`{3}' + escape_captures: + 0: meta.string.heredoc.coffee string.quoted.script.coffee punctuation.definition.string.end.coffee - match: \` - scope: punctuation.definition.string.begin.coffee - push: backtick-quoted-string-body - - backtick-quoted-string-body: - - meta_scope: meta.string.coffee string.quoted.script.coffee - - match: \` - scope: punctuation.definition.string.end.coffee - pop: true - - include: string-escapes + scope: meta.string.coffee string.quoted.script.coffee punctuation.definition.string.begin.coffee + embed: scope:source.jsx + embed_scope: meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee + escape: '{{no_escape_behind}}`' + escape_captures: + 0: meta.string.coffee string.quoted.script.coffee punctuation.definition.string.end.coffee double-quoted-strings: - match: \" @@ -531,7 +629,7 @@ contexts: - meta_scope: meta.string.coffee string.quoted.double.coffee - match: \" scope: punctuation.definition.string.end.coffee - pop: true + pop: 1 - include: string-escapes - include: string-interpolations @@ -544,7 +642,7 @@ contexts: - meta_scope: meta.string.coffee string.quoted.single.coffee - match: \' scope: punctuation.definition.string.end.coffee - pop: true + pop: 1 - include: string-escapes string-escapes: @@ -564,7 +662,7 @@ contexts: - meta_scope: meta.embedded.coffee source.coffee.embedded.source - match: \} scope: punctuation.section.embedded.coffee - pop: true + pop: 1 - include: script string-embedded-body: @@ -572,30 +670,318 @@ contexts: - meta_scope: meta.embedded.coffee source.coffee.embedded.source - match: '%>' scope: punctuation.section.embedded.coffee - pop: true + pop: 1 - include: script -###[ VARIABLES ]############################################################### +###[ JSX TAGS ]################################################################ - instance-variables: - - match: (@)(?:{{identifier}})? - scope: variable.other.readwrite.instance.coffee + jsx-tags: + - match: (<)(?:({{component_names}})|({{tag_names}}))(?=\s|/?>) captures: - 1: punctuation.definition.variable.coffee + 1: punctuation.definition.tag.begin.coffee + 2: entity.name.tag.component.coffee + 3: entity.name.tag.coffee + push: + - jsx-meta + - jsx-tag-open-body + + jsx-meta: + - meta_include_prototype: false + - meta_scope: meta.jsx.coffee + - include: immediately-pop + + jsx-body: + - match: (</)(?:({{component_names}})|({{tag_names}}))(?=\s|/?>) + captures: + 1: punctuation.definition.tag.begin.coffee + 2: entity.name.tag.component.coffee + 3: entity.name.tag.coffee + set: jsx-tag-close-body + - match: (<)(?:({{component_names}})|({{tag_names}}))(?=\s|/?>) + captures: + 1: punctuation.definition.tag.begin.coffee + 2: entity.name.tag.component.coffee + 3: entity.name.tag.coffee + push: jsx-tag-open-body + - include: jsx-text-interpolations + + jsx-tag-close-body: + - meta_include_prototype: false + - meta_scope: meta.tag.coffee + - match: /?> + scope: punctuation.definition.tag.end.coffee + pop: 1 + + jsx-tag-open-body: + - meta_include_prototype: false + - meta_scope: meta.tag.coffee + - match: /> + scope: punctuation.definition.tag.end.coffee + pop: 1 + - match: \> + scope: punctuation.definition.tag.end.coffee + set: jsx-body + - match: '{{attribute_name_start}}' + push: + - jsx-tag-attribute-meta + - jsx-tag-attribute-assignment + - jsx-tag-attribute-name + + jsx-tag-attribute-name: + - meta_scope: entity.other.attribute-name.coffee + - include: jsx-string-interpolations + - match: '{{attribute_name_break}}' + pop: 1 + - match: '["''`<]' + scope: invalid.illegal.attribute-name.coffee + + jsx-tag-attribute-meta: + - meta_include_prototype: false + - meta_scope: meta.attribute-with-value.coffee + - include: immediately-pop + + jsx-tag-attribute-assignment: + - meta_include_prototype: false + - match: = + scope: punctuation.separator.key-value.coffee + set: jsx-tag-attribute-value + - include: else-pop + + jsx-tag-attribute-value: + - meta_include_prototype: false + - match: \" + scope: punctuation.definition.string.begin.coffee + set: jsx-tag-attribute-value-double-quoted-content + - match: \' + scope: punctuation.definition.string.begin.coffee + set: jsx-tag-attribute-value-single-quoted-content + - match: '{{unquoted_attribute_start}}' + set: jsx-tag-attribute-value-unquoted-content + - include: else-pop + + jsx-tag-attribute-value-double-quoted-content: + # See the top of this file for why prototype is excluded + - meta_include_prototype: false + - meta_scope: meta.string.coffee string.quoted.double.coffee + - match: \" + scope: punctuation.definition.string.end.coffee + pop: 1 + - include: jsx-string-interpolations + + jsx-tag-attribute-value-single-quoted-content: + # See the top of this file for why prototype is excluded + - meta_include_prototype: false + - meta_scope: meta.string.coffee string.quoted.single.coffee + - match: \' + scope: punctuation.definition.string.end.coffee + pop: 1 + - include: jsx-string-interpolations + + jsx-tag-attribute-value-unquoted-content: + # See the top of this file for why prototype is excluded + - meta_include_prototype: false + - meta_content_scope: meta.string.coffee string.unquoted.coffee + - include: jsx-string-interpolations + - match: '{{unquoted_attribute_break}}' + pop: 1 + - match: '["''`<]' + scope: invalid.illegal.attribute-value.coffee + + jsx-string-interpolations: + - match: \{# + scope: punctuation.definition.comment.begin.coffee + push: jsx-string-comment-body + - match: \{ + scope: punctuation.section.interpolation.begin.coffee + push: jsx-string-interpolation-body + + jsx-string-comment-body: + # required to support "toggle_comment" + - clear_scopes: 1 + - meta_scope: meta.interpolation.coffee comment.block.coffee + - include: jsx-text-comment-body + + jsx-string-interpolation-body: + - clear_scopes: 1 + - meta_scope: meta.interpolation.coffee + - meta_content_scope: source.coffee.embedded.jsx + - include: jsx-text-interpolation-body + + jsx-text-interpolations: + - match: \{# + scope: punctuation.definition.comment.begin.coffee + push: jsx-text-comment-body + - match: \{ + scope: punctuation.section.interpolation.begin.coffee + push: jsx-text-interpolation-body + + jsx-text-comment-body: + # required to support "toggle_comment" + - meta_scope: meta.interpolation.coffee comment.block.coffee + - match: \} + scope: punctuation.definition.comment.end.coffee + pop: 1 + + jsx-text-interpolation-body: + - meta_scope: meta.interpolation.coffee + - meta_content_scope: source.coffee.embedded.jsx + - match: \} + scope: punctuation.section.interpolation.end.coffee + pop: 1 + - match: \# + scope: punctuation.definition.comment.coffee + push: jsx-line-comment-body + - include: script + + jsx-line-comment-body: + - meta_scope: comment.line.number-sign.coffee + - match: $\n?|(?=}) + pop: 1 + +###[ VARIABLES ]############################################################## + + variables: + - match: (super)(\.) + captures: + 1: variable.language.super.coffee + 2: punctuation.accessor.dot.coffee + push: member + - match: super(?!\s*[:=]){{break}} + scope: variable.language.super.coffee + - match: (this)(\.) + captures: + 1: variable.language.this.coffee + 2: punctuation.accessor.dot.coffee + push: member + - match: this(?!\s*[:=]){{break}} + scope: variable.language.this.coffee + - match: \@ + scope: variable.language.this.coffee + push: member + - match: ({{identifier}})?(\.) + captures: + 1: variable.other.object.coffee + 2: punctuation.accessor.dot.coffee + push: member + - match: '{{identifier}}' + scope: variable.other.readwrite.coffee + + variable: + - match: (super)(\.) + captures: + 1: variable.language.super.coffee + 2: punctuation.accessor.dot.coffee + set: member + - match: super(?!\s*[:=]){{break}} + scope: variable.language.super.coffee + - match: (this)(\.) + captures: + 1: variable.language.this.coffee + 2: punctuation.accessor.dot.coffee + set: member + - match: this(?!\s*[:=]){{break}} + scope: variable.language.this.coffee + - match: \@ + scope: variable.language.this.coffee + set: member + - match: ({{identifier}})?(\.) + captures: + 1: variable.other.object.coffee + 2: punctuation.accessor.dot.coffee + set: member + - match: '{{identifier}}' + scope: variable.other.readwrite.coffee + pop: 1 + + member: + - meta_scope: meta.path.coffee + # member objects + - match: ({{identifier}})(\.) + captures: + 1: variable.other.object.coffee + 2: punctuation.accessor.dot.coffee + # method + - match: '{{identifier}}(?=\()' + scope: meta.function-call.identifier.coffee variable.function.coffee + set: function-call-argument-list + # member function definition or variable + - match: (?=(?:(?!and=|or=)){{identifier}}) + branch_point: member + branch: + - member-function + - member-variable + pop: 1 + - include: immediately-pop + + member-function: + - meta_include_prototype: false + - match: '{{identifier}}' + scope: meta.function.identifier.coffee meta.path.coffee entity.name.function.coffee + push: + - member-function-body + - function-parameter-list + - function-assignment + - include: immediately-pop + + member-function-body: + - meta_content_scope: meta.function.coffee + - match: '[=-]>' + scope: meta.function.coffee keyword.declaration.function.coffee + pop: 2 + - match: (?=\S|\Z) + fail: member + + member-variable: + - match: '{{identifier}}' + scope: meta.path.coffee variable.other.member.coffee + pop: 1 + - include: immediately-pop ###[ PROTOTYPES ]############################################################## else-pop: - match: (?=\S) - pop: true + pop: 1 + + eol-pop: + - match: $ + pop: 1 immediately-pop: + - meta_include_prototype: false - match: '' - pop: true + pop: 1 ############################################################################### - variables: - identifier: '[a-zA-Z\$_]\w*' + ascii_space: '\t\n\f ' + break: (?!{{ident_char}}) + + # A lookbehind used in embed..escape patterns, to check for unescaped characters + # in embed...escape statements. + no_escape_behind: (?<![^\\]\\)(?<![\\]{3}) + + bin_digit: '[01_]' + oct_digit: '[0-7_]' + dec_digit: '[0-9_]' + hex_digit: '[\h_]' + dec_integer: (?:0|[1-9]{{dec_digit}}*) + dec_exponent: '[Ee](?:[-+]|(?![-+])){{dec_digit}}*' + + identifier: '{{ident_start}}{{ident_char}}*' + ident_start: '[[:alpha:]$_]' + ident_char: '[[:alnum:]$_]' + + component_names: '[A-Z][[:alnum:]_.-]*' + tag_names: '[[:alpha:]][[:alnum:]_.-]*' + + # https://html.spec.whatwg.org/multipage/syntax.coffee#attributes-2 + attribute_name_break_char: '[{{ascii_space}}=/>]' + attribute_name_break: (?={{attribute_name_break_char}}) + attribute_name_start: (?=[^{{attribute_name_break_char}}]) + + # https://html.spec.whatwg.org/multipage/syntax.coffee#syntax-attribute-value + unquoted_attribute_break: (?=[{{ascii_space}}]|/?>) + unquoted_attribute_start: (?=[^{{ascii_space}}=>]) diff --git a/Comments JSX.tmPreferences b/Comments JSX.tmPreferences new file mode 100644 index 0000000..6448f16 --- /dev/null +++ b/Comments JSX.tmPreferences @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>source.coffee meta.jsx, source.coffee meta.jsx meta.interpolation comment.line</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>{# </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END</string> + <key>value</key> + <string> }</string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/Default (Linux).sublime-keymap b/Default (Linux).sublime-keymap index 11d3b1b..7b5539f 100644 --- a/Default (Linux).sublime-keymap +++ b/Default (Linux).sublime-keymap @@ -1,11 +1,65 @@ [ - {"keys": ["alt+shift+s"], "command": "check_syntax"}, - {"keys": ["alt+shift+r"], "command": "run_script"}, - {"keys": ["alt+shift+t"], "command": "run_cake_task"}, - {"keys": ["alt+shift+c"], "command": "compile"}, - {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}}, - {"keys": ["alt+shift+l"], "command": "compile_and_display", "args": {"opt": "-t"}}, - {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}}, - {"keys": ["alt+shift+w"], "command": "toggle_watch"}, - {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} + // { + // "keys": ["alt+shift+s"], + // "command": "check_syntax", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+r"], + // "command": "run_script", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+t"], + // "command": "run_cake_task", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+c"], + // "command": "compile", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+d"], + // "command": "compile_and_display", "args": {"opt": "-p"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+l"], + // "command": "compile_and_display", "args": {"opt": "-t"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+n"], + // "command": "compile_and_display", "args": {"opt": "-n"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+w"], + // "command": "toggle_watch", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+z"], + // "command": "toggle_output_panel", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // } ] diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap index 3c125a3..af2329c 100644 --- a/Default (OSX).sublime-keymap +++ b/Default (OSX).sublime-keymap @@ -1,11 +1,65 @@ [ - {"keys": ["alt+shift+s"], "command": "check_syntax"}, - {"keys": ["alt+shift+r"], "command": "run_script"}, - {"keys": ["alt+shift+t"], "command": "run_cake_task"}, - {"keys": ["alt+shift+c"], "command": "compile"}, - {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}}, - {"keys": ["alt+shift+x"], "command": "compile_and_display", "args": {"opt": "-t"}}, - {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}}, - {"keys": ["alt+shift+w"], "command": "toggle_watch"}, - {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} -] + // { + // "keys": ["alt+shift+s"], + // "command": "check_syntax", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+r"], + // "command": "run_script", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+t"], + // "command": "run_cake_task", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+c"], + // "command": "compile", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+d"], + // "command": "compile_and_display", "args": { "opt": "-p" }, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+x"], + // "command": "compile_and_display", "args": { "opt": "-t" }, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+n"], + // "command": "compile_and_display", "args": { "opt": "-n" }, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+w"], + // "command": "toggle_watch", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+z"], + // "command": "toggle_output_panel", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // } +] \ No newline at end of file diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap index 11d3b1b..7b5539f 100644 --- a/Default (Windows).sublime-keymap +++ b/Default (Windows).sublime-keymap @@ -1,11 +1,65 @@ [ - {"keys": ["alt+shift+s"], "command": "check_syntax"}, - {"keys": ["alt+shift+r"], "command": "run_script"}, - {"keys": ["alt+shift+t"], "command": "run_cake_task"}, - {"keys": ["alt+shift+c"], "command": "compile"}, - {"keys": ["alt+shift+d"], "command": "compile_and_display", "args": {"opt": "-p"}}, - {"keys": ["alt+shift+l"], "command": "compile_and_display", "args": {"opt": "-t"}}, - {"keys": ["alt+shift+n"], "command": "compile_and_display", "args": {"opt": "-n"}}, - {"keys": ["alt+shift+w"], "command": "toggle_watch"}, - {"keys": ["alt+shift+z"], "command": "toggle_output_panel"} + // { + // "keys": ["alt+shift+s"], + // "command": "check_syntax", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+r"], + // "command": "run_script", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+t"], + // "command": "run_cake_task", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+c"], + // "command": "compile", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+d"], + // "command": "compile_and_display", "args": {"opt": "-p"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+l"], + // "command": "compile_and_display", "args": {"opt": "-t"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+n"], + // "command": "compile_and_display", "args": {"opt": "-n"}, + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+w"], + // "command": "toggle_watch", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // }, + // { + // "keys": ["alt+shift+z"], + // "command": "toggle_output_panel", + // "context": [ + // { "key": "selector", "operand": "source.coffee, source.litcoffee" } + // ] + // } ] diff --git a/HTML (CoffeeScript).sublime-syntax b/HTML (CoffeeScript).sublime-syntax new file mode 100644 index 0000000..c78da88 --- /dev/null +++ b/HTML (CoffeeScript).sublime-syntax @@ -0,0 +1,100 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/syntax.html +name: HTML (CoffeeScript) +scope: text.html.coffee +version: 2 + +extends: Packages/HTML/HTML.sublime-syntax + +file_extensions: + - coffee.html + +contexts: + + script-common: + - meta_prepend: true + - match: (?i:lang(?:uage)?){{attribute_name_break}} + scope: meta.attribute-with-value.lang.html entity.other.attribute-name.html + set: script-lang-attribute-assignment + + script-lang-attribute-assignment: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.lang.html + - match: = + scope: punctuation.separator.key-value.html + set: script-lang-attribute-value + - match: (?=\S) + set: script-javascript + + script-lang-attribute-value: + - meta_include_prototype: false + - meta_scope: meta.tag.script.begin.html meta.attribute-with-value.lang.html + - match: (?=(?i:coffee(?:script)?{{unquoted_attribute_break}}|'coffee(?:script)?'|"coffee(?:script)?")) + set: + - script-coffee + - tag-lang-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - script-javascript + - tag-lang-attribute-meta + - tag-generic-attribute-value + + tag-lang-attribute-meta: + - meta_include_prototype: false + - meta_scope: meta.attribute-with-value.lang.html + - include: immediately-pop + + script-type-decider: + - meta_prepend: true + - match: (?={{coffee_mime_type}}{{unquoted_attribute_break}}|'{{coffee_mime_type}}'|"{{coffee_mime_type}}") + set: + - script-coffee + - tag-type-attribute-meta + - tag-generic-attribute-value + + tag-type-attribute-meta: + # required until ST4184 + - meta_include_prototype: false + - meta_scope: meta.attribute-with-value.type.html + - include: immediately-pop + + script-coffee: + - meta_include_prototype: false + - meta_scope: meta.tag.script.begin.html + - match: '>' + scope: punctuation.definition.tag.end.html + set: script-coffee-content + - include: script-common + + script-coffee-content: + - meta_include_prototype: false + - match: \s*((<!\[)(CDATA)(\[)) + captures: + 1: meta.tag.sgml.cdata.html + 2: punctuation.definition.tag.begin.html + 3: keyword.declaration.cdata.html + 4: punctuation.definition.tag.begin.html + pop: 1 # make sure to match only once + embed: scope:source.coffee + embed_scope: meta.tag.sgml.cdata.html source.coffee.embedded.html + escape: \]\]> + escape_captures: + 0: meta.tag.sgml.cdata.html punctuation.definition.tag.end.html + - match: '{{script_content_begin}}' + captures: + 1: comment.block.html punctuation.definition.comment.begin.html + pop: 1 # make sure to match only once + embed: scope:source.coffee + embed_scope: source.coffee.embedded.html + escape: '{{script_content_end}}' + escape_captures: + 1: source.coffee.embedded.html + 2: comment.block.html punctuation.definition.comment.end.html + 3: source.coffee.embedded.html + 4: comment.block.html punctuation.definition.comment.end.html + +variables: + + coffee_mime_type: |- + (?xi: (?: (?: application | text ) / coffee(?:script)? ) {{mime_type_parameters}}? ) diff --git a/Indentation Rules.tmPreferences b/Indentation Rules.tmPreferences index 5922b59..aaea42e 100644 --- a/Indentation Rules.tmPreferences +++ b/Indentation Rules.tmPreferences @@ -11,7 +11,7 @@ <key>increaseIndentPattern</key> <string>(?x) ^\s* - ( class\b + ( .*\bclass\b(?!\s*:) # class keyword without colon after it (otherwise we are in object with property name "class") | [a-zA-Z\$_](\w|\$|:|\.)*\s*(?=\:(\s*\(.*\))?\s*((=|-)>\s*$)) # function that is not one line | [a-zA-Z\$_](\w|\$|\.)*\s*(:|=)\s*((if|while)(?!.*?then)|for|$) # assignment using multiline if/while/for | (if|while|unless)\b(?!.*?then)|(for|switch|when|loop)\b diff --git a/README.md b/README.md index 59cb54e..d623433 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,107 @@ -## Overview +# CoffeeScript <img src="logo.svg" title="CoffeeScript" width="32" height="32"> + +[CoffeeScript](https://coffeescript.org/) syntax definitions build system and snippets for [Sublime Text](https://www.sublimetext.com). + +![preview](preview.png) **This package is for Sublime Text 3+**. An old version for Sublime Text 2 is accessible via the [`st2` branch](https://github.com/SublimeText/BetterCoffeeScript/tree/st2). -**We are looking for a maintainer!** -See https://github.com/SublimeText/BetterCoffeeScript/issues/244 for details. - -## Description +# Installation -CoffeeScript plug-in was originally created by @Xavura. As I, @aponxi, began writing a lot of code in CoffeeScript, I felt the need for side-by-side view for compiled CoffeeScript. Since Xavura's repository have been inactive I decided to branch out my own version. The biggest change in my branch is the Watch Mode which updates the compiled JavaScript view whenever you modify the CoffeeScript thus enabling you to view your progress side-by-side. +### Package Control -## Contributing +The easiest way to install is using [Package Control](https://packagecontrol.io). It's listed as `CoffeeScript`. -- Please use the [issues page](https://github.com/SublimeText/BetterCoffeeScript/issues) to make requests or report bugs. -- Please make _pull requests_ to the `master` branch only. ST2 is not supported anymore. +1. Open `Command Palette` using <kbd>ctrl+shift+P</kbd> or menu item `Tools → Command Palette...` +2. Choose `Package Control: Install Package` +3. Find `CoffeeScript` and hit <kbd>Enter</kbd> -# Installation +### Manual Install -## via Package Control +1. Download appropriate [CoffeeScript.sublime-package](https://github.com/SublimeText/CoffeeScript/releases) for your Sublime Text build. +2. Copy it into _Installed Packages_ directory -> This is the recommended installation method. +> [!NOTE] +> +> To find _Installed Packages_... +> +> 1. call _Menu > Preferences > Browse Packages.._ +> 2. Navigate to parent folder -If you have [Package Control](https://packagecontrol.io/), you know what to do. If not, well: it's a package manager for Sublime Text 3. Installation guide can be [found here](https://packagecontrol.io/installation). After installing the package manager: +> [!WARNING] +> +> Manually installed packages are not automatically updated by Package Control. -* Open the Command Pallete (`ctrl+shift+P` or `cmd+shift+P`). -* Type "Install Package" and hit return. -* Type "CoffeeScript" and hit return. +### Source Control -## via Source Control - -> If you plan to contribute, then you should install via this method. Otherwise it is recommended that you install the package via Package Control, see above. +> [!TIP] +> +> Only recommended, if contributions to this package are planned. Sublime stores packages in the following locations: - Nix: ~/.config/sublime-text-3/packages - Mac: ~/Library/Application\ Support/Sublime\ Text\ 3/Packages - Win: %APPDATA%\Sublime Text 3\Packages - -When using Sublime Text 4 or higher, -the directory without the "3" (and the preceding separator character) -will be preferred. +```sh +Nix: ~/.config/sublime-text/packages +Mac: ~/Library/Application\ Support/Sublime\ Text/Packages +Win: %APPDATA%\Sublime Text\Packages +``` -### As a repository within the packages directory +#### As a repository within the packages directory Open a Terminal/Console and run the following commands, replacing `PACKAGE_PATH` with the path corresponding to your OS above. - cd PACKAGE_PATH - git clone https://github.com/SublimeText/BetterCoffeeScript.git "CoffeeScript" +```sh +cd PACKAGE_PATH +git clone https://github.com/SublimeText/BetterCoffeeScript.git "CoffeeScript" +``` -### As a repository outside of the packages directory +#### As a repository outside of the packages directory If you use Github for Mac/Windows which store repositories in a specific location, or if you just don't want a repository in your packages directory, then instead you can use a link. -If you don't yet have the repository, then grab it via your GUI program or via the command line: - - cd WHEREVER_YOU_WANT - git clone https://github.com/SublimeText/BetterCoffeeScript.git - -Once that is done, we will create the link: - -#### Windows: - - cd PACKAGE_PATH - mklink /D "CoffeeScript" ABSOLUTE_PATH_TO_REPOSITORY - -#### Nix/Mac: - - cd PACKAGE_PATH - ln -s ABSOLUTE_PATH_TO_REPOSITORY "CoffeeScript" - +1. Clone the repository via GUI program or command line: + + ```sh + cd WHEREVER_YOU_WANT + git clone https://github.com/SublimeText/BetterCoffeeScript.git + ``` + +2. Once that is done, create the link: + + **Windows:** + + ```sh + cd PACKAGE_PATH + mklink /D "CoffeeScript" ABSOLUTE_PATH_TO_REPOSITORY + ``` + + **Nix/Mac:** + + ```sh + cd PACKAGE_PATH + ln -s ABSOLUTE_PATH_TO_REPOSITORY "CoffeeScript" + ``` # Commands/Shortcuts You can access the commands either using the command palette (`ctrl+shift+P` or `cmd+shift+P`) or via shortcuts. - alt+shift+t - Run a Cake task - alt+shift+r - Run some CoffeeScript (prints output to a panel on the bottom) - alt+shift+s - Run a syntax check - alt+shift+c - Compile a file - alt+shift+d - Display compiled JavaScript - alt+shift+l - Display lexer tokens - alt+shift+n - Display parser nodes - alt+shift+w - Toggle watch mode - alt+shift+p - Toggle output panel + alt+shift+t - Run a Cake task + alt+shift+r - Run some CoffeeScript (prints output to a panel on the bottom) + alt+shift+s - Run a syntax check + alt+shift+c - Compile a file + alt+shift+d - Display compiled JavaScript + alt+shift+l - Display lexer tokens + alt+shift+n - Display parser nodes + alt+shift+w - Toggle watch mode + alt+shift+p - Toggle output panel Context menu has `Compile Output` that compiles the current CoffeeScript and outputs the javascript code that is run, in a panel. **Note:** Some of the commands use the Status Bar for output, so you'll probably want to enable it (View » Show Status Bar). - - # Snippets - Use `TAB` to run a snippet after typing the trigger. @@ -101,32 +112,32 @@ Context menu has `Compile Output` that compiles the current CoffeeScript and out **Comprehension** - Array: forin - Object: forof - Range: fori (inclusive) - Range: forx (exclusive) + Array: forin + Object: forof + Range: fori (inclusive) + Range: forx (exclusive) **Statements** - If: if - Else: el - If Else: ifel - Else If: elif - Switch: swi - Ternary: ter - Try Catch: try - Unless: unl + If: if + Else: el + If Else: ifel + Else If: elif + Switch: swi + Ternary: ter + Try Catch: try + Unless: unl **Classes** - Class - cla - Class extends SuperClass - clx + Class - cla + Class extends SuperClass - clx **Other** - Function: - - Function: = (bound) - Interpolation: # + Function: - + Function: = (bound) + Interpolation: # # Building @@ -140,124 +151,113 @@ Let's say before distributing your project that you would like to combine all of That's what this is for! You would create a `Cakefile` and inside it you would write a task: - task 'sbuild', 'Prepare project for distribution.', -> - # ... + task 'sbuild', 'Prepare project for distribution.', -> + # ... # Settings Go to `Preferences > Package Settings > CoffeeScript > Settings - User` to change settings. -```Javascript +```jsonc { - /* - The directories you would like to include in $PATH environment variable. - Use this if your node installation is at a separate location and getting errors such as `cannot find node executable` - - example: - "envPATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - - */ - "envPATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - /* - The directory containing your coffee binary. Usually - /usr/local/bin. - */ - "binDir": "/usr/local/bin" - - /* - Compile without the top-level function wrapper (coffee -b). - */ - -, "noWrapper": true - - /* - Enable or disable refresh the compiled Output on Save. - Only available for watch mode. - */ -, "watchOnSave": true - /* - Enable refreshing compiled JS when CoffeeScript is modified. - - Put false to disable - Put a number of seconds to delay the refresh - */ -, "watchOnModified": 0.5 - /* - Enable Compiling on save. It will compile into the same folder. - */ -, "compileOnSave": true - /* - ## Enable outputting the results of the compiled coffeescript in a panel - */ -, "showOutputOnSave": false - /* - ## Enable compiling to a specific directory. - #### Description - - if it is a string like 'some/directory' then `-o some/directory` will be added to `coffee` compiler. - if it is false or not string then it will compile your `script.coffee` to the directory it is in. - - #### Example: - Directory is relative to the file you are editing if specified such as - compileDir": "out" - Directory is absolute if specified such as - compileDir": "/home/logan/Desktop/out" - - */ -, "compileDir": false - /* - ## Enable compiling to a specific relative directories. - - #### Example: - Set absolute path for compile dir: - "compileDir": "/home/user/projects/js" - And specified folders - "relativeDir": "/home/user/projects/coffee" - "compilePaths": - { - "/home/user/projects/coffee": "/home/user/projects/first/js", - "/home/user/projects/second/coffee": "../js", - } - - So - "/home/user/projects/coffee/app.coffee" will compile to "/home/user/projects/first/js/app.js" - "/home/user/projects/coffee/models/prod.coffee" will compile to "/home/user/projects/first/js/models/prod.js" - "/home/user/projects/coffee/second/coffee/app2.coffee" will compile to "/home/user/projects/second/js/app2.js" - "/home/user/projects/main.coffee" will compile to "/home/user/projects/js/main.js" - - */ -, "compilePaths": false - - - + /* + The directories you would like to include in $PATH environment variable. + Use this if your node installation is at a separate location and getting errors such as `cannot find node executable` + + example: + "envPATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + + */ + "envPATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + /* + The directory containing your coffee binary. Usually + /usr/local/bin. + */ + "binDir": "/usr/local/bin", + + /* + Compile without the top-level function wrapper (coffee -b). + */ + + "noWrapper": true, + + /* + Enable or disable refresh the compiled Output on Save. + Only available for watch mode. + */ + "watchOnSave": true, + /* + Enable refreshing compiled JS when CoffeeScript is modified. + + Put false to disable + Put a number of seconds to delay the refresh + */ + "watchOnModified": 0.5, + /* + Enable Compiling on save. It will compile into the same folder. + */ + "compileOnSave": true, + /* + ## Enable outputting the results of the compiled coffeescript in a panel + */ + "showOutputOnSave": false, + /* + ## Enable compiling to a specific directory. + #### Description + + if it is a string like 'some/directory' then `-o some/directory` will be added to `coffee` compiler. + if it is false or not string then it will compile your `script.coffee` to the directory it is in. + + #### Example: + Directory is relative to the file you are editing if specified such as + compileDir": "out" + Directory is absolute if specified such as + compileDir": "/home/logan/Desktop/out" + + */ + "compileDir": false, + /* + ## Enable compiling to a specific relative directories. + + #### Example: + Set absolute path for compile dir: + "compileDir": "/home/user/projects/js" + And specified folders + "relativeDir": "/home/user/projects/coffee" + "compilePaths": + { + "/home/user/projects/coffee": "/home/user/projects/first/js", + "/home/user/projects/second/coffee": "../js", + } + + So + "/home/user/projects/coffee/app.coffee" will compile to "/home/user/projects/first/js/app.js" + "/home/user/projects/coffee/models/prod.coffee" will compile to "/home/user/projects/first/js/models/prod.js" + "/home/user/projects/coffee/second/coffee/app2.coffee" will compile to "/home/user/projects/second/js/app2.js" + "/home/user/projects/main.coffee" will compile to "/home/user/projects/js/main.js" + + */ + "compilePaths": false, } - - ``` ## Project settings Go to `Project > Edit Project` to change project settings. -```Javascript +```json { - "folders": - [ - ... - ], - "settings": - { - "CoffeeScript": - { - "noWrapper": true, - "compileOnSave": true, - "compileDir": "out" - } - } + "folders": [ + "." + ], + "settings": { + "CoffeeScript": { + "noWrapper": true, + "compileOnSave": true, + "compileDir": "out" + } + } } - - - ``` # FAQ @@ -297,19 +297,3 @@ This path will go into the `binDir` setting. - I'm getting the error message `'coffee' is not recognized as an internal or external command,` when saving. The coffee-script binary probably is not installed. Either install coffee-script or set `checkSyntaxOnSave` and `compileOnSave` to `false` in `Preferences > Package Settings > CoffeeScript > Settings - User`. - - - -# Latest Changelog -### v0.7.0 01/June/2013 - -- merged st3 with master branch -- now the sublime text 2 support is in st2 branch -- fixed the @ highlight in language definitions -- fixed an error you would get when it was looking for project settings when it wasn't a project we were editing - -# Special Thanks - - -Thanks to [everyone who has contributed to this project](https://github.com/SublimeText/BetterCoffeeScript/graphs/contributors). -You guys rock! diff --git a/Script Lang Values.sublime-completions b/Script Lang Values.sublime-completions new file mode 100644 index 0000000..74d885b --- /dev/null +++ b/Script Lang Values.sublime-completions @@ -0,0 +1,10 @@ +{ + "scope": "text.html.coffee meta.tag.script meta.attribute-with-value.lang", + "completions": [ + { + "trigger": "coffee", + "kind": ["type", "t", "Language Type"], + "details": "CoffeeScript" + } + ] +} \ No newline at end of file diff --git a/Script Type Values.sublime-completions b/Script Type Values.sublime-completions new file mode 100644 index 0000000..c5668f6 --- /dev/null +++ b/Script Type Values.sublime-completions @@ -0,0 +1,25 @@ +{ + "scope": "text.html.coffee meta.tag.script meta.attribute-with-value.type", + "completions": [ + { + "trigger": "application/coffee", + "kind": ["type", "t", "Mime Type"], + "details": "CoffeeScript" + }, + { + "trigger": "application/coffeescript", + "kind": ["type", "t", "Mime Type"], + "details": "CoffeeScript" + }, + { + "trigger": "text/coffee", + "kind": ["type", "t", "Mime Type"], + "details": "CoffeeScript" + }, + { + "trigger": "text/coffeescript", + "kind": ["type", "t", "Mime Type"], + "details": "CoffeeScript" + } + ] +} \ No newline at end of file diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..872f380 --- /dev/null +++ b/logo.svg @@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" fill="#ea7130" viewBox="0 0 16 16"> + <path d="M6.554,2.492A0.21,0.21,0,0,1,6.4,2.71a1.636,1.636,0,0,0-.817-0.122C5.264,2.614,5,2.723,5.035,2.955s0.357,0.367.906,0.313c1.34-.122,1.328-1.089,3.294-1.279,1.532-.15,2.387.354,2.5,0.966,0.089,0.476-.281.939-1.392,1.034-0.983.1-1.557-.191-1.609-0.476-0.026-.15.051-0.367,0.523-0.422a0.759,0.759,0,0,0,.957.408c0.46-.041.843-0.218,0.792-0.49s-0.536-.449-1.3-0.381C8.15,2.778,7.767,3.69,6.439,3.812A1.552,1.552,0,0,1,4.626,3c-0.038-.2-0.038-0.68.957-0.776a0.918,0.918,0,0,1,.97.272h0ZM1.575,8.181a2.947,2.947,0,0,0-.587,1.933,2.292,2.292,0,0,0,.83,1.633,1.913,1.913,0,0,0,1.685.422,5.5,5.5,0,0,0,.753-0.259,2.048,2.048,0,0,1-1.379-.544,2.232,2.232,0,0,1-.868-1.511,2.133,2.133,0,0,1,.306-1.606,1.965,1.965,0,0,1,1.379-.8,2.3,2.3,0,0,1,1.609.5,3.608,3.608,0,0,0-.434-0.463,1.957,1.957,0,0,0-1.736-.367A2.6,2.6,0,0,0,1.575,8.181h0ZM8.418,5.037a19.246,19.246,0,0,1-4.175-.422c-1.136-.3-1.736-0.626-1.736-1.048a0.615,0.615,0,0,1,.306-0.5c-0.715.3-1.1,0.544-1.1,0.925,0.038,0.422.677,0.844,1.979,1.17a18.6,18.6,0,0,0,4.685.5,18.384,18.384,0,0,0,4.685-.5c1.3-.327,1.928-0.762,1.928-1.17a1.051,1.051,0,0,0-.791-0.8,0.466,0.466,0,0,1,.2.367c0,0.422-.587.762-1.775,1.048a18.534,18.534,0,0,1-4.213.436h0Zm4.7,1.17a19.947,19.947,0,0,1-4.685.5,20.81,20.81,0,0,1-4.724-.5,3.228,3.228,0,0,1-1.889-.966,12.952,12.952,0,0,0,1.3,4.083c0.472,0.762.945,1.429,1.417,2.15a5.509,5.509,0,0,1,.434,1.266,2.285,2.285,0,0,0,1.3.925,5.019,5.019,0,0,0,2.094.327H8.443a5.6,5.6,0,0,0,2.157-.327,2.444,2.444,0,0,0,1.264-.925H11.9a5.364,5.364,0,0,1,.4-1.266c0.472-.721.945-1.388,1.417-2.15a13.756,13.756,0,0,0,1.3-4.083,3.13,3.13,0,0,1-1.9.966h0Z"/> +</svg> diff --git a/make.cmd b/make.cmd new file mode 100644 index 0000000..a54f14f --- /dev/null +++ b/make.cmd @@ -0,0 +1,32 @@ +@echo off +setlocal +chcp 65001 >nul +pushd %~dp0 + +if /i "%1" == "release" goto RELEASE +goto :usage + +:RELEASE + if "%2"== "" goto :usage + + for %%d in ("%~dp0.") do set package=%%~nxd + + echo Createing assets for "%package%"... + + set build=4143 + set archive=%package%.sublime-package + call git archive --format zip -o "%archive%" master + + :: create the release + gh release create --target master -t "v%2" "%build%-%2" *.sublime-package + del /f /q *.sublime-package + git fetch + goto :eof + +:USAGE + echo USAGE: + echo. + echo make ^[release^] + echo. + echo release ^<semver^> -- create and publish a release (e.g. 1.2.3) + goto :eof diff --git a/preview.coffee b/preview.coffee new file mode 100644 index 0000000..e769a17 --- /dev/null +++ b/preview.coffee @@ -0,0 +1,30 @@ +# Assignment: +number = 42 +opposite = true + +# Conditions: +number = -42 if opposite + +# Functions: +square = (x) -> x * x + +# Arrays: +list = [1, 2, 3, 4, 5] + +# Objects: +math = + root: Math.sqrt + square: square + cube: (x) -> x * square x + +# Splats: +race = (winner, runners...) -> + print winner, runners + +# Array comprehensions: +cubes = (math.cube num for num in list) + +# Existence: +alert "I knew it!" if elvis? + + diff --git a/preview.png b/preview.png new file mode 100644 index 0000000..6daec93 Binary files /dev/null and b/preview.png differ diff --git a/tests/syntax_test_scope.coffee b/tests/syntax_test_scope.coffee index a8a4d3f..afd7f55 100644 --- a/tests/syntax_test_scope.coffee +++ b/tests/syntax_test_scope.coffee @@ -43,21 +43,34 @@ export parentClass ###[ CLASSES ]################################################################ class extends parentClass -# <- meta.class.coffee storage.type.class.coffee -#^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.coffee -#^^^^ storage.type.class.coffee -# ^^^^^^^ keyword.control.inheritance.coffee +# <- meta.class.coffee keyword.declaration.class.coffee +#^^^^ meta.class.coffee +# ^ meta.class.identifier.coffee +# ^^^^^^^^^^^^^^^^^^^ meta.class.extends.coffee +#^^^^ keyword.declaration.class.coffee +# ^^^^^^^ storage.modifier.extends.coffee # ^^^^^^^^^^^ entity.other.inherited-class.coffee constructor: -> return class App.Router extends Snakeskin.Router -# <- meta.class.coffee storage.type.class.coffee -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.coffee -#^^^^ storage.type.class.coffee -# ^^^^^^^^^^ entity.name.type.class.coffee -# ^^^^^^^ keyword.control.inheritance.coffee -# ^^^^^^^^^^^^^^^^ entity.other.inherited-class.coffee +# <- meta.class.coffee keyword.declaration.class.coffee +#^^^^ meta.class.coffee +# ^^^^^^^^^^^^ meta.class.identifier.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.extends.coffee +#^^^^ keyword.declaration.class.coffee +# ^^^ support.class.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^^ entity.name.class.coffee +# ^^^^^^^ storage.modifier.extends.coffee +# ^^^^^^^^^ support.class.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^^ entity.other.inherited-class.coffee + +class +# <- meta.class.coffee keyword.declaration.class.coffee + constructor: -> +# ^ meta.function.identifier.coffee entity.name.function.coffee ###[ FUNCTIONS ]############################################################### @@ -65,64 +78,87 @@ class App.Router extends Snakeskin.Router # ^^^^^ - meta.function - entity.name.function name: -> +# ^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^^^ meta.function.coffee # ^ keyword.operator.assignment.coffee # ^^ keyword.declaration.function.coffee @name: -> -# ^^^^^ meta.function.identifier.coffee entity.name.function.coffee +# ^^^^^^^^^ - meta.function meta.function +# ^ variable.language.this.coffee +# ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^^^ meta.function.coffee # ^ keyword.operator.assignment.coffee # ^^ keyword.declaration.function.coffee namespace.name: -> -# ^^^^^^^^^^^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^^^^ meta.function.coffee -# ^ keyword.operator.assignment.coffee -# ^^ keyword.declaration.function.coffee - - name = => +# ^^^^^^^^^ meta.path.coffee variable.other.object.coffee +# ^ meta.path.coffee punctuation.accessor.dot.coffee +# ^^^^^^^^ - meta.function meta.function +# ^^^^ meta.function.identifier.coffee meta.path.coffee entity.name.function.coffee +# ^ meta.function.coffee keyword.operator.assignment.coffee +# ^ meta.function.coffee - keyword +# ^^ meta.function.coffee keyword.declaration.function.coffee +# ^ - meta.function + + name = -> +# ^^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^ meta.function.identifier.coffee - entity +# ^ meta.function.coffee - entity # ^^^^ meta.function.coffee # ^ keyword.operator.assignment.coffee # ^^ keyword.declaration.function.coffee - namespace.name = => -# ^^^^^^^^^^^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^ meta.function.identifier.coffee - entity -# ^^^^ meta.function.coffee -# ^ keyword.operator.assignment.coffee -# ^^ keyword.declaration.function.coffee + namespace.name = -> +# ^^^^^^^^^ meta.path.coffee variable.other.object.coffee +# ^ meta.path.coffee punctuation.accessor.dot.coffee +# ^^^^^^^^^ - meta.function meta.function +# ^^^^ meta.function.identifier.coffee meta.path.coffee entity.name.function.coffee +# ^ meta.function.coffee - keyword +# ^ meta.function.coffee keyword.operator.assignment.coffee +# ^ meta.function.coffee - keyword +# ^^ meta.function.coffee keyword.declaration.function.coffee +# ^ - meta.function name: => +# ^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^^^ meta.function.coffee # ^ keyword.operator.assignment.coffee # ^^ keyword.declaration.function.coffee namespace.name: => -# ^^^^^^^^^^^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^^^^ meta.function.coffee -# ^ keyword.operator.assignment.coffee -# ^^ keyword.declaration.function.coffee +# ^^^^^^^^^ meta.path.coffee variable.other.object.coffee +# ^ meta.path.coffee punctuation.accessor.dot.coffee +# ^^^^^^^^ - meta.function meta.function +# ^^^^ meta.function.identifier.coffee meta.path.coffee entity.name.function.coffee +# ^ meta.function.coffee keyword.operator.assignment.coffee +# ^ meta.function.coffee - keyword +# ^^ meta.function.coffee keyword.declaration.function.coffee +# ^ - meta.function name = => +# ^^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^ meta.function.identifier.coffee - entity +# ^ meta.function.coffee - entity # ^^^^ meta.function.coffee # ^ keyword.operator.assignment.coffee # ^^ keyword.declaration.function.coffee namespace.name = => -# ^^^^^^^^^^^^^^ meta.function.identifier.coffee entity.name.function.coffee -# ^ meta.function.identifier.coffee - entity -# ^^^^ meta.function.coffee -# ^ keyword.operator.assignment.coffee -# ^^ keyword.declaration.function.coffee +# ^^^^^^^^^ meta.path.coffee variable.other.object.coffee +# ^ meta.path.coffee punctuation.accessor.dot.coffee +# ^^^^^^^^^ - meta.function meta.function +# ^^^^ meta.function.identifier.coffee meta.path.coffee entity.name.function.coffee +# ^ meta.function.coffee - keyword +# ^ meta.function.coffee keyword.operator.assignment.coffee +# ^ meta.function.coffee - keyword +# ^^ meta.function.coffee keyword.declaration.function.coffee +# ^ - meta.function name: () -> +# ^^^^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^ meta.function.coffee # ^^ meta.function.parameters.coffee @@ -133,6 +169,7 @@ class App.Router extends Snakeskin.Router # ^^ keyword.declaration.function.coffee name: (foo, bar = undefined, baz="buuz", ...) -> +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.function meta.function # ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^ meta.function.coffee # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters.coffee @@ -153,6 +190,30 @@ class App.Router extends Snakeskin.Router # ^ punctuation.section.parameters.end.coffee # ^^ keyword.declaration.function.coffee + name: +# ^^^^ meta.function.identifier.coffee entity.name.function.coffee +# ^ meta.function.coffee keyword.operator.assignment.coffee + (foo, bar = undefined, +#^^^ meta.function.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters.coffee +# ^ punctuation.section.parameters.begin.coffee +# ^^^ variable.parameter.coffee +# ^ punctuation.separator.sequence.coffee +# ^^^ variable.parameter.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^^^^^ constant.language.coffee +# ^ punctuation.separator.sequence.coffee + baz="buuz", ...) -> +# ^^^^^^^^^^^^^^^^^^ meta.function.parameters.coffee +# ^^^ meta.function.coffee +# ^^^ variable.parameter.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^^ meta.string.coffee string.quoted.double.coffee +# ^ punctuation.separator.sequence.coffee +# ^^^ keyword.operator.variadic.coffee +# ^ punctuation.section.parameters.end.coffee +# ^^ keyword.declaration.function.coffee + name: ( # ^^^^ meta.function.identifier.coffee entity.name.function.coffee # ^^ meta.function.coffee @@ -192,54 +253,226 @@ class App.Router extends Snakeskin.Router # ^^ keyword.declaration.function.coffee (foo) -> -# ^^^^^ meta.function.parameters.coffee +# ^^^^^ meta.function.parameters.coffee - meta.function meta.function # ^^^ meta.function.coffee # ^ punctuation.section.parameters.begin.coffee # ^^^ variable.parameter.coffee # ^ punctuation.section.parameters.end.coffee # ^^ keyword.declaration.function.coffee -###[ KEYWORDS ]################################################################ + (foo, + bar="baz") -> +# ^^^^^^^^^^^^ meta.function.parameters.coffee - meta.function meta.function +# ^^^ meta.function.coffee - meta.function meta.function +# ^^^ variable.parameter.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^ meta.string.coffee string.quoted.double.coffee +# ^ punctuation.section.parameters.end.coffee +# ^^ keyword.declaration.function.coffee + + -> +# ^^ keyword.declaration.function.coffee + + (a : "group") +# ^^^^^^^^^^^^^ meta.group.coffee +# ^ punctuation.section.group.begin.coffee +# ^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^^^ meta.string.coffee string.quoted.double.coffee +# ^ punctuation.definition.string.begin.coffee +# ^ punctuation.definition.string.end.coffee +# ^ punctuation.section.group.end.coffee - if .if _if $if -# ^^ keyword.control.conditional.if.coffee -# ^^^^^^^^^^^^ - keyword + geometry = new Class(); +# ^^^^^^^^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee +# ^^^ keyword.operator.object.new.coffee +# ^^^^^ support.class.coffee - for .for _for $for + try = new Class(); +# ^^^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee +# ^^^ keyword.operator.object.new.coffee +# ^^^^^ support.class.coffee + + geometry: new Class(); +# ^^^^^^^^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee +# ^^^ keyword.operator.object.new.coffee +# ^^^^^ support.class.coffee +# ^ punctuation.section.group.begin.coffee +# ^ punctuation.section.group.end.coffee + + try: new Class("Unknown sort: #{info.type}"); +# ^^^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee +# ^^^ keyword.operator.object.new.coffee +# ^^^^^ support.class.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.coffee +# ^ punctuation.section.group.begin.coffee +# ^^^^^^^^^^^^^^^ meta.string.coffee string.quoted.double.coffee - meta.interpolation +# ^^^^^^^^^^^^ meta.string.coffee meta.embedded.coffee source.coffee.embedded.source +# ^ meta.string.coffee string.quoted.double.coffee - meta.interpolation +# ^ punctuation.section.group.end.coffee +# ^ punctuation.terminator.statement.coffee + +###[ LOOP STATEMENTS ]######################################################### + + for a, b in @links # ^^^ keyword.control.loop.for.coffee -# ^^^^^^^^^^^^^^^^ - keyword - - break .break _break $break -# ^^^^^ keyword.control.flow.coffee -# ^^^^^^^^^^^^^^^^^^^^^ - keyword - - continue .continue _continue $continue -# ^^^^^^^^ keyword.control.flow.coffee -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword +# ^ variable.other.readwrite.coffee +# ^ punctuation.separator.sequence.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.control.loop.in.coffee +# ^ variable.language.this.coffee +# ^^^^^ variable.other.member.coffee + + @links = ($(a) for a in @$links unless a in filtered) +# ^ variable.language.this.coffee +# ^^^^^ variable.other.member.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.coffee +# ^ punctuation.section.group.begin.coffee +# ^ meta.function-call.identifier.coffee variable.function.coffee +# ^^^ meta.function-call.arguments.coffee +# ^ punctuation.section.group.begin.coffee +# ^ variable.other.readwrite.coffee +# ^ punctuation.section.group.end.coffee +# ^^^ keyword.control.loop.for.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.control.loop.in.coffee +# ^ variable.language.this.coffee +# ^^^^^^ variable.other.member.coffee +# ^^^^^^ keyword.control.conditional.unless.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.operator.word.coffee keyword.operator.comparison.coffee +# ^^^^^^^^ variable.other.readwrite.coffee +# ^ punctuation.section.group.end.coffee + + for a, b of @links +# ^^^ keyword.control.loop.for.coffee +# ^ variable.other.readwrite.coffee +# ^ punctuation.separator.sequence.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.control.loop.of.coffee +# ^ variable.language.this.coffee +# ^^^^^ variable.other.member.coffee + + @links = ($(a) for a of @$links unless a of filtered) +# ^ variable.language.this.coffee +# ^^^^^ variable.other.member.coffee +# ^ keyword.operator.assignment.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.coffee +# ^ punctuation.section.group.begin.coffee +# ^ meta.function-call.identifier.coffee variable.function.coffee +# ^^^ meta.function-call.arguments.coffee +# ^ punctuation.section.group.begin.coffee +# ^ variable.other.readwrite.coffee +# ^ punctuation.section.group.end.coffee +# ^^^ keyword.control.loop.for.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.control.loop.of.coffee +# ^ variable.language.this.coffee +# ^^^^^^ variable.other.member.coffee +# ^^^^^^ keyword.control.conditional.unless.coffee +# ^ variable.other.readwrite.coffee +# ^^ keyword.operator.word.coffee keyword.operator.comparison.coffee +# ^^^^^^^^ variable.other.readwrite.coffee +# ^ punctuation.section.group.end.coffee - yield @foo -# ^^^^^ keyword.control.flow.coffee -# ^^^^ variable.other.readwrite.instance.coffee +###[ KEYWORDS ]################################################################ - yield from @foo -# ^^^^^^^^^^ keyword.control.flow.coffee -# ^^^^ variable.other.readwrite.instance.coffee + await .await _await await_ $await await$ +# ^^^^^ keyword.control.flow.await.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + break .break _break break_ $break break$ +# ^^^^^ keyword.control.flow.break.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + by .by _by $by +# ^^ keyword.control.loop.by.coffee +# ^^^^^^^^^^^^ - keyword + catch .catch _catch catch_ $catch catch$ +# ^^^^^ keyword.control.exception.catch.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + continue .continue _continue continue_ $continue continue$ +# ^^^^^^^^ keyword.control.flow.continue.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + debugger .debugger _debugger debugger_ $debugger debugger$ +# ^^^^^^^^ keyword.control.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + do .do _do $do +# ^^ keyword.control.flow.do.coffee +# ^^^^^^^^^^^^ - keyword + else .else _else else_ $else else$ +# ^^^^ keyword.control.conditional.else.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + finally .finally _finally finally_ $finally finally$ +# ^^^^^^^ keyword.control.exception.finally.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + for .for _for for_ $for for$ +# ^^^ keyword.control.loop.for.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + from .from _from from_ $from from$ +# ^^^^ keyword.control.import.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + if .if _if $if +# ^^ keyword.control.conditional.if.coffee +# ^^^^^^^^^^^^ - keyword + import .import _import import_ $import import$ +# ^^^^^^ keyword.control.import.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + loop .loop _loop loop_ $loop loop$ +# ^^^^ keyword.control.loop.loop.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + return .return _return return_ $return return$ +# ^^^^^^ keyword.control.flow.return.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + switch .switch _switch switch_ $switch switch$ +# ^^^^^^ keyword.control.conditional.switch.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + then .then _then then_ $then then$ +# ^^^^ keyword.control.conditional.then.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + throw .throw _throw throw_ $throw throw$ +# ^^^^^ keyword.control.flow.throw.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + try .try _try try_ $try try$ +# ^^^ keyword.control.exception.try.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + unless .unless _unless unless_ $unless unless$ +# ^^^^^^ keyword.control.conditional.unless.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + until .until _until until_ $until until$ +# ^^^^^ keyword.control.loop.until.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + when .when _when when_ $when when$ +# ^^^^ keyword.control.conditional.when.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + while .while _while while_ $while while$ +# ^^^^^ keyword.control.loop.while.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + yield .yield _yield yield_ $yield yield$ +# ^^^^^ keyword.control.flow.yield.coffee +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - keyword + yield from +# ^^^^^^^^^^ keyword.control.flow.yield.coffee ###[ OPERATORS ]############################################################### as # ^^ keyword.operator.assignment.as.coffee - in of -# ^^ keyword.operator.iterator.coffee -# ^^ keyword.operator.iterator.coffee + in is isnt is not of +# ^^ keyword.operator.comparison.coffee +# ^^ keyword.operator.comparison.coffee +# ^^^^ keyword.operator.comparison.coffee +# ^^^^^^ keyword.operator.comparison.coffee +# ^^ keyword.operator.comparison.coffee - and or is isnt not + and or not # ^^^ keyword.operator.logical.coffee # ^^ keyword.operator.logical.coffee -# ^^ keyword.operator.logical.coffee -# ^^^^ keyword.operator.logical.coffee -# ^^^ keyword.operator.logical.coffee +# ^^^ keyword.operator.logical.coffee new # ^^^ keyword.operator.object.new.coffee @@ -261,10 +494,10 @@ class App.Router extends Snakeskin.Router # ^^^^^^ keyword.operator.object.delete.coffee # ^^^ variable.other.readwrite.coffee - obj typeof Bar + obj = typeof obj # ^^^ variable.other.readwrite.coffee -# ^^^^^^ keyword.operator.comparison.type.coffee -# ^^^ support.class.coffee +# ^^^^^^ keyword.operator.object.typeof.coffee +# ^^^ variable.other.readwrite.coffee obj instanceof Bar # ^^^ variable.other.readwrite.coffee @@ -310,12 +543,15 @@ class App.Router extends Snakeskin.Router # ^ keyword.operator.bitwise.coffee # ^ keyword.operator.bitwise.coffee - + - * / % + + - * / % ** // %% # ^ keyword.operator.arithmetic.coffee # ^ keyword.operator.arithmetic.coffee # ^ keyword.operator.arithmetic.coffee # ^ keyword.operator.arithmetic.coffee # ^ keyword.operator.arithmetic.coffee +# ^^ keyword.operator.arithmetic.coffee +# ^^ keyword.operator.arithmetic.coffee +# ^^ keyword.operator.arithmetic.coffee = : # ^ keyword.operator.assignment.coffee @@ -327,7 +563,7 @@ class App.Router extends Snakeskin.Router ###[ BUILTIN FUNCTIONS ]####################################################### console.log() -# ^^^^^^^ variable.language.console.coffee +# ^^^^^^^ support.class.console.coffee # ^ punctuation.accessor.dot.coffee # ^^^ support.function.console.coffee # ^ punctuation.section.group.begin.coffee @@ -343,12 +579,90 @@ class App.Router extends Snakeskin.Router # ^ punctuation.section.group.begin.coffee # ^ punctuation.section.group.end.coffee +###[ USER FUNCTIONS ]########################################################## + + func() +# ^^^^ meta.function-call.identifier.coffee variable.function.coffee +# ^^ meta.function-call.arguments.coffee + + $func() +# ^^^^^ meta.function-call.identifier.coffee variable.function.coffee +# ^^ meta.function-call.arguments.coffee + + $('') +# ^ meta.function-call.identifier.coffee variable.function.coffee +# ^^^^ meta.function-call.arguments.coffee + + @name(@, obj.obj.) +# ^ variable.language.this.coffee +# ^^^^ meta.function-call.identifier.coffee variable.function.coffee +# ^^^^^^^^^^^^^ meta.function-call.arguments.coffee +# ^ punctuation.section.group.begin.coffee +# ^ variable.language.this.coffee +# ^ punctuation.separator.sequence.coffee +# ^^^^^^^^ meta.path.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^ punctuation.section.group.end.coffee + + @$('#notification') +# ^ variable.language.this.coffee +# ^ meta.function-call.identifier.coffee variable.function.coffee +# ^^^^^^^^^^^^^^^^^ meta.function-call.arguments.coffee +# ^ variable.function.coffee +# ^ punctuation.section.group.begin.coffee +# ^^^^^^^^^^^^^^^ meta.string.coffee string.quoted.single.coffee +# ^ punctuation.section.group.end.coffee + ###[ OBJECT MEMBERS ]########################################################## - this.key -# ^^^^ variable.language.coffee -# ^ meta.path.coffee punctuation.accessor.dot.coffee -# ^^^ meta.path.coffee variable.other.member.coffee + super.key +# ^^^^^^^^^ meta.path.coffee +# ^^^^^ variable.language.super.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^ variable.other.member.coffee +# ^ - meta + + this.member +# ^^^^^^^^^^^ meta.path.coffee +# ^^^^ variable.language.this.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^^ variable.other.member.coffee +# ^ - meta + + this.obj.member +# ^^^^^^^^^^^^^^^ meta.path.coffee +# ^^^^ variable.language.this.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^^ variable.other.member.coffee +# ^ - meta + + @member +# ^^^^^^^ meta.path.coffee +# ^ variable.language.this.coffee +# ^^^^^^ variable.other.member.coffee +# ^ - meta + + @obj.member +# ^^^^ meta.path.coffee +# ^ variable.language.this.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^^ variable.other.member.coffee +# ^ - meta + + @obj.obj. +# ^^^^^^^^^ meta.path.coffee +# ^ variable.language.this.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^ - meta obj.Object # ^^^^^^^^^^ meta.path.coffee @@ -385,11 +699,21 @@ class App.Router extends Snakeskin.Router # ^^^^^ meta.string.coffee string.quoted.double.coffee # ^ punctuation.section.group.end.coffee + class: 1 +# ^^^^^ variable.other.readwrite.coffee +# ^ keyword.operator.assignment.coffee + + obj.class: 1 +# ^^^^^^^^^ meta.path.coffee +# ^^^ variable.other.object.coffee +# ^ punctuation.accessor.dot.coffee +# ^^^^^ variable.other.member.coffee + ###[ LITERALS ]################################################################ Infinity NaN undefined .Infinity .NaN .undefined -# ^^^^^^^^ constant.language.coffee -# ^^^ constant.language.coffee +# ^^^^^^^^ constant.language.infinity.coffee +# ^^^ constant.language.nan.coffee # ^^^^^^^^^ constant.language.coffee # ^ punctuation.accessor.dot.coffee # ^^^^^^^^ variable.other.member.coffee @@ -444,12 +768,17 @@ class App.Router extends Snakeskin.Router 10.e5 # ^^^^^ meta.number.float.decimal.coffee constant.numeric.value.coffee +# ^ punctuation.separator.decimal.coffee - 10.23 + 10.23 .23 # ^^^^^ meta.number.float.decimal.coffee constant.numeric.value.coffee +# ^ punctuation.separator.decimal.coffee +# ^^^ meta.number.float.decimal.coffee constant.numeric.value.coffee +# ^ punctuation.separator.decimal.coffee 10.23e-5 # ^^^^^^^^ meta.number.float.decimal.coffee constant.numeric.value.coffee +# ^ punctuation.separator.decimal.coffee 52 # ^^ meta.number.integer.decimal.coffee constant.numeric.value.coffee @@ -488,6 +817,44 @@ class App.Router extends Snakeskin.Router # ^^^ meta.string.heredoc.coffee string.quoted.single.coffee punctuation.definition.string.end.coffee # ^ - meta.string - string + ``` +# ^^^ meta.string.heredoc.coffee string.quoted.script.coffee punctuation.definition.string.begin.coffee +# ^ meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee - string + + var i = `back ${tick} string`; +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee - source.jsx source.jsx +# ^^^ keyword.declaration +# ^^^^^^ meta.string string.quoted.other.js +# ^^^^^^^ meta.string meta.interpolation.js +# ^^^^^^^ meta.string string.quoted.other.js + return (<h1>Hello {World}</h1>) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee - source.jsx source.jsx +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.js meta.jsx.js +# ^^^^ meta.tag +# ^^^^^ meta.tag + ``` +# <- meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee - string +#^ meta.string.heredoc.coffee meta.embedded.coffee source.jsx.embedded.coffee - string +# ^^^ meta.string.heredoc.coffee string.quoted.script.coffee punctuation.definition.string.end.coffee +# ^ - meta.string - string + + ` +# ^ meta.string.coffee string.quoted.script.coffee punctuation.definition.string.begin.coffee +# ^ meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee - string + var i = 0; +# ^^^^^^^^^^^ meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee - source.jsx source.jsx +# ^^^ keyword.declaration + return (<h1>Hello {World}</h1>) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee - source.jsx source.jsx +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.js meta.jsx.js +# ^^^^ meta.tag +# ^^^^^ meta.tag + ` +# <- meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee - string +#^ meta.string.coffee meta.embedded.coffee source.jsx.embedded.coffee - string +# ^ meta.string.coffee string.quoted.script.coffee punctuation.definition.string.end.coffee +# ^ - meta.string - string + /// # <- - meta.string #^ - meta.string @@ -531,5 +898,53 @@ class App.Router extends Snakeskin.Router # ^ meta.number.integer.decimal.coffee constant.numeric.value.coffee @variable -# ^^^^^^^^^ variable.other.readwrite.instance.coffee -# ^ punctuation.definition.variable.coffee +# ^ variable.language.this.coffee +# ^^^^^^^^ variable.other.member.coffee + +###[ JSX ]##################################################################### + + <Component attrib="va{@lue}"> +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.jsx.coffee meta.tag.coffee +# ^ punctuation.definition.tag.begin.coffee +# ^^^^^^^^^ entity.name.tag.component.coffee +# ^^^^^^^^^^^^^^^^^ meta.attribute-with-value.coffee +# ^^^^^^ entity.other.attribute-name.coffee +# ^ punctuation.separator.key-value.coffee +# ^^^ meta.string.coffee string.quoted.double.coffee +# ^^^^^^ meta.string.coffee meta.interpolation.coffee +# ^ punctuation.section.interpolation.begin.coffee +# ^^^^ source.coffee.embedded.jsx +# ^ variable.language.this.coffee +# ^^^ variable.other.member.coffee +# ^ punctuation.section.interpolation.end.coffee +# ^ meta.string.coffee string.quoted.double.coffee punctuation.definition.string.end.coffee +# ^ punctuation.definition.tag.end.coffee + <h1>Text {# comment}!</h1> +# ^^^^ meta.jsx.coffee meta.tag.coffee +# ^ punctuation.definition.tag.begin.coffee +# ^^ entity.name.tag.coffee +# ^ punctuation.definition.tag.end.coffee +# ^^^^^ meta.jsx.coffee - meta.interpolation +# ^^^^^^^^^^^ meta.jsx.coffee meta.interpolation.coffee comment.block.coffee +# ^^ punctuation.definition.comment.begin.coffee +# ^ punctuation.definition.comment.end.coffee +# ^ meta.jsx.coffee - meta.interpolation +# ^^^^^ meta.jsx.coffee meta.tag.coffee +# ^^ punctuation.definition.tag.begin.coffee +# ^^ entity.name.tag.coffee +# ^ punctuation.definition.tag.end.coffee + </Component> +# ^^^^^^^^^^^^ meta.jsx.coffee meta.tag.coffee +# ^^ punctuation.definition.tag.begin.coffee +# ^^^^^^^^^ entity.name.tag.component.coffee +# ^ punctuation.definition.tag.end.coffee +# ^ - meta.jsx - meta.tag + + <EmailInput + {# THIS IS A GOOD COMMENT } +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.jsx.coffee meta.tag.coffee meta.attribute-with-value.coffee meta.interpolation.coffee comment.block.coffee + {...@props} +# ^^^^^^^^^^^ meta.jsx.coffee meta.tag.coffee meta.attribute-with-value.coffee meta.interpolation.coffee + /> +# ^^ meta.jsx.coffee meta.tag.coffee punctuation.definition.tag.end.coffee +# ^ - meta.jsx - meta.tag diff --git a/tests/syntax_test_scope.html b/tests/syntax_test_scope.html new file mode 100644 index 0000000..a6230a8 --- /dev/null +++ b/tests/syntax_test_scope.html @@ -0,0 +1,78 @@ +# SYNTAX TEST "HTML (CoffeeScript).sublime-syntax" + +<script type="text/coffeescript"> +# <- meta.tag.script.begin.html punctuation.definition.tag.begin.html +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.script.begin.html +#^^^^^^ entity.name.tag.script.html +# ^^^^ entity.other.attribute-name.html +# ^ punctuation.separator.key-value.html +# ^^^^^^^^^^^^^^^^^^^ meta.string.html string.quoted.double.html +# ^ punctuation.definition.tag.end.html + class extends parentClass + # <- source.coffee.embedded.html meta.class.coffee keyword.declaration.class.coffee + #^^^^^^^^^^^^^^^^^^^^^^^^ source.coffee.embedded.html meta.class + #^^^^ keyword.declaration.class.coffee + # ^^^^^^^ storage.modifier.extends.coffee + # ^^^^^^^^^^^ entity.other.inherited-class.coffee + constructor: -> + return + # <- source.coffee.embedded.html + # ^^^^^^ source.coffee.embedded.html keyword.control.flow.return.coffee +</script> +# <- meta.tag.script.end.html punctuation.definition.tag.begin.html +#^^^^^^^^ meta.tag.script.end.html +#^ punctuation.definition.tag.begin.html +# ^^^^^^ entity.name.tag.script.html +# ^ punctuation.definition.tag.end.html + +<script lang="coffee"> +# <- meta.tag.script.begin.html punctuation.definition.tag.begin.html +#^^^^^^^^^^^^^^^^^^^^^ meta.tag.script.begin.html +# ^^^^^^^^^^^^^ meta.attribute-with-value.lang.html +#^^^^^^ entity.name.tag.script.html +# ^^^^ entity.other.attribute-name.html +# ^ punctuation.separator.key-value.html +# ^^^^^^^^ meta.string.html string.quoted.double.html +# ^ punctuation.definition.tag.end.html + class extends parentClass + # <- source.coffee.embedded.html meta.class.coffee keyword.declaration.class.coffee + #^^^^^^^^^^^^^^^^^^^^^^^^ source.coffee.embedded.html meta.class + #^^^^ keyword.declaration.class.coffee + # ^^^^^^^ storage.modifier.extends.coffee + # ^^^^^^^^^^^ entity.other.inherited-class.coffee + constructor: -> + return + # <- source.coffee.embedded.html + # ^^^^^^ source.coffee.embedded.html keyword.control.flow.return.coffee +</script> +# <- meta.tag.script.end.html punctuation.definition.tag.begin.html +#^^^^^^^^ meta.tag.script.end.html +#^ punctuation.definition.tag.begin.html +# ^^^^^^ entity.name.tag.script.html +# ^ punctuation.definition.tag.end.html + +<script language="coffee"> +# <- meta.tag.script.begin.html punctuation.definition.tag.begin.html +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.script.begin.html +# ^^^^^^^^^^^^^^^^^ meta.attribute-with-value.lang.html +#^^^^^^ entity.name.tag.script.html +# ^^^^^^^^ entity.other.attribute-name.html +# ^ punctuation.separator.key-value.html +# ^^^^^^^^ meta.string.html string.quoted.double.html +# ^ punctuation.definition.tag.end.html + class extends parentClass + # <- source.coffee.embedded.html meta.class.coffee keyword.declaration.class.coffee + #^^^^^^^^^^^^^^^^^^^^^^^^ source.coffee.embedded.html meta.class + #^^^^ keyword.declaration.class.coffee + # ^^^^^^^ storage.modifier.extends.coffee + # ^^^^^^^^^^^ entity.other.inherited-class.coffee + constructor: -> + return + # <- source.coffee.embedded.html + # ^^^^^^ source.coffee.embedded.html keyword.control.flow.return.coffee +</script> +# <- meta.tag.script.end.html punctuation.definition.tag.begin.html +#^^^^^^^^ meta.tag.script.end.html +#^ punctuation.definition.tag.begin.html +# ^^^^^^ entity.name.tag.script.html +# ^ punctuation.definition.tag.end.html diff --git a/tests/syntax_test_scope.litcoffee b/tests/syntax_test_scope.litcoffee index 59dcdbc..8369361 100644 --- a/tests/syntax_test_scope.litcoffee +++ b/tests/syntax_test_scope.litcoffee @@ -1,32 +1,35 @@ | SYNTAX TEST "CoffeeScript Literate.sublime-syntax" # Heading -| <- meta.block-level.markdown markup.heading.markdown punctuation.definition.heading.markdown -|^^^^^^^^^ meta.block-level.markdown markup.heading.markdown +| <- markup.heading.1.markdown punctuation.definition.heading.begin.markdown +|^^^^^^^^^ text.html.markdown.litcoffee markup.heading.1.markdown # Indendet Code Block class App.Router extends Snakeskin.Router - | <- markup.raw.block.markdown meta.class.coffee storage.type.class.coffee - |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.raw.block.markdown meta.class.coffee - - @index: () => - | ^^^^^^ meta.function.identifier.coffee entity.name.function.coffee - | ^^ meta.function.coffee - | ^^ meta.function.parameters.coffee - | ^^^ meta.function.coffee - | ^^ keyword.declaration.function.coffee + | <- meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee keyword.declaration.class.coffee + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.embedded.litcoffee source.coffee.embedded.markdown meta.class + index: () => @ensureData((data) => @_parseDates(data, ['trending', 'new', 'top']) App.layout.renderExchange('index', data, ['index', 'search']) ) +- In list items + + class App.Router extends Snakeskin.Router + | <- markup.list.unnumbered.markdown meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee keyword.declaration.class.coffee + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.list.unnumbered.markdown meta.embedded.litcoffee source.coffee.embedded.markdown meta.class + index: () => + @ensureData((data) => + @_parseDates(data, ['trending', 'new', 'top']) + App.layout.renderExchange('index', data, ['index', 'search']) + ) + > Not in block quotes > > class App.Router extends Snakeskin.Router -|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block-level.markdown markup.quote.markdown - markdup.raw - -# https://github.com/SublimeText/CoffeeScript/issues/203 +| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.quote.markdown markup.raw.block.markdown - source.coffee This is a test showcasing that multiline string interpolation is broken. Copy this post into a .litcoffee file and open it in Sublime to see the breakage. @@ -56,3 +59,14 @@ into a .litcoffee file and open it in Sublime to see the breakage. ...even this markdown is as well. :( | <- meta.paragraph.markdown |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown + +```coffee +| <- text.html.markdown.litcoffee meta.code-fence.definition.begin.markdown-gfm punctuation.definition.raw.code-fence.begin.markdown +|^^^^^^^^ text.html.markdown.litcoffee meta.code-fence.definition.begin.markdown-gfm +|^^ punctuation.definition.raw.code-fence.begin.markdown +| ^^^^^^ constant.other.language-name.markdown + +| <- text.html.markdown.litcoffee markup.raw.code-fence source.coffee +``` +| <- text.html.markdown.litcoffee meta.code-fence.definition.end.markdown-gfm punctuation.definition.raw.code-fence.end.markdown +|^^ text.html.markdown.litcoffee meta.code-fence.definition.end.markdown-gfm punctuation.definition.raw.code-fence.end.markdown