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