I want to customize the HTML mode so I can edit LIT-html template strings with it. I did add a rule to start
that matches ${
, switching the state to js-start
. This works when I add next: 'js-start'
to the rule. However, as the JavaScript code can include nested HTML (wrapped in lit.html`...`
), I would have to use push
instead of next
, but then the rule does not seem to work any more.
As a follow-up, as ${
can occur anywhere, I assume I will have to copy my new rule to any state defined for HTML, right? (i.e. all states on this.$highlightRules.$rules
that do not start with js-
or css-
).
Code Snippet:
const editor = ace.edit(wrap);
const HtmlMode = ace.require("ace/mode/html").Mode;
const CustomMode = function() {
HtmlMode.call(this);
const HtmlHighlightRules = ace.require("ace/mode/html_highlight_rules").HtmlHighlightRules;
this.$highlightRules = new HtmlHighlightRules();
this.$highlightRules.$rules.start.unshift({
token: "punctuation.definition.tag",
regex: /\${/,
// works
next: 'js-start',
// does not work
//push: 'js-start',
});
};
CustomMode.prototype = Object.create(HtmlMode.prototype);
CustomMode.prototype.constructor = CustomMode;
CustomMode.prototype.$id = "ace/mode/lit-html";
editor.getSession().setMode(new CustomMode());
As expected, something like <p class="something">${Math.random()}</p>
is correctly higlighted. But as soon as I use push
instead of next
, Math.random()
is not highlighted, i.e. ACE does not switch to js-start
.
You'll want to call
this.$highlightRules.normalizeRules()
after adding rules that push
/pop
- these are a shorthand for supplying functions that manipulate the state "stack".