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

searchRange is too small for cva #837

Closed
kachkaev opened this issue Aug 10, 2023 · 1 comment · Fixed by #840
Closed

searchRange is too small for cva #837

kachkaev opened this issue Aug 10, 2023 · 1 comment · Fixed by #840

Comments

@kachkaev
Copy link

kachkaev commented Aug 10, 2023

What version of VS Code are you using?

1.81.0

What version of Tailwind CSS IntelliSense are you using?

v0.9.11

What version of Tailwind CSS are you using?

v3.3.3

What package manager are you using?

pnpm

What operating system are you using?

macOS

Tailwind config

https://github.com/shadcn-ui/ui/blob/3c9f7ca0e20638bf75833ef920f9b23f5d97bc71/tailwind.config.cjs

VS Code settings

https://github.com/shadcn-ui/ui/blob/3c9f7ca0e20638bf75833ef920f9b23f5d97bc71/.vscode/settings.json

Reproduction URL

https://github.com/shadcn-ui/ui

Describe your issue

When working on a project inspired by chadcn-ui, I noticed that autocompletion was not always working inside a cva() function (class-variance-authority). As it turned out, it was to do with this bit of code in the extension:

const searchRange: Range = {
start: document.positionAt(Math.max(0, positionOffset - 1000)),
end: document.positionAt(positionOffset + 1000),
}

For class name autocompletion to work inside arbitrary chunks of code, the extension looks at the current location of the cursor and then scans the source file 1000 characters both ways. Within this range, it tries to match a regexp, e.g.:

{ // .vscode/settings.json
  "tailwindCSS.experimental.classRegex": [
    ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
    ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
  ]
}

This works in most cases, except when we use cva() with a few variants. Here is an example of that:

https://github.com/shadcn-ui/ui/blob/3c9f7ca0e20638bf75833ef920f9b23f5d97bc71/apps/www/registry/new-york/ui/button.tsx

In the file above, there are 1067 characters between cva( and ), which is greater than 1000. If I place a cursor somewhere in the middle of the function call, autocompletion works because both ends of the regexp are less than 1000 characters away:

Screenshot 2023-08-10 at 16 30 44

However, if I move the cursor so that it gets more than 1000 characters away from either end of cva( ), autocompletion stops working:

Screenshot 2023-08-10 at 16 30 52

It works again if I delete a few class names, thus placing both ends of the regex ‘within reach’:

Screenshot 2023-08-10 at 16 31 22

Thus, a hardcoded range of 1000 characters makes it impossible to configure autocompletion in cva when we have a few variants or compoundVariants to define.

I’d be great to configure this range, e.g.:

 { // .vscode/settings.json
+  "tailwindCSS.experimental.classRegexSearchRange": 5000,
   "tailwindCSS.experimental.classRegex": [
     ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]",], 
     ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
   ]
 }

I understand that large ranges may affect performance, so if there are other ways to fix the bug, it’d be great to discuss them! Perhaps, instead of matching for the whole regex end-to-end, the extension can first search for the prefix, then search for the suffix and finally get the ‘islands’ of strings with class names within it. Walking an AST might be something to explore too (this can help with complex cases like JS comments inside cva().


PS: Thanks for the extension folks, it makes Tailwind DX a bliss 🤩 This bug with cva is nothing compared with the overall experience 💯

@clementoriol
Copy link

I'm still seeing this issue in v0.10.3 in a long (~300 lines) object.

Could we make the searchRange configurable ?

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

Successfully merging a pull request may close this issue.

2 participants