Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for named template strings #2

Open
ispringle opened this issue Nov 6, 2024 · 6 comments
Open

Support for named template strings #2

ispringle opened this issue Nov 6, 2024 · 6 comments

Comments

@ispringle
Copy link

Some frameworks, like lit, use template strings to define HTML and CSS. For example:

const element = html`<div class="foo">This is my new custom element!</div>`

Wondering what it would take to add support for that to this mode. Neovim is using treesitter to pull this off, they do it with the following query:

(call_expression
  function: (identifier) @injection.language
  arguments: [
    (arguments
      (template_string) @injection.content)
    (template_string) @injection.content
  ])

I've tested this in the treesitter playground and it highlights the correct portion of the above JS example. I'm not sure how to turn that query into its own set of nested highlighting though or else I'd make a PR

@guillaumebrunerie
Copy link
Owner

Hey!
I'd love to have that as well (I use styled components in React a lot myself, and it would be great to have CSS syntax highlighting there), but I think that the last time I investigated it, my conclusion was that Emacs has no support whatsoever for injection queries.
I might be wrong, or it might have changed, maybe I'll try again to make it work.

@guillaumebrunerie
Copy link
Owner

I got something partially working, but then ran into some Emacs bugs (for instance this one), so I'll wait until Emacs 30 to try again.

@ispringle
Copy link
Author

ispringle commented Dec 12, 2024

@guillaumebrunerie is it in a branch? I have the latest version of emacs-30 running, I can test it for you.

I can't find the associated commits that Yuan made to fix this issue, if it's a TS issue that should eventually get backported (I think) to the TS package and than you could manually pull that into your version of emacs, assuming 28 or 29, and that should allow you to continue working with the latest version of TS.

EDIT: I see it's in master, I'll get my ultimate-js-mode updated and I can continue working on this if you want.

@guillaumebrunerie
Copy link
Owner

It's in the main branch, you should just need to uncomment the following lines to try it out

;; (treesit-parser-create 'css)
;; (setq-local treesit-range-settings
;; (treesit-range-rules
;; :embed 'css
;; :host ultimate-js--lang
;; '((call_expression
;; function: (identifier) @_tag
;; (:match "\\`css\\'" @_tag)
;; arguments: (template_string (string_fragment) @capture)))))
;; (setq-local treesit-language-at-point-function #'ultimate-js-mode--language-at-point)

For now it's very much a proof of concept, it's hard coded (in several places) to check for a css tag and has some very basic CSS highlighting queries (maybe it should use the ones bundled in Emacs instead, assuming the grammar didn't change too much).

The main issue I had with it was that even though adding a css template string correctly highlighted it, removing the css part didn't revert the highlight, so the highlight could easily get completely broken. I believe it was fixed by this commit: emacs-mirror/emacs@0834106, at least the description seems to match what I observed.

@guillaumebrunerie
Copy link
Owner

Actually, there are also three other lines that need to be uncommented:

;; (ultimate-js-mode--partial-queries-css)
and the two similar ones below.

I now quickly tried in Emacs 30, and I can confirm that the issue I mentioned above is fixed, but I noticed a few more issues as well, for instance I’m using CSS faces that are only available after loading the regular css-mode, and Emacs 30 complains about not finding some functions (not sure what this is about). Finally I would like embedded languages to have a slightly different background, otherwise it seems to me like it would be very confusing, but this will most likely require a completely different implementation using overlays or so.

Have you actually been using ultimate-js-mode? I have mostly designed it for myself without thinking anyone else would use it, so it’s very likely that some parts of it don’t really work well with a different setup.

@ispringle
Copy link
Author

Yes I have been using ultimate-js-mode for editing UX code because it's handling Lit better than anything else. I use the treesitter version for server-side stuff but for the UX I'm using ultimate-js-mode. I haven't tried your changes yet. I switched to guix last week to evaluate it and haven't figured out how to get emacs 30 installed yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants