Textmate grammar for template expressions
See original GitHub issueIs your feature request related to a problem? Please describe.
The language service extension now provides a Textmate grammar for the Angular template syntax (#483), and describes template expressions via a JavaScript grammar. However, template expressions are not JavaScript, and to have an accurate grammar long-term, it would be useful to define a grammar specifically for Angular template expressions.
Additional context
_Originally posted by @dannymcgee in https://github.com/angular/vscode-ng-language-service/issues/541#issuecomment-577494343_:
@ayazhafiz I’ve been thinking about the issue with embedded grammars getting stuck and the potential solution I mentioned earlier in this thread, and I made a really rough proof of concept that seems promising.
The basic idea is:
- We embed our own subset of the JavaScript grammar instead of the full JS grammar, limited to just the syntax that’s actually valid in Angular templates
- We have two versions of that grammar, one which recognizes single quotes as an end condition, and one that recognizes double quotes
- For each template binding, we inject the correct grammar depending on whether the value was bound with double or single quotes
The hard (or annoying) part of that equation is having to maintain two nearly identical grammars for the JavaScript subset. The solution I came up with was to generate the JSON files dynamically with TypeScript, where each grammar “repository” is defined in a separate file. Then you can just swap out the imports for the handful of repositories that actually need to be different between the two versions. The proof of concept for that is here: https://github.com/dannymcgee/vscode-grammar-from-ts-experiment
There are some other advantages to doing it this way, namely much better code organization and much more readable regex patterns since they can be written as regex literals and benefit from syntax highlighting. And the additional benefits of defining our own grammar for the scripting language is that we can add more accurate grammar scopes for things like pipes and the as local-val
syntax.
Do you think this is a reasonable solution? And if so, any guidance on how to split up my PRs for ease of review?
_Response; originally posted by @ayazhafiz in https://github.com/angular/vscode-ng-language-service/issues/541#issuecomment-577500730_
@dannymcgee thanks for taking the time to do this. I like your idea of a template syntax grammar; it’s definitely the “correct” way to do it.
I’m not sure that we need two separate grammars for single and double quotes. I guess the case where this matters is if someone uses single quotes inside an attribute itself demarcated by single quotes (and symmetrically for double quotes), though I wonder how common this pattern is – if it’s not very common or does not significantly impact the stability of the grammar, it may not be worth the cost of maintaining two disjoint grammars. I’m not opposed to compiling the grammar from TypeScript definitions if the way to move forward is with two grammars. What do you think?
For PRs, incremental features should work fine. Looking at your PoC, for example, there could be a PR for all numeric things, then one for all objects, etc. After everything gets merged we can swap out the call to the JS grammar to the template syntax grammar.
I will open another issue for this where can discuss further.
Issue Analytics
- State:
- Created 4 years ago
- Comments:27 (26 by maintainers)
@ayazhafiz I’m sorry for disappearing like this. Had a really hard rest of the week at work, end of a project, had to work in the weekend.
It’s going well. I will finish doing this by the end of the day.
I started working on porting my grammar to the format @dannymcgee introduced in #581.