use lsp file events when available
parent
405f22f339
commit
20da2b3e67
|
@ -23,6 +23,8 @@ import {
|
||||||
CodeActionRequest,
|
CodeActionRequest,
|
||||||
BulkUnregistration,
|
BulkUnregistration,
|
||||||
HoverRequest,
|
HoverRequest,
|
||||||
|
DidChangeWatchedFilesNotification,
|
||||||
|
FileChangeType,
|
||||||
} from 'vscode-languageserver/node'
|
} from 'vscode-languageserver/node'
|
||||||
import { TextDocument } from 'vscode-languageserver-textdocument'
|
import { TextDocument } from 'vscode-languageserver-textdocument'
|
||||||
import { URI } from 'vscode-uri'
|
import { URI } from 'vscode-uri'
|
||||||
|
@ -32,7 +34,7 @@ import normalizePath from 'normalize-path'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import chokidar from 'chokidar'
|
import chokidar, { FSWatcher } from 'chokidar'
|
||||||
import findUp from 'find-up'
|
import findUp from 'find-up'
|
||||||
import minimatch from 'minimatch'
|
import minimatch from 'minimatch'
|
||||||
import resolveFrom, { setPnpApi } from './util/resolveFrom'
|
import resolveFrom, { setPnpApi } from './util/resolveFrom'
|
||||||
|
@ -206,8 +208,65 @@ async function createProjectService(
|
||||||
const documentSettingsCache: Map<string, Settings> = new Map()
|
const documentSettingsCache: Map<string, Settings> = new Map()
|
||||||
let registrations: Promise<BulkUnregistration>
|
let registrations: Promise<BulkUnregistration>
|
||||||
|
|
||||||
const watcher = chokidar.watch(
|
let watcher: FSWatcher
|
||||||
[normalizePath(`${folder}/**/${CONFIG_FILE_GLOB}`), normalizePath(`${folder}/**/package.json`)],
|
|
||||||
|
function onFileEvents(changes: Array<{ file: string; type: FileChangeType }>): void {
|
||||||
|
let needsInit = false
|
||||||
|
let needsRebuild = false
|
||||||
|
|
||||||
|
for (let change of changes) {
|
||||||
|
let file = normalizePath(change.file)
|
||||||
|
|
||||||
|
if (change.type === FileChangeType.Created) {
|
||||||
|
needsInit = true
|
||||||
|
break
|
||||||
|
} else if (change.type === FileChangeType.Changed) {
|
||||||
|
if (!state.enabled || minimatch(file, '**/package.json')) {
|
||||||
|
needsInit = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
needsRebuild = true
|
||||||
|
}
|
||||||
|
} else if (change.type === FileChangeType.Deleted) {
|
||||||
|
if (
|
||||||
|
!state.enabled ||
|
||||||
|
minimatch(file, '**/package.json') ||
|
||||||
|
minimatch(file, `**/${CONFIG_FILE_GLOB}`)
|
||||||
|
) {
|
||||||
|
needsInit = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
needsRebuild = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsInit) {
|
||||||
|
tryInit()
|
||||||
|
} else if (needsRebuild) {
|
||||||
|
tryRebuild()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.capabilities.workspace?.didChangeWatchedFiles?.dynamicRegistration) {
|
||||||
|
connection.onDidChangeWatchedFiles(({ changes }) => {
|
||||||
|
onFileEvents(
|
||||||
|
changes.map(({ uri, type }) => ({
|
||||||
|
file: URI.parse(uri).fsPath,
|
||||||
|
type,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
connection.client.register(DidChangeWatchedFilesNotification.type, {
|
||||||
|
watchers: [{ globPattern: `**/${CONFIG_FILE_GLOB}` }, { globPattern: '**/package.json' }],
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
watcher = chokidar.watch(
|
||||||
|
[
|
||||||
|
normalizePath(`${folder}/**/${CONFIG_FILE_GLOB}`),
|
||||||
|
normalizePath(`${folder}/**/package.json`),
|
||||||
|
],
|
||||||
{
|
{
|
||||||
ignorePermissionErrors: true,
|
ignorePermissionErrors: true,
|
||||||
ignoreInitial: true,
|
ignoreInitial: true,
|
||||||
|
@ -224,29 +283,12 @@ async function createProjectService(
|
||||||
})
|
})
|
||||||
|
|
||||||
watcher
|
watcher
|
||||||
.on('add', () => {
|
.on('add', (file) => onFileEvents([{ file, type: FileChangeType.Created }]))
|
||||||
tryInit()
|
.on('change', (file) => onFileEvents([{ file, type: FileChangeType.Changed }]))
|
||||||
})
|
.on('unlink', (file) => onFileEvents([{ file, type: FileChangeType.Deleted }]))
|
||||||
.on('unlink', (file) => {
|
|
||||||
if (
|
|
||||||
!state.enabled ||
|
|
||||||
minimatch(file, '**/package.json') ||
|
|
||||||
minimatch(file, `**/${CONFIG_FILE_GLOB}`)
|
|
||||||
) {
|
|
||||||
tryInit()
|
|
||||||
} else {
|
|
||||||
tryRebuild()
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.on('change', (file) => {
|
|
||||||
if (!state.enabled || minimatch(file, '**/package.json')) {
|
|
||||||
tryInit()
|
|
||||||
} else {
|
|
||||||
tryRebuild()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function registerCapabilities(): void {
|
function registerCapabilities(watchFiles?: string[]): void {
|
||||||
if (supportsDynamicRegistration(connection, params)) {
|
if (supportsDynamicRegistration(connection, params)) {
|
||||||
if (registrations) {
|
if (registrations) {
|
||||||
registrations.then((r) => r.dispose())
|
registrations.then((r) => r.dispose())
|
||||||
|
@ -268,6 +310,11 @@ async function createProjectService(
|
||||||
resolveProvider: true,
|
resolveProvider: true,
|
||||||
triggerCharacters: [...TRIGGER_CHARACTERS, state.separator],
|
triggerCharacters: [...TRIGGER_CHARACTERS, state.separator],
|
||||||
})
|
})
|
||||||
|
if (watchFiles) {
|
||||||
|
capabilities.add(DidChangeWatchedFilesNotification.type, {
|
||||||
|
watchers: watchFiles.map((file) => ({ globPattern: file })),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
registrations = connection.client.register(capabilities)
|
registrations = connection.client.register(capabilities)
|
||||||
}
|
}
|
||||||
|
@ -766,10 +813,10 @@ async function createProjectService(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.dependencies) {
|
if (state.dependencies) {
|
||||||
watcher.unwatch(state.dependencies)
|
watcher?.unwatch(state.dependencies)
|
||||||
}
|
}
|
||||||
state.dependencies = getModuleDependencies(state.configPath)
|
state.dependencies = getModuleDependencies(state.configPath)
|
||||||
watcher.add(state.dependencies)
|
watcher?.add(state.dependencies)
|
||||||
|
|
||||||
state.configId = getConfigId(state.configPath, state.dependencies)
|
state.configId = getConfigId(state.configPath, state.dependencies)
|
||||||
|
|
||||||
|
@ -784,7 +831,7 @@ async function createProjectService(
|
||||||
|
|
||||||
updateAllDiagnostics(state)
|
updateAllDiagnostics(state)
|
||||||
|
|
||||||
registerCapabilities()
|
registerCapabilities(state.dependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -796,7 +843,7 @@ async function createProjectService(
|
||||||
updateAllDiagnostics(state)
|
updateAllDiagnostics(state)
|
||||||
}
|
}
|
||||||
if (settings.editor.colorDecorators) {
|
if (settings.editor.colorDecorators) {
|
||||||
registerCapabilities()
|
registerCapabilities(state.dependencies)
|
||||||
} else {
|
} else {
|
||||||
connection.sendNotification('@/tailwindCSS/clearColors')
|
connection.sendNotification('@/tailwindCSS/clearColors')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue