Skip to content

Commit fdad2e9

Browse files
committed
Merge branch 'main' into junepil/main
2 parents 80f6a24 + d907701 commit fdad2e9

File tree

131 files changed

+5718
-1995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+5718
-1995
lines changed

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Run Tests
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
7+
jobs:
8+
tests:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
node: [18, 20, 22, 24]
13+
os: [ubuntu-latest, macos-latest, windows-latest]
14+
15+
runs-on: ${{ matrix.os }}
16+
name: Run Tests - Node v${{ matrix.node }} / ${{ matrix.os }}
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: pnpm/action-setup@v4
21+
- uses: actions/setup-node@v4
22+
with:
23+
cache: 'pnpm'
24+
node-version: ${{ matrix.node-version }}
25+
26+
- name: Install dependencies
27+
run: pnpm install
28+
29+
- name: Run tests
30+
run: |
31+
cd packages/tailwindcss-language-server &&
32+
pnpm run build &&
33+
pnpm run test

.vscode/launch.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
"request": "launch",
88
"name": "Launch Client",
99
"runtimeExecutable": "${execPath}",
10-
"args": ["--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-tailwindcss"],
10+
"args": [
11+
// enable this flag if you want to activate the extension only when you are debugging the extension
12+
// "--disable-extensions",
13+
"--disable-updates",
14+
"--disable-workspace-trust",
15+
"--skip-release-notes",
16+
"--skip-welcome",
17+
"--extensionDevelopmentPath=${workspaceRoot}/packages/vscode-tailwindcss"
18+
],
1119
"stopOnEntry": false,
1220
"sourceMaps": true,
1321
"outFiles": ["${workspaceRoot}/packages/vscode-tailwindcss/dist/**/*.js"],

.vscode/tasks.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
"panel": "dedicated",
2424
"reveal": "never"
2525
},
26+
"options": {
27+
"cwd": "${workspaceFolder}/packages/vscode-tailwindcss"
28+
},
2629
"problemMatcher": ["$tsc-watch"]
2730
}
2831
]

packages/tailwindcss-language-server/package.json

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tailwindcss/language-server",
3-
"version": "0.14.9",
3+
"version": "0.14.16",
44
"description": "Tailwind CSS Language Server",
55
"license": "MIT",
66
"repository": {
@@ -34,14 +34,23 @@
3434
"access": "public"
3535
},
3636
"devDependencies": {
37-
"@parcel/watcher": "2.0.3",
37+
"@parcel/watcher": "2.5.1",
38+
"@parcel/watcher-darwin-x64": "2.5.1",
39+
"@parcel/watcher-darwin-arm64": "2.5.1",
40+
"@parcel/watcher-win32-x64": "2.5.1",
41+
"@parcel/watcher-win32-arm64": "2.5.1",
42+
"@parcel/watcher-linux-x64-glibc": "2.5.1",
43+
"@parcel/watcher-linux-x64-musl": "2.5.1",
44+
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
45+
"@parcel/watcher-linux-arm64-musl": "2.5.1",
3846
"@tailwindcss/aspect-ratio": "0.4.2",
3947
"@tailwindcss/container-queries": "0.1.0",
4048
"@tailwindcss/forms": "0.5.3",
4149
"@tailwindcss/language-service": "workspace:*",
4250
"@tailwindcss/line-clamp": "0.4.2",
43-
"@tailwindcss/oxide": "^4.0.0-alpha.19",
51+
"@tailwindcss/oxide": "^4.1.0",
4452
"@tailwindcss/typography": "0.5.7",
53+
"@types/braces": "3.0.1",
4554
"@types/color-name": "^1.1.3",
4655
"@types/culori": "^2.1.0",
4756
"@types/debounce": "1.2.0",
@@ -66,7 +75,6 @@
6675
"dset": "3.1.4",
6776
"enhanced-resolve": "^5.16.1",
6877
"esbuild": "^0.25.0",
69-
"fast-glob": "3.2.4",
7078
"find-up": "5.0.0",
7179
"jiti": "^2.3.3",
7280
"klona": "2.0.4",
@@ -83,18 +91,19 @@
8391
"rimraf": "3.0.2",
8492
"stack-trace": "0.0.10",
8593
"tailwindcss": "3.4.17",
86-
"tailwindcss-v4": "npm:tailwindcss@4.0.6",
94+
"tailwindcss-v4": "npm:tailwindcss@4.1.1",
95+
"tinyglobby": "^0.2.12",
8796
"tsconfck": "^3.1.4",
8897
"tsconfig-paths": "^4.2.0",
8998
"typescript": "5.3.3",
9099
"vite-tsconfig-paths": "^4.3.1",
91-
"vitest": "^1.6.1",
92-
"vscode-css-languageservice": "6.2.9",
100+
"vitest": "^3.0.9",
101+
"vscode-css-languageservice": "6.3.3",
93102
"vscode-jsonrpc": "8.2.0",
94103
"vscode-languageclient": "8.1.0",
95104
"vscode-languageserver": "8.1.0",
96105
"vscode-languageserver-protocol": "^3.17.5",
97-
"vscode-languageserver-textdocument": "1.0.11",
106+
"vscode-languageserver-textdocument": "1.0.12",
98107
"vscode-uri": "3.0.2"
99108
},
100109
"engines": {

packages/tailwindcss-language-server/src/config.ts

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,16 @@
11
import merge from 'deepmerge'
22
import { isObject } from './utils'
3-
import type { Settings } from '@tailwindcss/language-service/src/util/state'
3+
import {
4+
getDefaultTailwindSettings,
5+
type Settings,
6+
} from '@tailwindcss/language-service/src/util/state'
47
import type { Connection } from 'vscode-languageserver'
58

69
export interface SettingsCache {
710
get(uri?: string): Promise<Settings>
811
clear(): void
912
}
1013

11-
function getDefaultSettings(): Settings {
12-
return {
13-
editor: { tabSize: 2 },
14-
tailwindCSS: {
15-
inspectPort: null,
16-
emmetCompletions: false,
17-
classAttributes: ['class', 'className', 'ngClass', 'class:list'],
18-
codeActions: true,
19-
hovers: true,
20-
suggestions: true,
21-
validate: true,
22-
colorDecorators: true,
23-
rootFontSize: 16,
24-
lint: {
25-
cssConflict: 'warning',
26-
invalidApply: 'error',
27-
invalidScreen: 'error',
28-
invalidVariant: 'error',
29-
invalidConfigPath: 'error',
30-
invalidTailwindDirective: 'error',
31-
invalidSourceDirective: 'error',
32-
recommendedVariantOrder: 'warning',
33-
},
34-
showPixelEquivalents: true,
35-
includeLanguages: {},
36-
files: { exclude: ['**/.git/**', '**/node_modules/**', '**/.hg/**', '**/.svn/**'] },
37-
experimental: {
38-
classRegex: [],
39-
configFile: null,
40-
},
41-
},
42-
}
43-
}
44-
4514
export function createSettingsCache(connection: Connection): SettingsCache {
4615
const cache: Map<string, Settings> = new Map()
4716

@@ -73,7 +42,7 @@ export function createSettingsCache(connection: Connection): SettingsCache {
7342
tailwindCSS = isObject(tailwindCSS) ? tailwindCSS : {}
7443

7544
return merge<Settings>(
76-
getDefaultSettings(),
45+
getDefaultTailwindSettings(),
7746
{ editor, tailwindCSS },
7847
{ arrayMerge: (_destinationArray, sourceArray, _options) => sourceArray },
7948
)

packages/tailwindcss-language-server/src/css/extract-source-directives.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import type { Plugin } from 'postcss'
2+
import type { SourcePattern } from '../project-locator'
23

3-
export function extractSourceDirectives(sources: string[]): Plugin {
4+
export function extractSourceDirectives(sources: SourcePattern[]): Plugin {
45
return {
56
postcssPlugin: 'extract-at-rules',
67
AtRule: {
78
source: ({ params }) => {
9+
let negated = /^not\s+/.test(params)
10+
11+
if (negated) params = params.slice(4).trimStart()
12+
813
if (params[0] !== '"' && params[0] !== "'") return
9-
sources.push(params.slice(1, -1))
14+
15+
sources.push({
16+
pattern: params.slice(1, -1),
17+
negated,
18+
})
1019
},
1120
},
1221
}

packages/tailwindcss-language-server/src/language/css-server.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
CompletionItemKind,
1414
Connection,
1515
} from 'vscode-languageserver/node'
16-
import { TextDocument } from 'vscode-languageserver-textdocument'
16+
import { Position, TextDocument } from 'vscode-languageserver-textdocument'
1717
import { Utils, URI } from 'vscode-uri'
1818
import { getLanguageModelCache } from './languageModelCache'
1919
import { Stylesheet } from 'vscode-css-languageservice'
@@ -121,6 +121,7 @@ export class CssServer {
121121
async function withDocumentAndSettings<T>(
122122
uri: string,
123123
callback: (result: {
124+
original: TextDocument
124125
document: TextDocument
125126
settings: LanguageSettings | undefined
126127
}) => T | Promise<T>,
@@ -130,13 +131,64 @@ export class CssServer {
130131
return null
131132
}
132133
return await callback({
134+
original: document,
133135
document: createVirtualCssDocument(document),
134136
settings: await getDocumentSettings(document),
135137
})
136138
}
137139

140+
function isInImportDirective(doc: TextDocument, pos: Position) {
141+
let text = doc.getText({
142+
start: { line: pos.line, character: 0 },
143+
end: pos,
144+
})
145+
146+
// Scan backwards to see if we're inside an `@import` directive
147+
let foundImport = false
148+
let foundDirective = false
149+
150+
for (let i = text.length - 1; i >= 0; i--) {
151+
let char = text[i]
152+
if (char === '\n') break
153+
154+
if (char === '(' && !foundDirective) {
155+
if (text.startsWith(' source(', i - 7)) {
156+
foundDirective = true
157+
}
158+
159+
//
160+
else if (text.startsWith(' theme(', i - 6)) {
161+
foundDirective = true
162+
}
163+
164+
//
165+
else if (text.startsWith(' prefix(', i - 7)) {
166+
foundDirective = true
167+
}
168+
}
169+
170+
//
171+
else if (char === '@' && !foundImport) {
172+
if (text.startsWith('@import ', i)) {
173+
foundImport = true
174+
}
175+
}
176+
}
177+
178+
return foundImport && foundDirective
179+
}
180+
138181
connection.onCompletion(async ({ textDocument, position }, _token) =>
139-
withDocumentAndSettings(textDocument.uri, async ({ document, settings }) => {
182+
withDocumentAndSettings(textDocument.uri, async ({ original, document, settings }) => {
183+
// If we're inside source(…), prefix(…), or theme(…), don't show
184+
// completions from the CSS language server
185+
if (isInImportDirective(original, position)) {
186+
return {
187+
isIncomplete: false,
188+
items: [],
189+
}
190+
}
191+
140192
let result = await cssLanguageService.doComplete2(
141193
document,
142194
position,

0 commit comments

Comments
 (0)