Gerwin
Gerwin

Reputation: 31

HTML syntax highlighting inside of template-strings in Sublime Text

In Sublime Text I would like my javascript files to have HTML syntax highlighting inside of template-strings. Until yesterday, I was using a custom syntax I found from this stack overflow which looked like this:

%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Javascript HTML
file_extensions:
  - element.js
  - tag.js
  - jsx
  - js
scope: source.js.tag
contexts:
  main:
    - match: ""
      push: Packages/JavaScript/JavaScript.sublime-syntax
      with_prototype:
      - match: '([a-zA-Z$_][\w$_]*)?(`)'
        push:
          - meta_content_scope: text.html.basic.embedded.js
          - include: 'scope:text.html.basic'
          - match: '`'
            pop: true
          - match: '\$\{'
            captures:
              0: punctuation.definition.template-expression.begin.js
            push:
              - meta_scope: meta.template.expression.js
              - include: 'scope:source.js'
              #- meta_content_scope: source.js.embedded.expression
              - match: '\}'
                scope: punctuation.definition.template-expression.end.js
                pop: true

I updated sublime last night and it threw an error saying "Apparent recursion within a with_prototype action: 25000 context sanity limit hit."

I now somewhat understand why this error throws and so started to look at the docs to write a new version that doesn't use with_prototype. I tried many things but I can never seem to get both JS highlighting and HTML within template-strings. It seems to only do one or the other.

After several attempts and my limited knowledge in this area I concluded that I should:

So this is the version of the syntax I've landed on but this still does not highlight html inside of template-strings and I'm not really sure where I'm going wrong.

%YAML 1.2
---
name: JavaScript HTML
file_extensions:
  - js
scope: source.js
version: 2
extends: Packages/JavaScript/JavaScript.sublime-syntax
contexts:
  main:
    - match: '(`)'
    - meta_append: true
      scope: punctuation.definition.string.begin.js
      push: template-literal

  template-literal:
    - meta_append: true
    - meta_scope: string.quoted.template.js
    - match: '`'
      scope: punctuation.definition.string.end.js
      pop: true
    
    - match: '(?=<)'
      embed: scope:text.html.basic
      embed_scope: text.html.basic
      escape: '(?=`)'

    - match: '\$\{'
      scope: punctuation.definition.template-expression.begin.js
      push:
        - meta_scope: meta.template.expression.js
        - include: Packages/JavaScript/JavaScript.sublime-syntax
        - match: '\}'
          scope: punctuation.definition.template-expression.end.js
          pop: true

Any thoughts or direction appreciated. I will keep playing and update if I get anywhere.

Update: After playing some more today I decided to check the source of the Javascript.sublime-syntax. I realised if I simply make a context with the right name literal-string-template-begin and add my instructions there I should be able to get it working and so it's pretty crude but this does what I want now with the caveat that ${} don't get proper highlighting yet.

%YAML 1.2
---
name: JavaScript HTML
file_extensions:
  - js
scope: source.js
version: 2
extends: Packages/JavaScript/JavaScript.sublime-syntax
contexts:
  literal-string-template-begin:
    - match: '`'
      embed: scope:text.html.basic
      embed_scope: text.html.basic
      escape: '`'
      pop: true

Upvotes: 0

Views: 72

Answers (0)

Related Questions