Hey, and thanks for the great work on CodeMirror and Lezer!
I’ve been extending the JavaScript parser to support nested grammars with template literals, e.g.
html`<span>hello</span>`
has HTML highlighting. I have been using parseMixed
to embed grammars, but am unable to nest grammars. For instance,
html`<span>hello ${"world"}</span>`
works fine, but
html`<span>hello ${html`<b>world`}</span>`
fails to highlight <b>world
.
I’m using overlays to re-highlight template parts in JavaScript. The full code is:
/* wrap: */ parseMixed((node, input) => {
if (node.type.id !== 38 /* TemplateString */) {
return null;
}
const tagNode = node.node.prevSibling;
if (tagNode === null || tagNode.type.id !== 11 /* VariableName */) {
return null;
}
const tag = input.read(tagNode.from, tagNode.to);
let parser: Parser;
if (tag === "css") {
parser = cssLanguage.parser;
} else if (tag === "html") {
parser = htmlLanguage.parser;
} else if (tag === "md") {
parser = markdownLanguage.parser;
} else {
return null;
}
const overlay: { from: number, to: number }[] = [];
let from = node.from;
for (let child = node.node.firstChild; child !== null; child = child!.nextSibling) {
overlay.push({ from, to: child.from });
from = child.to;
}
if (overlay.length === 0) {
return { parser };
}
overlay.push({ from, to: node.to });
return { parser, overlay };
})
Instead of using overlays, I thought about configuring
nested parsers to highlight specific ranges in my custom syntax, but am not sure how to achieve that.
Any idea on how I could achieve any of the above ideas?
Cheers,