Skip to content

searchRange is too small for cva #837

Closed
@kachkaev

Description

@kachkaev

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 💯

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions