orzechowskid / tsx-mode.el

a batteries-included Emacs major mode for Typescript, Javascript, TSX, and JSX files
GNU General Public License v3.0
100 stars 11 forks source link

Interpolating Javascript Breaks CSS Syntax Highlighting #15

Open stevemolitor opened 2 years ago

stevemolitor commented 2 years ago

A interpolated JS string in CSS causes all subsequent CSS to be syntax highlighted as if it were Javascript:

Running describe-face tells me that display, flex-direction and height, are tree-sitter-hl-face:variable, which is correct for CSS.

However background-color and width are tree-sitter-hl-face:tag, which is not correct.

danieljamesross commented 2 years ago

I get a similar experience. I think tsx-mode needs a strategy to detect template literals a bit like this issue:

https://github.com/polymode/polymode/issues/297

This is my experience:

Screenshot 2022-04-26 at 10 37 47

orzechowskid commented 2 years ago

FWIW I think this is best solved by using a tree-sitter grammar which understands CSS-in-JS. I've forked the existing tree-sitter CSS grammar repo and have something which mostly works, but (a) there are still a few rough edges and (b) I'm not sure if a CSS grammar is the correct place for such enhancements or if it would be better to create an entirely new grammar which inherits from CSS (like the Typescript grammar does from Javascript).

danieljamesross commented 2 years ago

I think you're probably right regarding writing a new grammar. Perhaps it ought to inherit CSS, javascript and typescript? It would be nice to have completion suggestions within template literals that are js or ts.

orzechowskid commented 2 years ago

thanks to the existing tree-sitter TS grammar we already know if point is inside a string template substitution, and if so then we enable TS autocompletion instead of CSS even if we're inside a CSS-in-JS region:

image

( https://github.com/orzechowskid/tsx-mode.el/blob/master/tsx-mode.el#L523 )

so that bit already exists, if I understand your comment correctly. for the rest of it, I think what needs to happen is one of the following:

it seems like with the first option I'd have to play whack-a-mole with each new tagged-template string syntax that the community releases (I'd rather do that here in elisp :smile: ). but the second option should be enough to support all CSS-in-JS solutions which use tagged-template strings.

I've started deriving a CSS-in-JS grammar here if you're interested in following along (or helping out!).

orzechowskid commented 2 years ago

I'm happy with the current state of that CSS-in-JS grammar, and I've a new branch of tsx-mode (feature/css-in-js) which incorporates it and tells tree-sitter to use it. please add the straight.el recipe for that grammar repo to your init file:

(straight-use-package '(tree-sitter-css-in-js :type git :host github :repo "orzechowskid/tree-sitter-css-in-js"))

and update your recipe for tsx-mode to point to the above-mentioned branch, and let me know how it goes.

you can verify that everything is working by switching to the *tsx-mode css* hidden buffer and running (tree-sitter-debug-mode) in it. the resulting CST should contain some nice new js_interpolation nodes.

I've only tested the grammar on my Ubuntu machine so I'd be especially interested to hear from anyone who uses OSX or Windows, but all feedback is greatly appreciated.

this should also fix #11 .

orzechowskid commented 2 years ago

the next branch should contain the fix for this.