From a35bfcb3de465de30ac2d2d871ffd626bde19062 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 20 Mar 2025 18:27:52 -0400 Subject: [PATCH 1/5] Refactor --- .../src/completionProvider.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 978f118c..e1c1e002 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,11 +735,11 @@ 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 - }) - matches.push(...fnMatches) + matches.push(match) + } } if (matches.length === 0) { From a43032f3320b77b3fef713ab5c23c201df2e7a00 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 20 Mar 2025 18:28:25 -0400 Subject: [PATCH 2/5] Make sure matches are sorted by position Since we have two separate data sources for matches they may end up out of order --- .../tailwindcss-language-service/src/completionProvider.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index e1c1e002..eaea9471 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -742,6 +742,9 @@ async function provideClassAttributeCompletions( } } + // Make sure matches are sorted by index + matches.sort((a, b) => a.index - b.index) + if (matches.length === 0) { return null } From a2b2b81870a78382d24715e424ebc0ddfc8f4ae4 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 20 Mar 2025 18:28:40 -0400 Subject: [PATCH 3/5] Discard function matches that appear after the current cursor --- packages/tailwindcss-language-service/src/completionProvider.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index eaea9471..5c0c5552 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -737,6 +737,7 @@ async function provideClassAttributeCompletions( for (let match of fnMatches) { if (match.index) match.index += offset + if (match.index > current) continue matches.push(match) } From b48b691f1ca0342942b38ffddccb660770d40f73 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 20 Mar 2025 18:41:33 -0400 Subject: [PATCH 4/5] Add test --- .../tests/completions/completions.test.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) 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) + }, +}) From 155b6c02224a167b521c7b5796da6805b153fd48 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 20 Mar 2025 18:50:40 -0400 Subject: [PATCH 5/5] Update changelog --- packages/vscode-tailwindcss/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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