Implementing Edge language support, need help on how to wire things
Hello there,
I started working on an Edge template implementation for JetBrains IDE, but I need some help to ensure I'm getting things done right.
For context, Edge is a JS templating language inspired by Laravel Blade, mainly used by the Node.js AdonisJS framework.
Let's start with a really simple Edge file example:
<body>
@if(auth.user === undefined)
<h1>Hello, guest</h1>
@else
<h1>Hello, {{ auth.user }}</h1>
@end
</body>
As you can see, syntax is very similare to Laravel's Blade lang:
- @tag indicate a tags, which can take an expression inside
- {{ javascript expression }} tells Edge to print the evaluated javascript expression
My problem is that Edge is embedded in HTML, and that it can contains JavaScript expressions, which mean there is three layers in there:
HTML → Blade → JavaScript
And I have absolutely no idea how to use Intellij concepts (injector, lexer, parser) to get things done right.
I've read and turned the Custom Language Support tutorial in doc but it absolutely doesn't mention how to, for example, reuse HTML capabilities and reuse JavaScript capabilities already shipped in JetBrains IDE.
At this point, any idea is welcome.
Thanks a lot.
Xavier
Please sign in to leave a comment.
Hi Xavier!
I think it would be the best to have a look at Angular plugin - https://github.com/JetBrains/intellij-plugins/tree/master/AngularJS (you would be interested in the stuff in
org.angular2.
package). You can also check out Vue plugin https://github.com/JetBrains/intellij-plugins/tree/master/vuejs, Astro https://github.com/JetBrains/intellij-plugins/tree/master/Astro or Svelte https://github.com/tomblachut/svelte-intellijAll of the plugins have custom HTML template language with embedded JS (or TS) expression. I think this should be a good starting point. To be able to get syntax highlighting for the lexer files - please install Grammar-Kit plugin.
As far as I can see, first you need a lexer, which gets the tokenization right. Funny enough I will be implementing the new Angular Control Flow syntax within a week or two and it has similar kind of control directives, so you will be able to check it out afterwards.
If you look at Astro lexer it is a mix of HTML and JS and it does not output embedded tokens for any kind of language expression. On the other hand, Angular and Vue lexers only recognize where JS expression are supposed to be and they produce single token, which is later parsed by JavaScript parser. In case of a syntax you have shown I would go for the simpler approach with embedded tokens, like it is with Angular and Vue.
I hope that this short introduction and examples will help you somehow.
Best regards,
Piotr Tomiak
Hey Piotr!
Thanks a lot for your answers, I briefly looked the `org.angular2.` package during lunch time and I think I now kinda understand how it mix with HTML. Yet I'm still trying to figure out how everything work. The lexer for example looks insanely complex and noisy compared to what I suppose I need for Edge.
I'll keep digging and eventually learn from your implem of Angular Control Flow when it's done.
Regards,
Xavier
Okay, I also discussed with Tomasz Błachut on Twitter and he says something that unlocked my thinking process about what I want to achieve:
"First of you copy .flex from HTMLPlugin which is open source."
It may seem obvious afterward, but I didn't understand that I hadn't to reimplement the full HTML lexer.
Xavier Stouder Awesome. My change for the @ syntax have been pushed yesterday, so you can see what needs to be added to the lexer and parser to support it. Angular has also interpolations and something called expansion forms. That won't be needed in your case, but they complicate Angular lexer and parser a lot.