@@ -23,6 +23,8 @@ import {
23
23
CodeActionRequest ,
24
24
BulkUnregistration ,
25
25
HoverRequest ,
26
+ DidChangeWatchedFilesNotification ,
27
+ FileChangeType ,
26
28
} from 'vscode-languageserver/node'
27
29
import { TextDocument } from 'vscode-languageserver-textdocument'
28
30
import { URI } from 'vscode-uri'
@@ -32,7 +34,7 @@ import normalizePath from 'normalize-path'
32
34
import * as path from 'path'
33
35
import * as os from 'os'
34
36
import * as fs from 'fs'
35
- import chokidar from 'chokidar'
37
+ import chokidar , { FSWatcher } from 'chokidar'
36
38
import findUp from 'find-up'
37
39
import minimatch from 'minimatch'
38
40
import resolveFrom , { setPnpApi } from './util/resolveFrom'
@@ -206,47 +208,87 @@ async function createProjectService(
206
208
const documentSettingsCache : Map < string , Settings > = new Map ( )
207
209
let registrations : Promise < BulkUnregistration >
208
210
209
- const watcher = chokidar . watch (
210
- [ normalizePath ( `${ folder } /**/${ CONFIG_FILE_GLOB } ` ) , normalizePath ( `${ folder } /**/package.json` ) ] ,
211
- {
212
- ignorePermissionErrors : true ,
213
- ignoreInitial : true ,
214
- ignored : [ '**/node_modules/**' ] ,
215
- awaitWriteFinish : {
216
- stabilityThreshold : 100 ,
217
- pollInterval : 20 ,
218
- } ,
219
- }
220
- )
211
+ let watcher : FSWatcher
221
212
222
- await new Promise < void > ( ( resolve ) => {
223
- watcher . on ( 'ready' , ( ) => resolve ( ) )
224
- } )
213
+ function onFileEvents ( changes : Array < { file : string ; type : FileChangeType } > ) : void {
214
+ let needsInit = false
215
+ let needsRebuild = false
216
+
217
+ for ( let change of changes ) {
218
+ let file = normalizePath ( change . file )
219
+
220
+ if ( change . type === FileChangeType . Created ) {
221
+ needsInit = true
222
+ break
223
+ } else if ( change . type === FileChangeType . Changed ) {
224
+ if ( ! state . enabled || minimatch ( file , '**/package.json' ) ) {
225
+ needsInit = true
226
+ break
227
+ } else {
228
+ needsRebuild = true
229
+ }
230
+ } else if ( change . type === FileChangeType . Deleted ) {
231
+ if (
232
+ ! state . enabled ||
233
+ minimatch ( file , '**/package.json' ) ||
234
+ minimatch ( file , `**/${ CONFIG_FILE_GLOB } ` )
235
+ ) {
236
+ needsInit = true
237
+ break
238
+ } else {
239
+ needsRebuild = true
240
+ }
241
+ }
242
+ }
225
243
226
- watcher
227
- . on ( 'add' , ( ) => {
244
+ if ( needsInit ) {
228
245
tryInit ( )
246
+ } else if ( needsRebuild ) {
247
+ tryRebuild ( )
248
+ }
249
+ }
250
+
251
+ if ( params . capabilities . workspace ?. didChangeWatchedFiles ?. dynamicRegistration ) {
252
+ connection . onDidChangeWatchedFiles ( ( { changes } ) => {
253
+ onFileEvents (
254
+ changes . map ( ( { uri, type } ) => ( {
255
+ file : URI . parse ( uri ) . fsPath ,
256
+ type,
257
+ } ) )
258
+ )
229
259
} )
230
- . on ( 'unlink' , ( file ) => {
231
- if (
232
- ! state . enabled ||
233
- minimatch ( file , '**/package.json' ) ||
234
- minimatch ( file , `**/${ CONFIG_FILE_GLOB } ` )
235
- ) {
236
- tryInit ( )
237
- } else {
238
- tryRebuild ( )
239
- }
260
+
261
+ connection . client . register ( DidChangeWatchedFilesNotification . type , {
262
+ watchers : [ { globPattern : `**/${ CONFIG_FILE_GLOB } ` } , { globPattern : '**/package.json' } ] ,
240
263
} )
241
- . on ( 'change' , ( file ) => {
242
- if ( ! state . enabled || minimatch ( file , '**/package.json' ) ) {
243
- tryInit ( )
244
- } else {
245
- tryRebuild ( )
264
+ } else {
265
+ watcher = chokidar . watch (
266
+ [
267
+ normalizePath ( `${ folder } /**/${ CONFIG_FILE_GLOB } ` ) ,
268
+ normalizePath ( `${ folder } /**/package.json` ) ,
269
+ ] ,
270
+ {
271
+ ignorePermissionErrors : true ,
272
+ ignoreInitial : true ,
273
+ ignored : [ '**/node_modules/**' ] ,
274
+ awaitWriteFinish : {
275
+ stabilityThreshold : 100 ,
276
+ pollInterval : 20 ,
277
+ } ,
246
278
}
279
+ )
280
+
281
+ await new Promise < void > ( ( resolve ) => {
282
+ watcher . on ( 'ready' , ( ) => resolve ( ) )
247
283
} )
248
284
249
- function registerCapabilities ( ) : void {
285
+ watcher
286
+ . on ( 'add' , ( file ) => onFileEvents ( [ { file, type : FileChangeType . Created } ] ) )
287
+ . on ( 'change' , ( file ) => onFileEvents ( [ { file, type : FileChangeType . Changed } ] ) )
288
+ . on ( 'unlink' , ( file ) => onFileEvents ( [ { file, type : FileChangeType . Deleted } ] ) )
289
+ }
290
+
291
+ function registerCapabilities ( watchFiles ?: string [ ] ) : void {
250
292
if ( supportsDynamicRegistration ( connection , params ) ) {
251
293
if ( registrations ) {
252
294
registrations . then ( ( r ) => r . dispose ( ) )
@@ -268,6 +310,11 @@ async function createProjectService(
268
310
resolveProvider : true ,
269
311
triggerCharacters : [ ...TRIGGER_CHARACTERS , state . separator ] ,
270
312
} )
313
+ if ( watchFiles ) {
314
+ capabilities . add ( DidChangeWatchedFilesNotification . type , {
315
+ watchers : watchFiles . map ( ( file ) => ( { globPattern : file } ) ) ,
316
+ } )
317
+ }
271
318
272
319
registrations = connection . client . register ( capabilities )
273
320
}
@@ -766,10 +813,10 @@ async function createProjectService(
766
813
}
767
814
768
815
if ( state . dependencies ) {
769
- watcher . unwatch ( state . dependencies )
816
+ watcher ? .unwatch ( state . dependencies )
770
817
}
771
818
state . dependencies = getModuleDependencies ( state . configPath )
772
- watcher . add ( state . dependencies )
819
+ watcher ? .add ( state . dependencies )
773
820
774
821
state . configId = getConfigId ( state . configPath , state . dependencies )
775
822
@@ -784,7 +831,7 @@ async function createProjectService(
784
831
785
832
updateAllDiagnostics ( state )
786
833
787
- registerCapabilities ( )
834
+ registerCapabilities ( state . dependencies )
788
835
}
789
836
790
837
return {
@@ -796,7 +843,7 @@ async function createProjectService(
796
843
updateAllDiagnostics ( state )
797
844
}
798
845
if ( settings . editor . colorDecorators ) {
799
- registerCapabilities ( )
846
+ registerCapabilities ( state . dependencies )
800
847
} else {
801
848
connection . sendNotification ( '@/tailwindCSS/clearColors' )
802
849
}
0 commit comments