Thom1729 / Sublime-JS-Custom

Customizable JavaScript syntax highlighting for Sublime Text.
MIT License
137 stars 9 forks source link

Styled Components highlighting bug #142

Open felixcatto opened 1 year ago

felixcatto commented 1 year ago

Sublime Text build number

4150

Example Code

const myClass = css`
  display: block;
`;

JS Custom Preferences

{
  "configurations": {
    "TSX + CSS": {
      "scope": "source.tsx",
      "file_extensions": ["tsx"],
      "typescript": true,
      "jsx": true,
      "custom_templates": {
        "styled_components": true,
        "tags": {
          "css": "scope:source.css"
        }
      }
    }
  }
}

Configuration name

No response

Description

Currently with those config it works, but it applies original source.css scope inside template string. I.e. syntax only works inside css class. But in styled components there is no need to write css class. It should work on top level, without css selectors.

2023-07-01_08-43

2023-07-01_08-44

2023-07-01_08-46

2023-07-01_08-46_1

I tried to add more specific scope

"tags": {
  "css": "scope:source.css meta.property-list.css meta.block.css"
}

But this doesn't work, the result scope is text.plain :cry:

Thom1729 commented 1 year ago

I think you want to copy the Styled Components recipe from the docs. For the css tag, that configuration embeds scope:source.js.css, which will use the Styled Components syntax provided by JS Custom (and which is used internally by the custom_templates.styled_components configuration option). Please let me know if this does not do what you want.

N.B.: The compiled syntax definition takes the value e.g. scope:source.js.css and plugs it in as a set. That value should be something that Sublime recognizes as a reference to a context, which is a sort of state that the parser can be in. The form scope:<something> tells Sublime to find a syntax definition whose top-level scope is <something>, and then use that syntax's main context. It doesn't work to put arbitrary scopes like meta.property-list.css in there.

What you can do instead is refer to the specific context that has the behavior you want. For instance, you could have "css": "scope:source.js.css#property-list-body", which tells Sublime to find the syntax with the scope source.js.css and then use its property-list-body context. I don't generally recommend doing this because syntax maintainers may rename or reorganize the syntax's contexts in a way that breaks your reference. And I don't recommend doing it in this case because scope:source.js.css should work.

felixcatto commented 1 year ago

I tried scope:source.js.css before and tried it again with no success. It doesn't work at all neither on top lvl, nor in css selectors like .myClass { ... }. I am using Emotion CssInJs, it slightly different from StyledComponents library. Don't know is it affects on sublime somehow.

2023-07-02_06-23

2023-07-02_06-24

This one "css": "scope:source.css#property-list-body", also doesn't work, despite it inserts almost correct scope :cry:

2023-07-02_06-38

2023-07-02_06-38_1

Also i want to use not the pure CSS sublime syntax, but source.css.tailwind, because this one supports tailwind and css nested rules.

Maybe i should switch from Dev build 4150 to 4143. I remember i did't have such problems on it and source.css.tailwind was working ok

Thom1729 commented 1 year ago

I tried scope:source.js.css before and tried it again with no success. It doesn't work at all…

Can you be more specific? What doesn't work? Is it just that CSS completions aren't suggested? What source of CSS completions are you using?

Also i want to use not the pure CSS sublime syntax, but source.css.tailwind,

I assume that this is a third-party package? Can you link the package in question?

felixcatto commented 1 year ago

I tried scope:source.js.css before and tried it again with no success. It doesn't work at all…

Can you be more specific? What doesn't work? Is it just that CSS completions aren't suggested? What source of CSS completions are you using?

It never works at all for me. When i write scope:source.js.css i got no completions at all. You can check first and second screenshots in post above. The scope is - source.js.css, but there is no CSS completions.

But scope:source.css and scope:source.css.tailwind worked fine at previous version of SublimeText.

Also i want to use not the pure CSS sublime syntax, but source.css.tailwind,

I assume that this is a third-party package? Can you link the package in question?

https://github.com/SublimeText/TailwindCSS

felixcatto commented 1 year ago

UPD: it turns out that it also doesn't work in previous stable build 4143 :cry: Seems i understand why it worked before. There was a bug in TailwindCSS, and because of it scope:source.css.tailwind worked, but now it fixed and CSS completions doesn't work neither in 4143, nor in 4150.

Thom1729 commented 1 year ago

The Tailwind CSS package does not appear to provide completions. There is a separate package that does. I presume that you are not using that package and instead are using by default the completions provided by the core CSS package.

I read through the core CSS completion code and apparently by default it is active when the scope at the cursor is source.css - meta.selector.css. Since the Styled Components syntax uses the scope source.js.css (for historical reasons), the CSS completions will not be active. However, this is configurable. You can change this by creating a file in your User packages named CSS.sublime-settings with the following contents:

{
    "default_completions_selector": "source.css - meta.selector.css, source.js.css",
}

I tested this, using the example Emotion.js recipe from the docs, and the default CSS completions were active.

felixcatto commented 1 year ago

... However, this is configurable. You can change this by creating a file in your User packages named CSS.sublime-settings with the following contents:

{
    "default_completions_selector": "source.css - meta.selector.css, source.js.css",
}

I don't know what kind of magic this is, but it's works :smiling_face_with_three_hearts:

Not as smooth like original css completions - i.e. when in source.css i type dispay: flex|; and then press Enter, cursor moves on new line without ; symbol. But in source.js.css it moves to new line with ; symbol. But it's little inconvenience.

What is really cool - source.js.css supports nested symbol &, whereas original source.css doesn't support it. So now i don't need Tailwind CSS syntax and all works as it should. Big thanks :heart:

JGJP commented 1 year ago

@felixcatto your fix worked for me. My autocomplete didn't work at all in styled components. Maybe it's worth documenting this somewhere or renaming the issue to something that includes "autocomplete"? My setup is pretty standard

felixcatto commented 1 year ago

Definitely worth documenting. For example here https://github.com/Thom1729/Sublime-JS-Custom/blob/master/docs/recipes.md#emotionjs. I can make a pr, if needed, or Thom1729 can do it