Skip to content

Commit 78ee813

Browse files
Properly restart server when detecting new Tailwind CSS v4 configs (#1387)
In editors that use our language server directly (not our VSCode extension), if you start with a project with a CSS file that isn't a Tailwind CSS config then edit it we want the server to restart. Unfortunately this was hitting an error causing the restart to fail but because of how things are set up this error isn't easily catchable (but it did get logged thankfully). This fixes that error and turning a CSS file from a non-config into a proper Tailwind CSS v4 config should work and the server should react accordingly.
1 parent 3548037 commit 78ee813

File tree

4 files changed

+93
-1
lines changed

4 files changed

+93
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ export class TW {
11331133
this.commonRegistrations?.dispose()
11341134
this.commonRegistrations = undefined
11351135

1136-
this.lastTriggerCharacters.clear()
1136+
this.lastTriggerCharacters?.clear()
11371137
this.completionRegistration?.then((r) => r.dispose())
11381138
this.completionRegistration = undefined
11391139

packages/tailwindcss-language-server/tests/env/restart.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,79 @@ defineTest({
190190
expect(ids3).not.toContainEqual(expect.toBeOneOf(ids2))
191191
},
192192
})
193+
194+
defineTest({
195+
name: 'Creating a CSS config in an empty folder initalizes a project',
196+
fs: {
197+
'app.css': css`
198+
/* this file is not a Tailwind CSS config yet */
199+
`,
200+
},
201+
prepare: async ({ root }) => ({
202+
client: await createClient({ root, log: true }),
203+
}),
204+
handle: async ({ root, client }) => {
205+
let doc = await client.open({
206+
lang: 'html',
207+
text: '<div class="text-primary">',
208+
})
209+
210+
// <div class="text-primary">
211+
// ^
212+
let hover = await doc.hover({ line: 0, character: 13 })
213+
214+
expect(hover).toEqual(null)
215+
216+
// Create a CSS config file
217+
await fs.writeFile(
218+
`${root}/app.css`,
219+
css`
220+
@import 'tailwindcss';
221+
222+
@theme {
223+
--color-primary: #c0ffee;
224+
}
225+
`,
226+
)
227+
228+
// Create a CSS config file
229+
// Notify the server of the config change
230+
let didRestart = Promise.race([
231+
new Promise((resolve) => {
232+
client.conn.onNotification('@/tailwindCSS/serverRestarted', resolve)
233+
}),
234+
new Promise((_, reject) =>
235+
setTimeout(() => reject(new Error('Did not restart in time')), 5000),
236+
),
237+
])
238+
239+
await client.notifyChangedFiles({
240+
changed: [`${root}/app.css`],
241+
})
242+
243+
await didRestart
244+
245+
// TODO: Sending a shutdown request immediately after a restart
246+
// gets lost
247+
// await client.shutdown()
248+
249+
// <div class="text-primary">
250+
// ^
251+
hover = await doc.hover({ line: 0, character: 13 })
252+
253+
expect(hover).toEqual({
254+
contents: {
255+
language: 'css',
256+
value: dedent`
257+
.text-primary {
258+
color: var(--color-primary) /* #c0ffee */;
259+
}
260+
`,
261+
},
262+
range: {
263+
start: { line: 0, character: 12 },
264+
end: { line: 0, character: 24 },
265+
},
266+
})
267+
},
268+
})

packages/tailwindcss-language-server/tests/utils/client.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import {
1212
DocumentLinkRequest,
1313
DocumentSymbol,
1414
DocumentSymbolRequest,
15+
ExitNotification,
1516
FileChangeType,
1617
FileEvent,
1718
Hover,
1819
NotificationHandler,
1920
ProtocolConnection,
2021
PublishDiagnosticsParams,
2122
Registration,
23+
ShutdownRequest,
2224
SymbolInformation,
2325
UnregistrationRequest,
2426
WorkspaceFolder,
@@ -226,6 +228,11 @@ export interface Client extends ClientWorkspace {
226228
* Update the global settings for the server
227229
*/
228230
updateSettings(settings: DeepPartial<Settings>): Promise<void>
231+
232+
/**
233+
* Shutdown the server
234+
*/
235+
shutdown(): Promise<void>
229236
}
230237

231238
export interface ClientWorkspaceOptions {
@@ -567,6 +574,13 @@ export async function createClient(opts: ClientOptions): Promise<Client> {
567574
})
568575
}
569576

577+
let didExit = new Promise<void>((resolve) => conn.onNotification(ExitNotification.type, resolve))
578+
579+
async function shutdown() {
580+
await conn.sendRequest(ShutdownRequest.type)
581+
await didExit
582+
}
583+
570584
return {
571585
...clientWorkspaces[0],
572586
get serverCapabilities() {
@@ -576,6 +590,7 @@ export async function createClient(opts: ClientOptions): Promise<Client> {
576590
notifyChangedFiles,
577591
workspace,
578592
updateSettings,
593+
shutdown,
579594
}
580595
}
581596

packages/vscode-tailwindcss/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Prerelease
44

55
- Simplify completion details for border and outline utilities ([#1384](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1384))
6+
- Fix error initializing a new project when editing a CSS file ([#1387](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1387))
67

78
# 0.14.19
89

0 commit comments

Comments
 (0)