Skip to content

Commit a46bfe3

Browse files
committed
Add support for @source inline(…) and @source not inline(…)
1 parent 0cbf86c commit a46bfe3

File tree

7 files changed

+124
-1
lines changed

7 files changed

+124
-1
lines changed

packages/tailwindcss-language-server/tests/completions/at-config.test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,32 @@ withFixture('v4/dependencies', (c) => {
368368
})
369369
})
370370

371+
test.concurrent('@source inline(…)', async ({ expect }) => {
372+
let result = await completion({
373+
text: '@source inline("',
374+
lang: 'css',
375+
position: {
376+
line: 0,
377+
character: 16,
378+
},
379+
})
380+
381+
expect(result).toEqual(null)
382+
})
383+
384+
test.concurrent('@source not inline(…)', async ({ expect }) => {
385+
let result = await completion({
386+
text: '@source not inline("',
387+
lang: 'css',
388+
position: {
389+
line: 0,
390+
character: 20,
391+
},
392+
})
393+
394+
expect(result).toEqual(null)
395+
})
396+
371397
test.concurrent('@import "…" source(…)', async ({ expect }) => {
372398
let result = await completion({
373399
text: '@import "tailwindcss" source("',

packages/tailwindcss-language-server/tests/document-links/document-links.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ withFixture('v4/basic', (c) => {
157157
],
158158
})
159159

160+
testDocumentLinks('@source inline(…)', {
161+
text: '@source inline("m-{1,2,3}");',
162+
lang: 'css',
163+
expected: [],
164+
})
165+
166+
testDocumentLinks('@source not inline(…)', {
167+
text: '@source not inline("m-{1,2,3}");',
168+
lang: 'css',
169+
expected: [],
170+
})
171+
160172
testDocumentLinks('Directories in source(…) show links', {
161173
text: `
162174
@import "tailwindcss" source("../../");

packages/tailwindcss-language-server/tests/hover/hover.test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,74 @@ withFixture('v4/basic', (c) => {
320320
},
321321
})
322322

323+
testHover('css @source inline glob expansion', {
324+
exact: true,
325+
lang: 'css',
326+
text: `@source inline("{hover:,active:,}m-{1,2,3}")`,
327+
position: { line: 0, character: 23 },
328+
expected: {
329+
contents: {
330+
kind: 'markdown',
331+
value: [
332+
'**Expansion**',
333+
'```plaintext',
334+
'- hover:m-1',
335+
'- hover:m-2',
336+
'- hover:m-3',
337+
'- active:m-1',
338+
'- active:m-2',
339+
'- active:m-3',
340+
'- m-1',
341+
'- m-2',
342+
'- m-3',
343+
'```',
344+
].join('\n'),
345+
},
346+
range: {
347+
start: { line: 0, character: 15 },
348+
end: { line: 0, character: 43 },
349+
},
350+
},
351+
expectedRange: {
352+
start: { line: 2, character: 9 },
353+
end: { line: 2, character: 15 },
354+
},
355+
})
356+
357+
testHover('css @source not inline glob expansion', {
358+
exact: true,
359+
lang: 'css',
360+
text: `@source not inline("{hover:,active:,}m-{1,2,3}")`,
361+
position: { line: 0, character: 23 },
362+
expected: {
363+
contents: {
364+
kind: 'markdown',
365+
value: [
366+
'**Expansion**',
367+
'```plaintext',
368+
'- hover:m-1',
369+
'- hover:m-2',
370+
'- hover:m-3',
371+
'- active:m-1',
372+
'- active:m-2',
373+
'- active:m-3',
374+
'- m-1',
375+
'- m-2',
376+
'- m-3',
377+
'```',
378+
].join('\n'),
379+
},
380+
range: {
381+
start: { line: 0, character: 19 },
382+
end: { line: 0, character: 47 },
383+
},
384+
},
385+
expectedRange: {
386+
start: { line: 2, character: 9 },
387+
end: { line: 2, character: 18 },
388+
},
389+
})
390+
323391
testHover('--theme() works inside @media queries', {
324392
lang: 'tailwindcss',
325393
text: `@media (width>=--theme(--breakpoint-xl)) { .foo { color: red; } }`,

packages/tailwindcss-language-service/src/completions/file-paths.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,12 @@ test('Detecting v4 directives that point to files', async () => {
6161
suggest: 'directory',
6262
})
6363
})
64+
65+
test('@source inline is ignored', async () => {
66+
function find(text: string) {
67+
return findFileDirective({ enabled: true, v4: true }, text)
68+
}
69+
70+
await expect(find('@source inline("')).resolves.toEqual(null)
71+
await expect(find('@source not inline("')).resolves.toEqual(null)
72+
})

packages/tailwindcss-language-service/src/completions/file-paths.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { State } from '../util/state'
22

33
// @config, @plugin, @source
4+
// - @source inline("…") is *not* a file directive
5+
// - @source not inline("…") is *not* a file directive
46
const PATTERN_CUSTOM_V4 =
57
/@(?<directive>config|plugin|source)(?<not>\s+not)?\s*(?<partial>'[^']*|"[^"]*)$/
68
const PATTERN_CUSTOM_V3 = /@(?<directive>config)\s*(?<partial>'[^']*|"[^"]*)$/

packages/tailwindcss-language-service/src/diagnostics/getInvalidSourceDiagnostics.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const PATTERN_UTIL_SOURCE =
1414

1515
// @source
1616
const PATTERN_AT_SOURCE =
17-
/(?:\s|^)@(?<directive>source)\s*(?<not>not)?\s*(?<source>'[^']*'?|"[^"]*"?|[a-z]*|\)|;)/dg
17+
/(?:\s|^)@(?<directive>source)\s*(?<not>not)?\s*(?<source>'[^']*'?|"[^"]*"?|[a-z]*(?:\([^)]+\))?|\)|;)/dg
1818

1919
const HAS_DRIVE_LETTER = /^[A-Z]:/
2020

@@ -135,6 +135,11 @@ export function getInvalidSourceDiagnostics(
135135
})
136136
}
137137

138+
// `@source inline(…)` is fine
139+
else if (directive === 'source' && source.startsWith('inline(')) {
140+
//
141+
}
142+
138143
// - `@import "tailwindcss" source(no)`
139144
// - `@tailwind utilities source('')`
140145
else if (directive === 'source' && source !== 'none' && !isQuoted) {

packages/tailwindcss-language-service/src/hoverProvider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ async function provideSourceGlobHover(
170170

171171
let patterns = [
172172
/@source(?:\s+not)?\s*(?<glob>'[^']+'|"[^"]+")/dg,
173+
/@source(?:\s+not)?\s*inline\((?<glob>'[^']+'|"[^"]+")/dg,
173174
]
174175

175176
let matches = patterns.flatMap((pattern) => findAll(pattern, text))

0 commit comments

Comments
 (0)