2

I'm working on an AngluarJS web app in Sublime Text 3, and I need to be able to type boolean expressions inside certain directives, like ng-show, ng-class to define conditions for some display properties. Sublime sees the boolean operators as invalid and highlights them in pink (invalid syntax).

Here's an example:

<div ng-hide="line.valid && $index == 0"> ... </div>

In this example, the && gets highlighted pink because it shouldn't be present in HTML in Sublime's logic. Same goes for ||.

Is there a way to edit the syntax highlighting file to keep invalid syntax highlighting on everything except boolean operators?

I've seen ways to change the color of the highlighting altogether, but I'd really like to just make Sublime realize that those operators are fine to use in HTML so I can still get that highlighting on other bad code.

ryanoshea
  • 2,479
  • 1
  • 16
  • 15

2 Answers2

2

The problem is that the syntax definition for HTML assumes that an "&" or "&&" is invalid (There is no problem for "||"), hence the pink highlighting. I tweaked it slightly to fix your problem. If you want to find out how, read the code below. Otherwise skip ahead.

Before, string.quoted.double.html included entities, which match as invalid "&&".

repository:
...
  entities:
    patterns:
    - captures:
        '1': {name: punctuation.definition.entity.html}
        '3': {name: punctuation.definition.entity.html}
      match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)
      name: constant.character.entity.html
    - {match: '&', name: invalid.illegal.bad-ampersand.html}
...
  string-double-quoted:
    begin: '"'
    beginCaptures:
      '0': {name: punctuation.definition.string.begin.html}
    end: '"'
    endCaptures:
      '0': {name: punctuation.definition.string.end.html}
    name: string.quoted.double.html
    patterns:
    - {include: '#embedded-code'}
    - {include: '#entities'}

To fix this, I just duplicated the entities entry with string_entries and removed the ampersand error

repository:
...
  entities:
    patterns:
    - captures:
        '1': {name: punctuation.definition.entity.html}
        '3': {name: punctuation.definition.entity.html}
      match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)
      name: constant.character.entity.html
    - {match: '&', name: invalid.illegal.bad-ampersand.html}
  entities_string:
    patterns:
    - captures:
        '1': {name: punctuation.definition.entity.html}
        '3': {name: punctuation.definition.entity.html}
      match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)
      name: constant.character.entity.html
...
  string-double-quoted:
    begin: '"'
    beginCaptures:
      '0': {name: punctuation.definition.string.begin.html}
    end: '"'
    endCaptures:
      '0': {name: punctuation.definition.string.end.html}
    name: string.quoted.double.html
    patterns:
    - {include: '#embedded-code'}
    - {include: '#entities_string'}

Here is a link to the HTML.sublime-package (it is a zip, but you can just rename the suffix to sublime-package). You will need to go to the default packages directory where ST3 is installed and replace the HTML.sublime-package with this new one.

Post a comment if the link expires.

Alec
  • 31,829
  • 7
  • 67
  • 114
  • Actually, you can just change the match regex for `invalid.illegal.bad-ampersand.html` from `"&"` to `"(?<!&)&(?!&)"` which only match single ampersands (see http://stackoverflow.com/a/3735908/3685851) – justinsg Jul 22 '16 at 21:12
0

This is a quick fix, but if anyone has a better solution, I'm all ears.

Go to Sublime Text > Preferences > Browse Packages. In HTML/HTML.tmLanguage, comment out the following block of code, like so (using HTML comments):

<!--
<dict>
  <key>match</key>
  <string>&amp;</string>
  <key>name</key>
  <string>invalid.illegal.bad-ampersand.html</string>
</dict>
-->

This will fix the problem, but be overwritten in future Sublime Text updates. To get around that, you can duplicate the HTML folder within the Packages folder, name it something like HTMLAmpersandFix, and then in your User Settings (Preferences > Settings - User), add this:

"ignored_packages":
[
  "HTML",
  "Vintage"
],

I am not thoroughly enamored with this solution, as I would hope there's a way to fix it within the AngularJS package and submit it there as a pull request. The fix above is good enough for me for now, but I'd love to find a better one.

Note: Credits go to Alec's answer for putting me on the right track (though I have no idea what file his code snippet refers to and can't get his download link to work), and to the following Stack Overflow question for answering the question of how to overwrite HTML.tmLanguage. How do I edit HTML.tmLanguage in sublime on mac osx

Community
  • 1
  • 1
fuzzy marmot
  • 373
  • 4
  • 10