Packages
Packages copied to clipboard
[JSX] Consider scoping the tag content in JSX/TSX
The content of tags in JSX/TSX is basically a string. It would be nice to give color schemes an option to visually color it as such:
// Source:
<div>
some text <-- basically a string
</div>
// Actual output (approximate):
createElement('div', {}, 'some text <-- basically a string')
For inertia reasons, we probably don't want to use string scope by default, as it might be too drastic a change. But having some option would be nice.
Incidentally, if we did this in JSX/TSX, it would be nice to do that in XML and HTML for consistency. In HTML, this might also include content outside any tags.
We shouldn't / won't push into contexts between xml or html tags for good reasons. Matching anything outside of html tags makes any kind of interpolation by templating languages impossible. So that won't happen, too.
Out of curiosity, what are those reasons for XML and HTML?
The main reason is those to be used as base for higher level syntaxes such as ASP/JSP/PHP/... Many of them especially 3rd-party syntaxes use something like
https://github.com/sublimehq/Packages/blob/4b66388fd5b206357769a9650c163f1a6958cea6/PHP/PHP.sublime-syntax#L18-L27
Push into HTML and inject additional patterns into each context to add highlighting for templating stuff such as <%php ...>. It works quite well because HTML has a flat and non-recursive context structure.
Most or even all issues related with exceeding sanity limits of 25.000 contexts per syntax file are related with pushing with_prototype into highly structured syntaxes. They arose especially when CSS and JS evolved to be such complex syntaxes while being added to core HTML syntax. with_prototype started to add its patterns to each context of CSS/JS and HTML while not being able to detect whether it did so for a certain context already or not. An easy way to trigger this issue is to include a parent context in one it pushes to.
Example:
- match: \(
push:
- match: \)
- include: main
Even if the context limit is not hit, it is very likely for such templating syntaxes's cache files (compiled regexp patterns and the syntax tree) to grow to several megabytes, while a normal / simple file such as HTML contains only few kilobytes. Se XML or plain HTML (without CSS/JS) which are only 8 or 11kb.
The embed command doesn't help here because it doesn't allow to inject prototypes. So PHP can't embed: HTML.sublime-syntax directly. Note that an embed is replaced by push with_prototype if its owning context is pushed ... with_prototype, which effectively removes all advantages the command offers.
What I've learned while working on (ASP and) JSP is that it is literly impossible to embed two highly structured syntaxes into each other. In JSP you need to inject JSP tags into HTML the embedded CSS and JavaScript. Those JSP tags contain Java code, which itself requires a lot of information about the context to be able to highlight tokens correctly. Example: A function call maker() can also be the constructor of a class syntactically. The same JavaScript does. Templating is as tricky as C MACROS are, because they may start/end everywhere. So you can't maintain correct contexts for both, Java and JavaScript if those are mixed together.
Same would happen if we'd start to turn XML/HTML into such highly structured syntaxes. I guess it even breaks many syntaxes and makes many issues with regards to templating impossible to solve for a static lexer.
That said, there is no need to scope the content between XML and HTML tags at all, because both are text. scopes. The content is just text.plain with some certain tokens in the middle being highlighted.
Thanks for explaining! 😅
At least we don't have this issue for JSX, since it parses tags by itself, and already handles interpolations in {}.