diff --git a/packages/tailwindcss-language-server/tests/completions/completions.test.js b/packages/tailwindcss-language-server/tests/completions/completions.test.js
index 024213cb..96f8188a 100644
--- a/packages/tailwindcss-language-server/tests/completions/completions.test.js
+++ b/packages/tailwindcss-language-server/tests/completions/completions.test.js
@@ -849,3 +849,61 @@ defineTest({
})
},
})
+
+defineTest({
+ name: 'v4: class function completions mixed with class attribute completions work',
+ fs: {
+ 'app.css': css`
+ @import 'tailwindcss';
+ `,
+ },
+ prepare: async ({ root }) => ({ client: await createClient({ root }) }),
+ handle: async ({ client }) => {
+ let document = await client.open({
+ settings: {
+ tailwindCSS: {
+ classAttributes: ['className'],
+ classFunctions: ['cn', 'cva'],
+ },
+ },
+ lang: 'javascriptreact',
+ text: js`
+ let x = cva("")
+
+ export function Button() {
+ return
+ }
+
+ export function Button2() {
+ return
+ }
+
+ let y = cva("")
+ `,
+ })
+
+ // let x = cva("");
+ // ^
+ let completionA = await document.completions({ line: 0, character: 13 })
+
+ expect(completionA?.items.length).toBe(12289)
+
+ // return ;
+ // ^
+ let completionB = await document.completions({ line: 3, character: 30 })
+
+ expect(completionB?.items.length).toBe(12289)
+
+ // return ;
+ // ^
+ let completionC = await document.completions({ line: 7, character: 30 })
+
+ expect(completionC?.items.length).toBe(12289)
+
+ // let y = cva("");
+ // ^
+ let completionD = await document.completions({ line: 10, character: 13 })
+
+ expect(completionD?.items.length).toBe(12289)
+ },
+})
diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts
index 978f118c..5c0c5552 100644
--- a/packages/tailwindcss-language-service/src/completionProvider.ts
+++ b/packages/tailwindcss-language-service/src/completionProvider.ts
@@ -703,8 +703,9 @@ async function provideClassAttributeCompletions(
position: Position,
context?: CompletionContext,
): Promise {
+ let current = document.offsetAt(position)
let range: Range = {
- start: document.positionAt(Math.max(0, document.offsetAt(position) - SEARCH_RANGE)),
+ start: document.positionAt(Math.max(0, current - SEARCH_RANGE)),
end: position,
}
@@ -734,13 +735,17 @@ async function provideClassAttributeCompletions(
let offset = document.offsetAt(boundary.range.start)
let fnMatches = matchClassFunctions(str, settings.classFunctions)
- fnMatches.forEach((match) => {
+ for (let match of fnMatches) {
if (match.index) match.index += offset
- })
+ if (match.index > current) continue
- matches.push(...fnMatches)
+ matches.push(match)
+ }
}
+ // Make sure matches are sorted by index
+ matches.sort((a, b) => a.index - b.index)
+
if (matches.length === 0) {
return null
}
diff --git a/packages/vscode-tailwindcss/CHANGELOG.md b/packages/vscode-tailwindcss/CHANGELOG.md
index 1e8a1970..9c949db3 100644
--- a/packages/vscode-tailwindcss/CHANGELOG.md
+++ b/packages/vscode-tailwindcss/CHANGELOG.md
@@ -2,7 +2,7 @@
## Prerelease
-- Nothing yet!
+- Fix completions not showing for some class attributes when a class function exists in the document ([#1278](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1278))
# 0.14.10