Ymacs: Twig/Django mode and other news
As I find myself writing code in Ymacs sometimes, I wrote a mode suitable for editing
Twig/Django templates. It can be enabled with M-x twig_html_mode (the dogfood init code will auto-enable it for buffers coming from web-mode
if the filename contains .twig
).
While working on this (in itself, of course) I fixed a bunch of other issues related to indentation and syntax highlighting. JS mode will now highlight class, method and function names, and given these changes, I'd like to start working on some imenu-like functionality. Although, to be honest, the current “parsing” system could best be described as “a mess that works”, even after the significant refactoring at the beginning of this year (2024). My efforts would probably be better spent adopting CodeMirror's excellent parser generator (Lezer). But oh well, for now stuff is good enough. 🥲
Here's a small demo with the new Twig mode on:
The example above accommodates 4 languages into a single buffer. You can type CSS in <style>
tags,
JavaScript in <script>
tags, and in normal HTML mode it'll also recognize and highlight Twig tags. But you
can also include Twig tags in random JavaScript expressions inside <script>
blocks, and they'll be handled
correctly too, as you can see above if you take a look at the <script>
block. This is horrible, I agree,
but people do that. In order to sustain this level of… should I say “inception”? 😂 — the tokenizers must give up some
performance; for instance, instead of reading a string at once as a single token, for each character it must yield
control back to some master tokenizer, which will figure out if there's some embedded mode that wants to take over.
I'm pretty sure that there are situations where it doesn't work properly (CSS mode, for instance, might be less
friendly to embedded Twig expressions).
Dumb as they are, the tokenizers will still maintain some state and make an idea about the structure of your program, such that paredit-like operations will work correctly. For example, if you focus the JS string containing embedded Twig expressions, it'll highlight the matching end quote. And this, of course, is essential for automatic indentation to work—which it does. Press C-x h C-M-\ and it'll reindent the whole code. I still didn't make up my mind about how operations like M-x mark_sexp or M-x transpose_sexps should work in complex modes like HTML or Twig. For now they operate on the region delimited by the highlighted start/end “parens”, but that's obviously wrong in general. I'll probably make them operate on the “outer” region, which the tokenizers already track. To be done!
That's it for today. Since I'm probably the only Ymacs user in the World, I don't bother making formal releases; the code is at Github, and there are building instructions on the main page. If you try it and encounter any problems, please drop me an email, or file an issue at Github.
I might write some more in the following days/weeks. Cheers! 😇