diff --git a/packages/tailwindcss-language-server/src/lib/constants.ts b/packages/tailwindcss-language-server/src/lib/constants.ts deleted file mode 100644 index 7324327c59283b13931a342a761e3242e62b4c35..0000000000000000000000000000000000000000 --- a/packages/tailwindcss-language-server/src/lib/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const CONFIG_GLOB = '{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs}' -export const PACKAGE_LOCK_GLOB = '{package-lock.json,yarn.lock,pnpm-lock.yaml}' -export const CSS_GLOB = '*.{css,scss,sass,less,pcss}' diff --git a/packages/tailwindcss-language-server/src/lsp/diagnosticsProvider.ts b/packages/tailwindcss-language-server/src/lsp/diagnosticsProvider.ts index fe08b247f564cd57d80d9ece27c2481456e23eaf..e5f01a8998bd771b9bd02cd78332e2dda1033527 100644 --- a/packages/tailwindcss-language-server/src/lsp/diagnosticsProvider.ts +++ b/packages/tailwindcss-language-server/src/lsp/diagnosticsProvider.ts @@ -20,3 +20,15 @@ uri: document.uri, diagnostics: [], }) } + +export function clearAllDiagnostics(state: State): void { + state.editor?.documents.all().forEach((document) => { + clearDiagnostics(state, document) + }) +} + +export function updateAllDiagnostics(state: State): void { + state.editor?.documents.all().forEach((document) => { + provideDiagnostics(state, document) + }) +} diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts index 0b9b4f576833ca4784c611e280d7422d6253f4e8..008c221a7744fb579ca9a8887c75c87a9916755c 100644 --- a/packages/tailwindcss-language-server/src/server.ts +++ b/packages/tailwindcss-language-server/src/server.ts @@ -65,7 +65,11 @@ Settings, ClassNames, Variant, } from 'tailwindcss-language-service/src/util/state' -import { provideDiagnostics } from './lsp/diagnosticsProvider' +import { + provideDiagnostics, + updateAllDiagnostics, + clearAllDiagnostics, +} from './lsp/diagnosticsProvider' import { doCodeActions } from 'tailwindcss-language-service/src/codeActions/codeActionProvider' import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider' import { getDocumentLinks } from 'tailwindcss-language-service/src/documentLinksProvider' @@ -85,9 +89,6 @@ import { equal } from 'tailwindcss-language-service/src/util/array' import preflight from 'tailwindcss/lib/css/preflight.css' import merge from 'deepmerge' DocumentColorParams, - CompletionParams, -import { CONFIG_GLOB, CSS_GLOB, PACKAGE_LOCK_GLOB } from './lib/constants' - DocumentColorParams, createConnection, // @ts-ignore global.__preflight = preflight @@ -105,6 +106,8 @@ } ` )(require, __dirname) +const CONFIG_FILE_GLOB = '{tailwind,tailwind.config}.{js,cjs}' +const PACKAGE_GLOB = '{package-lock.json,yarn.lock,pnpm-lock.yaml}' const TRIGGER_CHARACTERS = [ // class attributes '"', @@ -180,14 +183,10 @@ } interface ProjectService { TextDocuments, - CompletionList, - enable: () => void - documentSelector: () => Array - TextDocuments, createConnection, tryInit: () => Promise TextDocuments, - ColorInformation, + InitializeResult, onUpdateSettings: (settings: any) => void onFileEvents: (changes: Array<{ file: string; type: FileChangeType }>) => void onHover(params: TextDocumentPositionParams): Promise @@ -195,8 +194,6 @@ onCompletion(params: CompletionParams): Promise onCompletionResolve(item: CompletionItem): Promise provideDiagnostics(document: TextDocument): void TextDocumentSyncKind, - Connection, - TextDocumentSyncKind, createConnection, onColorPresentation(params: ColorPresentationParams): Promise onCodeAction(params: CodeActionParams): Promise @@ -204,25 +201,8 @@ onDocumentLinks(params: DocumentLinkParams): DocumentLink[] } import './lib/env' -import { getModuleDependencies } from './util/getModuleDependencies' - folder: string - configPath?: string - documentSelector?: Array - ColorPresentationParams, CompletionParams, -} - -enum DocumentSelectorPriority { - USER_CONFIGURED = 0, import './lib/env' -import namedColors from 'color-name' - CSS_FILE = 0, - CONTENT_FILE = 1, - CSS_DIRECTORY = 2, - CONFIG_DIRECTORY = 3, - ROOT_DIRECTORY = 4, -} - CodeActionParams, CompletionList, function getMode(config: any): unknown { @@ -248,251 +228,172 @@ } } } -const documentSettingsCache: Map = new Map() - CodeAction, +import { DocumentColorParams, - if (documentSettingsCache.has(uri)) { + CompletionParams, import { - } +import { CONFIG_GLOB, CSS_GLOB, PACKAGE_LOCK_GLOB } from './lib/constants' import { -import './lib/env' + import { -import { +// @ts-ignore import { - CompletionItem, +global.__preflight = preflight - scopeUri: uri, + updateCapabilities: () => void import { + ColorInformation, CompletionParams, import { -import { + return global.__preflight - CompletionRequest, + try { Connection, - scopeUri: uri, - CompletionRequest, +import './lib/env' CompletionParams, - CompletionRequest, +import './lib/env' createConnection, - editor = isObject(editor) ? editor : {} - tailwindCSS = isObject(tailwindCSS) ? tailwindCSS : {} -import { import './lib/env' + 'tailwindcss/lib/jit/lib/setupTrackingContext' -import { import './lib/env' + CompletionParams, import './lib/env' + ColorInformation, -import { import './lib/env' + CompletionParams, import { -import { import './lib/env' - CompletionItem, + TextDocuments, DocumentColorRequest, - CompletionList, + TextDocuments, import { +import { TextDocuments, import { - TextDocumentSyncKind, + CompletionItem, -import { import './lib/env' - createConnection, + CompletionParams, import { - CodeActionParams, + CompletionList, -import { import './lib/env' - ColorInformation, + CompletionParams, import { - CompletionRequest, + CompletionParams, - BulkRegistration, import './lib/env' -import { + CompletionParams, BulkRegistration, -import { + TextDocuments, import { - CompletionItem, + Connection, -import { + TextDocuments, BulkUnregistration, -import { + TextDocuments, HoverRequest, - invalidVariant: 'error', + ]) -import { + TextDocuments, FileChangeType, -import { + TextDocuments, Disposable, -import { + + TextDocuments, TextDocumentIdentifier, -import { + TextDocuments, DocumentLinkRequest, -import { + TextDocuments, DocumentLinkParams, -import { + TextDocuments, DocumentLink, -import { + TextDocuments, } from 'vscode-languageserver/node' -import { + TextDocuments, import { TextDocument } from 'vscode-languageserver-textdocument' -import { + TextDocuments, import { URI } from 'vscode-uri' -import { + TextDocuments, import { formatError, showError, SilentError } from './util/error' - }, -import { + TextDocuments, import glob from 'fast-glob' -import { + TextDocuments, import normalizePath from 'normalize-path' -import { + TextDocuments, import * as path from 'path' -import { + TextDocuments, import * as os from 'os' import './lib/env' + CompletionParams, CompletionList, +import './lib/env' - BulkUnregistration, import './lib/env' -import { + CompletionParams, import type * as chokidar from 'chokidar' import './lib/env' -import { formatError, showError, SilentError } from './util/error' - -import { + CompletionParams, import findUp from 'find-up' -import { + TextDocuments, import minimatch from 'minimatch' -import { + TextDocuments, import resolveFrom, { setPnpApi } from './util/resolveFrom' -import { + TextDocuments, import { AtRule, Container, Node, Result } from 'postcss' import './lib/env' -import { + CompletionParams, import Module from 'module' -import { + TextDocuments, import Hook from './lib/hook' -import { +import { dset } from 'dset' CompletionList, - ColorInformation, -import { + TextDocuments, CompletionList, - createConnection, + ColorInformation, import './lib/env' -import { formatError, showError, SilentError } from './util/error' - -import { + CompletionParams, import dlv from 'dlv' - HoverRequest, import './lib/env' -import { CompletionParams, -import { -import { CompletionParams, - CompletionItem, - error: console.error, +import './lib/env' import './lib/env' - DocumentLinkRequest, -import { import { klona } from 'klona/full' import { -import { doHover } from 'tailwindcss-language-service/src/hoverProvider' import './lib/env' - DocumentLinkRequest, -import { CompletionParams, - createConnection, -import { CompletionParams, - DocumentColorParams, - } finally { - for (let key in fns) { - console[key] = fns[key] - } -import './lib/env' CompletionItem, import './lib/env' -import { formatError, showError, SilentError } from './util/error' - -function withFallback(getter: () => T, fallback: T): T { -import { CompletionParams, - createConnection, -import { CompletionParams, - DocumentColorParams, - } catch (e) { - DidChangeWatchedFilesNotification, CompletionList, + CompletionParams, import './lib/env' - DocumentLinkRequest, -} - + CompletionList, import { -} from 'tailwindcss-language-service/src/util/state' - let relative = path.relative(dir, file) - return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative) -import './lib/env' CompletionItem, - Connection, - -function changeAffectsFile(change: string, files: string[]): boolean { - for (let file of files) { - FileChangeType, import { + CompletionItem, createConnection, -import './lib/env' import './lib/env' + tailwindcss = require('tailwindcss') import './lib/env' - DocumentLinkRequest, - return false - InitializeResult, +import { klona } from 'klona/full' Connection, - - FileChangeType, CompletionItem, - FileChangeType, CompletionList, -import { createConnection, - CompletionParams, - let tmp: string - let dir = path.dirname(file) - let patterns: string[] = [file, dir] - while (true) { - dir = path.dirname((tmp = dir)) - Disposable, import './lib/env' - break + postcss = require('postcss') import './lib/env' -import { AtRule, Container, Node, Result } from 'postcss' -import { +import { klona } from 'klona/full' DocumentColorParams, - CompletionItem, - } } - return patterns -} - Disposable, +import './lib/env' CompletionParams, - projectConfig: ProjectConfig, - connection: Connection, - params: InitializeParams, - documentService: DocumentService, - updateCapabilities: () => void, - checkOpenDocuments: () => void, - refreshDiagnostics: () => void, - watchPatterns: (patterns: string[]) => void, - initialTailwindVersion: string - TextDocumentIdentifier, CompletionParams, -import { ColorInformation, - Connection, - const folder = projectConfig.folder - const disposables: Array> = [] - let documentSelector = projectConfig.documentSelector - - let state: State = { enabled: false, editor: { connection, folder, + globalSettings: await getConfiguration(), userLanguages: params.initializationOptions.userLanguages ? params.initializationOptions.userLanguages : {}, @@ -523,184 +429,227 @@ }, }, } -} from 'vscode-languageserver/node' + TextDocuments, Connection, - let deps = [] +import './lib/env' TextDocuments, -import './lib/env' + Settings, -} from 'vscode-languageserver/node' DocumentColorParams, + createConnection, CompletionItem, +import Hook from './lib/hook' CompletionItem, + CompletionList, ColorInformation, CompletionItem, - CompletionList, + CompletionParams, + CompletionItem, - CompletionList, + CompletionParams, import './lib/env' CompletionItem, - CompletionList, + CompletionParams, import { + + documentSelector: () => Array CompletionItem, + documentSelector: () => Array CompletionList, - CompletionItem, import './lib/env' + return option() CompletionItem, +import { URI } from 'vscode-uri' + } - function log(...args: string[]): void { + let isConfigFile = minimatch(file, `**/${CONFIG_FILE_GLOB}`, { dot: true }) -import { TextDocument } from 'vscode-languageserver-textdocument' +import './lib/env' CompletionParams, +import { provideDiagnostics } from './lsp/diagnosticsProvider' -import { TextDocument } from 'vscode-languageserver-textdocument' + TextDocuments, Connection, + createConnection, -import { TextDocument } from 'vscode-languageserver-textdocument' + DocumentColorParams, createConnection, import './lib/env' - DocumentLinkRequest, + log('Failed to load workspace modules.') CompletionItem, + createConnection, CompletionList, - DocumentColorParams, CompletionItem, -import * as semver from 'tailwindcss-language-service/src/util/semver' +import { getColor } from 'tailwindcss-language-service/src/util/color' CompletionItem, -import dlv from 'dlv' - DocumentColorParams, + createConnection, createConnection, CompletionItem, -import { dset } from 'dset' +import namedColors from 'color-name' CompletionItem, -import pkgUp from 'pkg-up' DocumentColorParams, - createConnection, CompletionItem, -import stackTrace from 'stack-trace' +import { getFileFsPath, normalizeFileNameToFsPath } from './util/uri' CompletionItem, -import extractClassNames from './lib/extractClassNames' +import { equal } from 'tailwindcss-language-service/src/util/array' CompletionItem, -import { klona } from 'klona/full' DocumentColorParams, - createConnection, CompletionItem, -import { doHover } from 'tailwindcss-language-service/src/hoverProvider' + CompletionItem, DocumentColorParams, - createConnection, + CompletionList, + CompletionItem, import { URI } from 'vscode-uri' - createConnection, CompletionItem, - CompletionParams, DocumentColorParams, - CompletionItem, CompletionParams, - ColorInformation, - CompletionItem, + TextDocuments, Connection, + ColorInformation, CompletionItem, - Connection, + DocumentColorParams, import './lib/env' CompletionItem, - Connection, + DocumentColorParams, import { CompletionItem, - Connection, + DocumentColorParams, CompletionItem, CompletionItem, - Connection, + DocumentColorParams, CompletionList, CompletionItem, - Connection, + CompletionItem, CompletionParams, - ), + } -import { formatError, showError, SilentError } from './util/error' + } + DocumentColorParams, createConnection, CompletionItem, - Connection, + DocumentColorParams, DocumentColorParams, CompletionItem, - Connection, + DocumentColorParams, ColorInformation, CompletionItem, - createConnection, + ColorInformation, CompletionItem, -import { provideDiagnostics } from './lsp/diagnosticsProvider' + 'require', + } -import glob from 'fast-glob' import './lib/env' + DocumentLinkRequest, - CompletionItem, + TextDocuments, createConnection, -import { -} from 'vscode-languageserver/node' +import './lib/env' CompletionParams, +import { getModuleDependencies } from './util/getModuleDependencies' - CompletionItem, + TextDocuments, createConnection, - CompletionItem, +import { + CompletionItem, } - DocumentColorParams, + TextDocuments, createConnection, CompletionItem, + TextDocuments, import * as parcel from './watcher/index.js' - CompletionItem, + TextDocuments, import { generateRules } from 'tailwindcss-language-service/src/util/jit' - CompletionItem, + TextDocuments, import { getColor } from 'tailwindcss-language-service/src/util/color' - CompletionItem, + TextDocuments, import * as culori from 'culori' - CompletionItem, + } + + TextDocuments, import namedColors from 'color-name' CompletionItem, + CompletionList, + TextDocuments, import tailwindPlugins from './lib/plugins' - CompletionItem, + TextDocuments, import isExcluded from './util/isExcluded' +import { CompletionItem, + createConnection, + { + TextDocuments, import { getFileFsPath, normalizeFileNameToFsPath } from './util/uri' - CompletionItem, + TextDocuments, import { equal } from 'tailwindcss-language-service/src/util/array' - CompletionItem, + ), + ColorInformation, DocumentColorParams, - CompletionItem, CompletionItem, +import Module from 'module' DocumentColorParams, - CompletionList, + createConnection, + tryInit: () => Promise CompletionItem, - CompletionItem, +import './lib/env' CompletionParams, +import merge from 'deepmerge' - CompletionItem, + TextDocuments, import { getTextWithoutComments } from 'tailwindcss-language-service/src/util/doc' +import { CompletionItem, -import { CONFIG_GLOB, CSS_GLOB, PACKAGE_LOCK_GLOB } from './lib/constants' + createConnection, CompletionItem, + ColorInformation, DocumentColorParams, + ColorPresentation, createConnection, - CompletionItem, + TextDocuments, DocumentColorParams, + Connection, import './lib/env' + applyComplexClasses.default = (config, ...args) => { - CompletionItem, + cwd: folder, + TextDocuments, DocumentColorParams, + ColorInformation, + ignoreInitial: true, + ignored: ignore, + dispose: () => Promise import { + dispose: () => Promise CompletionItem, - DocumentColorParams, + pollInterval: 20, +import { CompletionItem, + createConnection, CompletionItem, + ColorInformation, DocumentColorParams, - CompletionList, + + await new Promise((resolve) => { + chokidarWatcher.on('ready', () => resolve()) CompletionItem, - CompletionItem, + } + +import './lib/env' CompletionParams, + return global.__preflight + TextDocuments, } import './lib/env' + text: '__ORIGINAL_SELECTOR__:' + rule.selector, + TextDocumentSyncKind, - CompletionItem, + TextDocuments, DocumentColorParams, + CompletionItem, + TextDocuments, DocumentColorParams, + CompletionList, - tryInit() + chokidarWatcher.close() +import { CompletionItem, -new Function( + createConnection, import * as path from 'path' -import './lib/env' - } + DocumentColorParams, } function resetState(): void { - // clearAllDiagnostics(state) + clearAllDiagnostics(state) Object.keys(state).forEach((key) => { // Keep `dependencies` to ensure that they are still watched if (key !== 'editor' && key !== 'dependencies') { @@ -706,14 +655,10 @@ } }) state.enabled = false import * as os from 'os' -import * as os from 'os' import './lib/env' } async function tryInit() { - if (!enabled) { - return - } try { await init() } catch (error) { @@ -723,9 +668,6 @@ } } async function tryRebuild() { - if (!enabled) { - return - } try { await rebuild() } catch (error) { @@ -734,25 +676,55 @@ showError(connection, error) } } - CompletionList, import './lib/env' + Connection, + CompletionItem, + onUpdateSettings: (settings: any) => void CompletionList, import './lib/env' + await fn(css) import './lib/env' + css.walkComments((comment) => { + ColorInformation, DocumentColorParams, + }) + onUpdateSettings: (settings: any) => void createConnection, + delete (Module as any)._pathCache[key] + }) + } + + async function init() { clearRequireCache() let configPath = projectConfig.configPath if (!configPath) { + configPath = ( + await glob([`**/${CONFIG_FILE_GLOB}`], { + cwd: folder, + ignore: state.editor.globalSettings.tailwindCSS.files.exclude, + onlyFiles: true, + onFileEvents: (changes: Array<{ file: string; type: FileChangeType }>) => void CompletionList, + TextDocumentSyncKind, TextDocuments, import './lib/env' + BulkRegistration, + concurrency: Math.max(os.cpus().length, 1), +import { AtRule, Container, Node, Result } from 'postcss' + CompletionParams, DocumentColorParams, + CompletionList, + onFileEvents: (changes: Array<{ file: string; type: FileChangeType }>) => void createConnection, - CompletionList, TextDocumentSyncKind, + CodeActionParams, + } + + if (!configPath) { + throw new SilentError('No config file found.') + } const pnpPath = findUp.sync( (dir) => { @@ -826,16 +797,18 @@ ) { return } -import Module from 'module' + TextDocumentSyncKind, import './lib/env' + ColorInformation, postcss = require(postcssPath) postcssSelectorParser = require(postcssSelectorParserPath) - log(`Loaded postcss v${postcssVersion}: ${postcssDir}`) + console.log(`Loaded postcss v${postcssVersion}: ${postcssDir}`) tailwindcss = require(tailwindcssPath) -import Module from 'module' +import './lib/env' Connection, + DocumentColorRequest, try { resolveConfigFn = require(resolveFrom(tailwindDir, './resolveConfig.js')) @@ -982,13 +955,13 @@ expandApplyAtRules: { module: require('tailwindcss/lib/lib/expandApplyAtRules').default, }, } - CompletionParams, +import './lib/env' Connection, - DocumentColorParams, + BulkRegistration, - CompletionParams, +import './lib/env' Connection, - ColorInformation, + CodeActionRequest, - log(`Using bundled version of \`postcss\`: v${postcssVersion}`) + console.log(`Using bundled version of \`postcss\`: v${postcssVersion}`) } state.configPath = configPath @@ -1076,8 +1049,6 @@ await tryRebuild() } async function rebuild() { - log('Building...') - clearRequireCache() const { tailwindcss, postcss, resolveConfig } = state.modules @@ -1173,22 +1144,6 @@ if (!originalConfig) { throw new SilentError(`Failed to load config file: ${state.configPath}`) } - ///////////////////// - if (!projectConfig.isUserConfigured) { - documentSelector = [ - ...documentSelector.filter( - ({ priority }) => priority !== DocumentSelectorPriority.CONTENT_FILE - ), - ...getContentDocumentSelectorFromConfigFile( - state.configPath, - tailwindcss.version, - projectConfig.folder, - originalConfig - ), - ] - } - ////////////////////// - try { state.config = resolveConfig.module(originalConfig) state.separator = state.config.separator @@ -1244,15 +1199,15 @@ hook.unhook() } } - // if (state.dependencies) { -import * as parcel from './watcher/index.js' + onHover(params: TextDocumentPositionParams): Promise CompletionParams, +import './lib/env' Connection, - CompletionItem, + DidChangeWatchedFilesNotification, + ColorPresentation, state.dependencies = getModuleDependencies(state.configPath) - // chokidarWatcher?.add(state.dependencies) + onHover(params: TextDocumentPositionParams): Promise createConnection, -import Hook from './lib/hook' state.configId = getConfigId(state.configPath, state.dependencies) @@ -1267,144 +1222,134 @@ state.screens = isObject(screens) ? Object.keys(screens) : [] state.enabled = true - // updateAllDiagnostics(state) - refreshDiagnostics() + updateAllDiagnostics(state) updateCapabilities() } return { createConnection, -} from 'tailwindcss-language-service/src/completionProvider' + ClassNames, import { getColor } from 'tailwindcss-language-service/src/util/color' + Connection, + TextDocumentSyncKind, import { + ColorInformation, + TextDocumentSyncKind, CompletionItem, - DocumentColorParams, - createConnection, +import './lib/env' Connection, + CompletionItem, import './lib/env' - enabled = true + } }, createConnection, +import { getModuleDependencies } from './util/getModuleDependencies' +import './lib/env' ClassNames, +import { - createConnection, +import './lib/env' Connection, +} from 'vscode-languageserver/node' + onCompletion(params: CompletionParams): Promise CompletionList, - createConnection, +import './lib/env' Connection, + CompletionItem, CompletionParams, -import { + TextDocumentSyncKind, CompletionItem, - DocumentColorParams, + Connection, -import { getColor } from 'tailwindcss-language-service/src/util/color' Connection, + resolveCompletionItem, - createConnection, +import './lib/env' Connection, + CompletionItem, createConnection, - createConnection, +import './lib/env' Connection, + CompletionItem, DocumentColorParams, - createConnection, + } +import './lib/env' Connection, + CompletionItem, ColorInformation, -import * as culori from 'culori' + onCompletionResolve(item: CompletionItem): Promise - ColorInformation, + CompletionItem, DocumentColorParams, -import { CompletionItem, - DocumentColorParams, -import * as culori from 'culori' + onCompletionResolve(item: CompletionItem): Promise import './lib/env' - if (state.enabled) { -import * as culori from 'culori' CompletionItem, - } - if (settings.editor.colorDecorators) { - updateCapabilities() - Connection, + CompletionItem, CompletionParams, - DocumentColorParams, - connection.sendNotification('@/tailwindCSS/clearColors') } }, onFileEvents, async onHover(params: TextDocumentPositionParams): Promise { - return withFallback(async () => { - createConnection, import isExcluded from './util/isExcluded' + CompletionParams, - createConnection, DocumentColorParams, -import './lib/env' + Connection, - createConnection, DocumentColorParams, -import { createConnection, -import preflight from 'tailwindcss/lib/css/preflight.css' -import namedColors from 'color-name' + TextDocumentSyncKind, CompletionList, +import { - if (await isExcluded(state, document)) return null + if (!settings.tailwindCSS.hovers) return null -import namedColors from 'color-name' +import './lib/env' Connection, +import minimatch from 'minimatch' - }, null) + return doHover(state, document, params.position) }, async onCompletion(params: CompletionParams): Promise { - return withFallback(async () => { + if (!state.enabled) return null - createConnection, import isExcluded from './util/isExcluded' + Connection, +import isExcluded from './util/isExcluded' createConnection, - DocumentColorParams, import './lib/env' + originalConfig = klona(exports) - if (!document) return null + if (!settings.tailwindCSS.suggestions) return null - let settings = await state.editor.getConfiguration(document.uri) + if (await isExcluded(state, document)) return null + onCompletionResolve(item: CompletionItem): Promise createConnection, -global.__preflight = preflight - createConnection, + onCompletionResolve(item: CompletionItem): Promise DocumentColorParams, - CompletionParams, -import tailwindPlugins from './lib/plugins' +import './lib/env' - if (!result) return result -import tailwindPlugins from './lib/plugins' import { - createConnection, ColorInformation, - CompletionItem, - createConnection, + onCompletionResolve(item: CompletionItem): Promise ColorInformation, - CompletionList, -import tailwindPlugins from './lib/plugins' + TextDocumentSyncKind, CompletionParams, -import tailwindPlugins from './lib/plugins' +import './lib/env' Connection, +import { dset } from 'dset' - })), + data: { projectKey: JSON.stringify(projectConfig), originalData: item.data }, -} from 'vscode-languageserver/node' + TextDocumentSyncKind, CompletionParams, + CompletionItem, - createConnection, + ColorInformation, DocumentColorParams, - createConnection, }, onCompletionResolve(item: CompletionItem): Promise { - return withFallback(() => { - createConnection, import isExcluded from './util/isExcluded' - return resolveCompletionItem(state, { ...item, data: item.data?.originalData }) + CompletionParams, - }, null) + return resolveCompletionItem(state, { ...item, data: item.data?.originalData }) }, async onCodeAction(params: CodeActionParams): Promise { - return withFallback(async () => { - createConnection, import isExcluded from './util/isExcluded' + CompletionParams, - createConnection, DocumentColorParams, -import './lib/env' + Connection, - createConnection, DocumentColorParams, -import { createConnection, -import preflight from 'tailwindcss/lib/css/preflight.css' -import isExcluded from './util/isExcluded' + onCompletionResolve(item: CompletionItem): Promise import { - return doCodeActions(state, params) + if (!settings.tailwindCSS.codeActions) return null - }, null) + return doCodeActions(state, params) }, onDocumentLinks(params: DocumentLinkParams): DocumentLink[] { if (!state.enabled) return null @@ -1418,33 +1359,23 @@ if (!state.enabled) return provideDiagnostics(state, document) }, 500), import { getFileFsPath, normalizeFileNameToFsPath } from './util/uri' - CompletionList, - if (!state.enabled) return - provideDiagnostics(state, document) - }, + CompletionParams, - DocumentColorParams, import './lib/env' + Connection, CompletionParams, createConnection, -import tailwindPlugins from './lib/plugins' DocumentColorParams, -import './lib/env' Connection, - createConnection, DocumentColorParams, -import './lib/env' + CompletionRequest, - DocumentColorParams, import './lib/env' - createConnection, + if (typeof separator !== 'string') { -import namedColors from 'color-name' + TextDocumentSyncKind, CompletionParams, DocumentColorParams, - CodeActionParams, - }, null) }, async onColorPresentation(params: ColorPresentationParams): Promise { let document = documentService.getDocument(params.textDocument.uri) - if (!document) return [] let className = document.getText(params.range) let match = className.match( new RegExp(`-\\[(${colorNames.join('|')}|(?:(?:#|rgba?\\(|hsla?\\())[^\\]]+)\\]$`, 'i') @@ -1618,31 +1550,33 @@ for (let fn of fns) { let definition: string let container = root.clone() - let oldReadFileSync = require('fs').readFileSync +import './lib/env' Connection, - fn({ + CompletionParams, ColorInformation, -import Hook from './lib/hook' - separator: state.separator, - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void import './lib/env' - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void import { - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void CompletionItem, - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void CompletionList, - require('fs').readFileSync = function (filename, ...args) { + }, + provideDiagnosticsForce(document: TextDocument): void CompletionParams, - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void Connection, - require('fs').readFileSync = function (filename, ...args) { + provideDiagnosticsForce(document: TextDocument): void createConnection, - }, +import './lib/env' Connection, +import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider' + Hover, Connection, + DocumentColorParams, + let oldReadFileSync = require('fs').readFileSync -import './lib/env' if (!definition) { definition = returnValue @@ -1783,83 +1718,16 @@ // } } ColorPresentation, -import * as path from 'path' - let css = getTextWithoutComments(await fs.promises.readFile(cssFile, 'utf8'), 'css') - let match = css.match(/@config\s*(?'[^']+'|"[^"]+")/) - if (!match) { - return null - } - return path.resolve(path.dirname(cssFile), match.groups.config.slice(1, -1)) -} DocumentColorParams, - createConnection, -function getPackageRoot(cwd: string, rootDir: string) { import { - doComplete, ColorPresentation, -import { AtRule, Container, Node, Result } from 'postcss' -import * as fs from 'fs' DocumentColorParams, - let pkgJson = path.join(dir, 'package.json') - if (findUp.sync.exists(pkgJson)) { - return pkgJson - CompletionItem, CompletionItem, - CompletionParams, - if (dir === rootDir) { - return findUp.stop - } - }, - { cwd } - ) - return pkgJsonPath ? path.dirname(pkgJsonPath) : rootDir - } catch { - return rootDir - } -} - -function getContentDocumentSelectorFromConfigFile( - configPath: string, - tailwindVersion: string, - rootDir: string, - actualConfig?: any -): DocumentSelector[] { - let config = actualConfig ?? require(configPath) - let contentConfig: unknown = config.content?.files ?? config.content - let content = Array.isArray(contentConfig) ? contentConfig : [] - let relativeEnabled = semver.gte(tailwindVersion, '3.2.0') - ? config.future?.relativeContentPathsByDefault || config.content?.relative - : false - let contentBase: string - if (relativeEnabled) { - contentBase = path.dirname(configPath) - } else { - contentBase = getPackageRoot(path.dirname(configPath), rootDir) - } - return content - .filter((item): item is string => typeof item === 'string') - .map((item) => - item.startsWith('!') - ? `!${path.resolve(contentBase, item.slice(1))}` - : path.resolve(contentBase, item) - ) - .map((item) => ({ - pattern: normalizePath(item), - priority: DocumentSelectorPriority.CONTENT_FILE, - })) -} - -class TW { - private initialized = false - private lspHandlersAdded = false private workspaces: Map private projects: Map private documentService: DocumentService public initializeParams: InitializeParams private registrations: Promise - private disposables: Disposable[] = [] - private watchPatterns: (patterns: string[]) => void - private watched: string[] = [] constructor(private connection: Connection) { this.documentService = new DocumentService(this.connection) @@ -1870,719 +1738,284 @@ async init(): Promise { if (this.initialized) return - clearRequireCache() - this.initialized = true import './lib/env' - } - console.error('No workspace folders found, not initializing.') - return + plugin = plugin() import './lib/env' - DocumentColorParams, + Connection, createConnection, - Hover, -import { import './lib/env' - // class attributes - let ignore = globalSettings.tailwindCSS.files.exclude - let configFileOrFiles = globalSettings.tailwindCSS.experimental.configFile - - '.', Connection, - '.', createConnection, import './lib/env' - ' ', - -import './lib/env' import './lib/env' - ColorInformation, - CompletionList, Connection, + createConnection, import { import './lib/env' - '.', - (!isObject(configFileOrFiles) || - !Object.entries(configFileOrFiles).every(([key, value]) => { - if (typeof key !== 'string') return false - if (Array.isArray(value)) { - return value.every((item) => typeof item === 'string') Connection, + createConnection, CompletionItem, import './lib/env' - Hover, Connection, - // config/theme helper createConnection, CompletionList, -import { getDocumentLinks } from 'tailwindcss-language-service/src/documentLinksProvider' import './lib/env' -] as const - CompletionList, + Connection, createConnection, - } - + CompletionParams, // config/theme helper - ColorInformation, - typeof configFileOrFiles === 'string' ? { [configFileOrFiles]: '**' } : configFileOrFiles - DocumentColorParams, createConnection, import './lib/env' - process.argv.length <= 2 ? createConnection(process.stdin, process.stdout) : createConnection() - ([relativeConfigPath, relativeDocumentSelectorOrSelectors]) => { - return { - folder: base, - configPath: path.resolve(base, relativeConfigPath), - documentSelector: [].concat(relativeDocumentSelectorOrSelectors).map((selector) => ({ - '(', Connection, - '(', createConnection, - })), - isUserConfigured: true, - } - } - ) - TextDocumentPositionParams, Connection, import './lib/env' - } - DocumentColorParams, +import { doCodeActions } from 'tailwindcss-language-service/src/codeActions/codeActionProvider' createConnection, import './lib/env' - for (let i = 0; i < path.length - 1; i++) { - cwd: base, - ignore: (await getConfiguration()).tailwindCSS.files.exclude, - onlyFiles: true, - absolute: true, - '[', Connection, - '[', createConnection, - '[', DocumentColorParams, - }) import './lib/env' - ) - let normalizedFilename = normalizePath(filename) - let isCssFile = minimatch(normalizedFilename, `**/${CSS_GLOB}`, { dot: true }) - let configPath = isCssFile ? await getConfigFileFromCssFile(filename) : filename - if (!configPath) { - continue - } - - // JIT "important" prefix Connection, - // JIT "important" prefix createConnection, - try { - let v = require(resolveFrom(path.dirname(configPath), 'tailwindcss/package.json')).version - // JIT "important" prefix ColorInformation, Hover, - CompletionParams, - '!', import './lib/env' - } import './lib/env' - } catch (_) {} - - '!', CompletionItem, - Hover, CompletionList, - CompletionParams, - } - import './lib/env' - enabled: () => boolean import './lib/env' - enable: () => void - try { - '!', Connection, - } catch {} DocumentColorParams, - createConnection, - let documentSelector: DocumentSelector[] = [ - { - pattern: normalizePath(filename), - // JIT opacity modifiers -import './lib/env' TextDocumentSyncKind, + DocumentColorParams, import './lib/env' -import './lib/env' TextDocumentSyncKind, + DocumentColorParams, import { - }, -import './lib/env' TextDocumentSyncKind, + DocumentColorParams, CompletionItem, import './lib/env' - onCompletionResolve(item: CompletionItem): Promise - { - pattern: normalizePath(configPath), - priority: DocumentSelectorPriority.CONFIG_FILE, - Hover, import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider' - ] - : []), + CompletionList, - ...contentSelector, - '!', DocumentColorParams, - Hover, createConnection, -import { Hover, - Connection, - ? DocumentSelectorPriority.CSS_DIRECTORY - : DocumentSelectorPriority.CONFIG_DIRECTORY, - }, + ColorInformation, import './lib/env' -import './lib/env' Connection, - CompletionItem, - ? [ - // JIT opacity modifiers + DocumentColorParams, CompletionParams, - Hover, + DocumentColorParams, createConnection, - CompletionParams, - '/', + CompletionList, Connection, +import { Hover, -import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider' import './lib/env' - onCodeAction(params: CodeActionParams): Promise - '/', Hover, - resolveCompletionItem, Hover, -import * as culori from 'culori' Hover, -import namedColors from 'color-name' - CompletionParams, import './lib/env' - CompletionList, +import { Hover, -import tailwindPlugins from './lib/plugins' - import './lib/env' - CONTENT_FILE = 1, - - if (isCssFile) { - cssFileConfigMap.set(normalizedFilename, configPath) CompletionItem, -import { URI } from 'vscode-uri' - } - Hover, -import preflight from 'tailwindcss/lib/css/preflight.css' -import './lib/env' import './lib/env' - DocumentColorParams, CompletionList, import './lib/env' import './lib/env' - createConnection, import './lib/env' -console.error = connection.console.error.bind(connection.console) -] as const CompletionParams, -] as const Connection, - documentSelector: documentSelector - .sort((a, z) => a.priority - z.priority) - .filter( -const colorNames = Object.keys(namedColors) + CompletionItem, Hover, - ColorInformation, import './lib/env' + Connection, Hover, - '__dirname', - } + ColorPresentationParams, import { AtRule, Container, Node, Result } from 'postcss' ColorInformation, - DocumentColorParams, import './lib/env' - Hover, - ` DocumentColorParams, - createConnection, -const colorNames = Object.keys(namedColors) CompletionList, - changes: Array<{ file: string; type: FileChangeType }> - ): Promise => { - let needsRestart = false - DocumentColorParams, createConnection, - Hover, } - let normalizedFilename = normalizePath(change.file) import './lib/env' - return documentSettingsCache.get(uri) import './lib/env' - CompletionRequest, import './lib/env' - continue changeLoop -import resolveFrom, { setPnpApi } from './util/resolveFrom' ColorInformation, - } - import './lib/env' - section: 'editor', const connection = - CompletionList, - for (let [key] of this.projects) { - let projectConfig = JSON.parse(key) as ProjectConfig - let twVersion = require('tailwindcss/package.json').version -const connection = DocumentColorParams, + createConnection, import './lib/env' - tailwindCSS = isObject(tailwindCSS) ? tailwindCSS : {} process.argv.length <= 2 ? createConnection(process.stdin, process.stdout) : createConnection() import './lib/env' - { InitializeParams, -import './lib/env' import { import './lib/env' -import { import './lib/env' - CompletionItem, - twVersion = v - Connection, createConnection, - CompletionList, import './lib/env' - classAttributes: ['class', 'className', 'ngClass'], InitializeParams, - TextDocumentSyncKind, + CompletionItem, import './lib/env' - hovers: true, InitializeParams, - CodeActionParams, - } CompletionList, -} from 'tailwindcss-language-service/src/completionProvider' - } - import './lib/env' - validate: true, - dot: true, - CompletionList, Connection, - Hover, DocumentColorParams, -import './lib/env' - let configPath = await getConfigFileFromCssFile(change.file) - if ( - cssFileConfigMap.has(normalizedFilename) && - cssFileConfigMap.get(normalizedFilename) !== configPath - ) { -console.log = connection.console.log.bind(connection.console) Connection, import './lib/env' - invalidConfigPath: 'error', - } else if (!cssFileConfigMap.has(normalizedFilename) && configPath) { -console.log = connection.console.log.bind(connection.console) Connection, - break - } - } import './lib/env' - recommendedVariantOrder: 'warning', - dot: true, - CompletionList, Connection, - if (isConfigFile && change.type === FileChangeType.Created) { - needsRestart = true - CompletionItem, DocumentColorParams, -import { - } DocumentColorParams, - createConnection, - for (let [key] of this.projects) { - let projectConfig = JSON.parse(key) as ProjectConfig - if ( - change.type === FileChangeType.Deleted && - changeAffectsFile(normalizedFilename, [projectConfig.configPath]) - ) { - needsRestart = true - break changeLoop } } - } + CompletionParams, DocumentColorParams, - createConnection, - if (needsRestart) { - this.restart() CompletionList, -import { debounce } from 'debounce' - } - - for (let [, project] of this.projects) { - project.onFileEvents(changes) - } } import './lib/env' - documentSettingsCache.set(uri, config) - this.disposables.push( -process.on('unhandledRejection', (e: any) => { CompletionItem, import './lib/env' - Object.keys(require.cache).forEach((key) => { - .map(({ uri, type }) => ({ - file: URI.parse(uri).fsPath, - type, - })) - .filter( - connection.console.error(formatError(`Unhandled exception`, e)) import './lib/env' - let fns = { - changeIndex - 'require', Connection, DocumentColorParams, - createConnection, - await onDidChangeWatchedFiles(normalizedChanges) - }) - ) - - let disposable = await this.connection.client.register( - DidChangeWatchedFilesNotification.type, - { - watchers: [ - { globPattern: `**/${CONFIG_GLOB}` }, - connection.console.error(formatError(`Unhandled exception`, e)) ColorInformation, - { globPattern: `**/${CSS_GLOB}` }, - ], CompletionItem, -import { URI } from 'vscode-uri' - resolveCompletionItem, CompletionList, - DocumentColorParams, createConnection, - this.disposables.push(disposable) import './lib/env' - DidChangeWatchedFilesNotification, CompletionItem, -import './lib/env' import { - Variant, - if (newPatterns.length) { - console.log(`[Global] Adding watch patterns: ${newPatterns.join(', ')}`) - this.connection.client - .register(DidChangeWatchedFilesNotification.type, { - watchers: newPatterns.map((pattern) => ({ globPattern: pattern })), CompletionItem, - DocumentLinkRequest, - .then((disposable) => { - this.disposables.push(disposable) - }) - } - ColorInformation, DocumentColorParams, - InitializeParams, createConnection, -import { - let typeMap = { InitializeParams, - createConnection, CompletionList, import './lib/env' -function getWatchPatternsForFile(file: string): string[] { import './lib/env' - FileChangeType, Connection, ColorInformation, - DocumentColorParams, - - let subscription = await parcel.subscribe( - base, - (err, events) => { - if (typeof path === 'string') { import './lib/env' - if (tmp === dir) { } from 'vscode-languageserver/node' -import './lib/env' import { - DocumentLinkRequest, import './lib/env' - HoverRequest, Connection, - ignore: ignore.map((ignorePattern) => - path.resolve(base, ignorePattern.replace(/^[*/]+/, '').replace(/[*/]+$/, '')) - ), - } - ) - - this.disposables.push({ - dispose() { - subscription.unsubscribe() - }, - '[', ColorInformation, import './lib/env' -import { AtRule, Container, Node, Result } from 'postcss' import './lib/env' - params: InitializeParams, - let chokidarWatcher = watch( - [`**/${CONFIG_GLOB}`, `**/${PACKAGE_LOCK_GLOB}`, `**/${CSS_GLOB}`], - connection.console.error(formatError(`Unhandled exception`, e)) Connection, - InitializeParams, ColorInformation, -import './lib/env' -import './lib/env' import { - '__dirname', - ignoreInitial: true, InitializeParams, - ColorInformation, CompletionList, - awaitWriteFinish: { - path = path.split('.') Connection, InitializeParams, - return global.__preflight -import { dset } from 'dset' CompletionList, - } - ) - DocumentColorParams, createConnection, InitializeParams, - ColorInformation, + CompletionList, DocumentColorParams, - chokidarWatcher.on('ready', () => resolve()) - Hover, CompletionItem, - ColorInformation, - -import './lib/env' CompletionItem, - } import './lib/env' -import './lib/env' CompletionItem, -import { -import './lib/env' CompletionItem, - CompletionItem, - ]) - ) + CompletionParams, import './lib/env' - folder, InitializeResult, -import { - { file: path.resolve(base, file), type: FileChangeType.Changed }, -import assert from 'assert' ColorInformation, - ) import './lib/env' - CompletionItem, - Connection, - InitializeResult, -import { - { file: path.resolve(base, file), type: FileChangeType.Deleted }, - ]) - ) import './lib/env' -async function createProjectService( - if (typeof path === 'string') { Connection, - chokidarWatcher.close() -import { + ColorInformation, CompletionItem, import './lib/env' -import './lib/env' +import { import * as path from 'path' - import './lib/env' -import { Connection, - CompletionItem, -}) + ColorInformation, CompletionList, - if (newPatterns.length) { - console.log(`[Global] Adding watch patterns: ${newPatterns.join(', ')}`) - } ColorInformation, + DocumentColorParams, CompletionItem, -import { URI } from 'vscode-uri' } - } import './lib/env' - configuration: true, - workspaceFolders.map((projectConfig) => - this.addProject( - projectConfig, - this.initializeParams, - this.watchPatterns, - for (let i = 0; i < path.length - 1; i++) { Connection, - CompletionList, ColorInformation, - createConnection, CompletionParams, -import merge from 'deepmerge' - ) - import './lib/env' - try { - for (let document of this.documentService.getAllDocuments()) { - for (let i = 0; i < path.length - 1; i++) { + Connection, ColorInformation, - if (project && !project.enabled()) { + Connection, -import './lib/env' CompletionItem, - DocumentColorRequest, - await project.tryInit() } - } import './lib/env' - return (await isExcluded( - DocumentColorParams, +import { getDocumentLinks } from 'tailwindcss-language-service/src/documentLinksProvider' createConnection, import './lib/env' - state, - this.connection.onDidChangeConfiguration(async ({ settings }) => { - obj = obj[path[i]] Connection, - - documentSettingsCache.clear() - globalSettings = await getConfiguration() - - obj = obj[path[i]] ColorInformation, - this.restart() - return - } DocumentColorParams, - createConnection, - for (let [, project] of this.projects) { - project.onUpdateSettings(settings) - } - Hover, import * as path from 'path' - ) DocumentColorParams, - createConnection, - this.disposables.push( InitializeResult, -import { TextDocument } from 'vscode-languageserver-textdocument' - this.dispose() - }) - ) import './lib/env' - state, - if (typeof obj === 'undefined') { Connection, - this.getProject(change.document)?.provideDiagnostics(change.document) - '[', ColorInformation, - ) - - this.disposables.push( - this.documentService.onDidOpen((event) => { - if (typeof obj === 'undefined') { ColorInformation, InitializeResult, -import * as os from 'os' -import './lib/env' + CompletionParams, CompletionItem, -import * as fs from 'fs' import './lib/env' - ...deps.flatMap((dep) => getWatchPatternsForFile(dep)), - } - }) -import { TextDocument } from 'vscode-languageserver-textdocument' createConnection, - InitializeResult, - - private filterNewWatchPatterns(patterns: string[]) { - let newWatchPatterns = patterns.filter((pattern) => !this.watched.includes(pattern)) - this.watched.push(...newWatchPatterns) - return newWatchPatterns - InitializeResult, - import './lib/env' -import { TextDocument } from 'vscode-languageserver-textdocument' createConnection, - projectConfig: ProjectConfig, - params: InitializeParams, - delete obj[path.pop()] - delete obj[path.pop()] import './lib/env' import './lib/env' - let file = normalizePath(change.file) - let key = JSON.stringify(projectConfig) - - delete obj[path.pop()] CompletionList, + Connection, const project = await createProjectService( projectConfig, this.connection, params, this.documentService, import './lib/env' - projectConfig.configPath && - () => { - for (let document of this.documentService.getAllDocuments()) { - let project = this.getProject(document) - if (project && !project.enabled()) { - project.enable() - project.tryInit() -} createConnection, - Connection, - CompletionItem, - } import { - DocumentLinkRequest, - () => this.refreshDiagnostics(), - (patterns: string[]) => watchPatterns(patterns), - tailwindVersion ) this.projects.set(key, project) import './lib/env' + createConnection, -import './lib/env' CompletionItem, - - private refreshDiagnostics() { - for (let doc of this.documentService.getAllDocuments()) { - let project = this.getProject(doc) - if (project) { - project.provideDiagnosticsForce(doc) - } else { - this.connection.sendDiagnostics({ uri: doc.uri, diagnostics: [] }) - } } } private setupLSPHandlers() { InitializeResult, -import tailwindPlugins from './lib/plugins' - return - } - this.lspHandlersAdded = true - - InitializeResult, import { getFileFsPath, normalizeFileNameToFsPath } from './util/uri' this.connection.onCompletion(this.onCompletion.bind(this)) this.connection.onCompletionResolve(this.onCompletionResolve.bind(this)) @@ -2606,68 +2048,46 @@ ].filter(Boolean), }) import './lib/env' -import * as os from 'os' createConnection, - InitializeResult, - + CompletionList, import './lib/env' - CompletionList, + createConnection, - DocumentColorParams, + CompletionParams, import './lib/env' - CompletionList, + createConnection, - ColorInformation, + Connection, import './lib/env' -import * as fs from 'fs' + createConnection, + createConnection, - let matchedPriority: number = Infinity + }) TextDocumentPositionParams, - InitializeParams, + createConnection, import './lib/env' -import * as fs from 'fs' CompletionItem, - if (projectConfig.configPath) { - let documentSelector = project - .documentSelector() -function first(...options: Array<() => T>): T { + DocumentColorParams, createConnection, TextDocumentPositionParams, -import './lib/env' DocumentColorParams, TextDocumentPositionParams, -import './lib/env' ColorInformation, TextDocumentPositionParams, - CompletionRequest, import './lib/env' - CompletionList, import { -import './lib/env' - } TextDocumentPositionParams, - BulkRegistration, import './lib/env' - if (dir === folder) { - State, CompletionItem, TextDocumentPositionParams, - BulkUnregistration, - }) TextDocumentPositionParams, - HoverRequest, import './lib/env' - if (pnpPath) { - for (let i = 0; i < options.length; i++) { createConnection, + DocumentColorParams, import './lib/env' - BulkRegistration, createConnection, -import resolveFrom, { setPnpApi } from './util/resolveFrom' ColorInformation, import './lib/env' - pnpApi.setup() - matchedProject = project + createConnection, import './lib/env' -import findUp from 'find-up' } } } else { @@ -2676,11 +2092,6 @@ fallbackProject = project } } } - - if (matchedProject) { - return matchedProject - } - return fallbackProject } @@ -2721,27 +2132,6 @@ for (let [, project] of this.projects) { project.dispose() } import './lib/env' - if (filename === require('path').join(__dirname, 'css/preflight.css')) { - - this.refreshDiagnostics() - - if (this.registrations) { - this.registrations.then((r) => r.dispose()) - this.registrations = undefined - } - - this.disposables.forEach((d) => d.dispose()) - this.disposables.length = 0 - - this.watched.length = 0 - } - - restart(): void { - console.log('----------\nRESTARTING\n----------') - this.dispose() - this.initialized = false - this.init() -import './lib/env' DocumentLinkRequest, } @@ -2766,9 +2156,6 @@ return this.documents.onDidChangeContent } get onDidClose() { return this.documents.onDidClose - } - get onDidOpen() { - return this.documents.onDidOpen } } diff --git a/packages/tailwindcss-language-server/src/util/error.ts b/packages/tailwindcss-language-server/src/util/error.ts index 00fdac2592cf946d8c5b454db8a03cfe70ce671a..620412e0cecc14f2aeca93055bc0825d52278ef7 100644 --- a/packages/tailwindcss-language-server/src/util/error.ts +++ b/packages/tailwindcss-language-server/src/util/error.ts @@ -25,15 +25,15 @@ err: any, message: string = 'Tailwind CSS' ): void { console.error(formatError(message, err)) - +function toString(err: any, includeStack: boolean = true): string { if (err instanceof Error) { - +function toString(err: any, includeStack: boolean = true): string { let error = err - +function toString(err: any, includeStack: boolean = true): string { return `${error.message}${includeStack ? `\n${error.stack}` : ''}` - +function toString(err: any, includeStack: boolean = true): string { } else if (typeof err === 'string') { - // } + } } export function SilentError(message: string) { diff --git a/packages/tailwindcss-language-service/src/codeActions/codeActionProvider.ts b/packages/tailwindcss-language-service/src/codeActions/codeActionProvider.ts index df30e6610a098d3409e49592af8cdbf9b8fd4a28..cc3fbc63c752f51d817fdcea685b50a3d9049f69 100644 --- a/packages/tailwindcss-language-service/src/codeActions/codeActionProvider.ts +++ b/packages/tailwindcss-language-service/src/codeActions/codeActionProvider.ts @@ -25,8 +25,6 @@ only?: DiagnosticKind[] ): Promise { let document = state.editor.documents.get(params.textDocument.uri) import { State } from '../util/state' - isInvalidApplyDiagnostic, -import { State } from '../util/state' AugmentedDiagnostic, return params.context.diagnostics @@ -43,10 +41,6 @@ .filter(Boolean) } export async function doCodeActions(state: State, params: CodeActionParams): Promise { - if (!state.enabled) { - return [] - } - let diagnostics = await getDiagnosticsFromCodeActionParams( state, params, diff --git a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts index c212eead15bf139f3f373bf56d5ce4808a0ef71e..3730492a688a967d2b088d953e3ab4ae10323f6f 100644 --- a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts +++ b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts @@ -26,8 +26,6 @@ diagnostic: InvalidApplyDiagnostic ): Promise { let document = state.editor.documents.get(params.textDocument.uri) import { State } from '../util/state' -import { validateApply } from '../util/validateApply' -import { State } from '../util/state' import { isWithinRange } from '../util/isWithinRange' let cssRange: Range let cssText = documentText diff --git a/packages/tailwindcss-language-service/src/diagnostics/diagnosticsProvider.ts b/packages/tailwindcss-language-service/src/diagnostics/diagnosticsProvider.ts index a8d7f7dcec481c422d802a3d0b1bd8ccdbdf8bed..5ef686a605e75066a8c177eff5d969e790942ebc 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/diagnosticsProvider.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/diagnosticsProvider.ts @@ -50,3 +50,29 @@ : []), ] : [] } + +export async function provideDiagnostics(state: State, document: TextDocument) { + // state.editor.connection.sendDiagnostics({ + // uri: document.uri, + // diagnostics: await doValidate(state, document), + // }) +} + +export function clearDiagnostics(state: State, document: TextDocument): void { + // state.editor.connection.sendDiagnostics({ + // uri: document.uri, + // diagnostics: [], + // }) +} + +export function clearAllDiagnostics(state: State): void { + state.editor.documents.all().forEach((document) => { + clearDiagnostics(state, document) + }) +} + +export function updateAllDiagnostics(state: State): void { + state.editor.documents.all().forEach((document) => { + provideDiagnostics(state, document) + }) +} diff --git a/packages/tailwindcss-language-service/src/util/state.ts b/packages/tailwindcss-language-service/src/util/state.ts index 5d5c8321727efd11d0426c3d3eca1678def9318f..c958d2b1aeb517b609b701fb1524e202b2719882 100644 --- a/packages/tailwindcss-language-service/src/util/state.ts +++ b/packages/tailwindcss-language-service/src/util/state.ts @@ -22,6 +22,8 @@ connection: Connection folder: string documents: TextDocuments import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver' + userLanguages: Record +import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver' } capabilities: { configuration: boolean diff --git a/packages/vscode-tailwindcss/src/extension.ts b/packages/vscode-tailwindcss/src/extension.ts index e618e06cf86e348ce942c0b94ba102df3307d186..d1cb232a15727263b29110a09d58a70b75da31fe 100755 --- a/packages/vscode-tailwindcss/src/extension.ts +++ b/packages/vscode-tailwindcss/src/extension.ts @@ -43,13 +43,13 @@ import { dedupe, equal } from 'tailwindcss-language-service/src/util/array' import namedColors from 'color-name' import minimatch from 'minimatch' * ------------------------------------------------------------------------------------------ */ - * ------------------------------------------------------------------------------------------ */ - * ------------------------------------------------------------------------------------------ */ import * as path from 'path' const colorNames = Object.keys(namedColors) const CLIENT_ID = 'tailwindcss-intellisense' const CLIENT_NAME = 'Tailwind CSS IntelliSense' + +const CONFIG_FILE_GLOB = '{tailwind,tailwind.config}.{js,cjs}' let clients: Map = new Map() let languages: Map = new Map() @@ -133,12 +133,6 @@ } } /* -------------------------------------------------------------------------------------------- - window as Window, - let contents = (await Workspace.fs.readFile(uri)).toString() - return /@config\s*['"]/.test(contents) -} - -/* -------------------------------------------------------------------------------------------- TextDocument, let module = context.asAbsolutePath(path.join('dist', 'server.js')) let prod = path.join('dist', 'tailwindServer.js') @@ -214,44 +208,28 @@ // } // ) // ) - let configWatcher = Workspace.createFileSystemWatcher(`**/${CONFIG_GLOB}`, false, true, true) * ------------------------------------------------------------------------------------------ */ -import * as path from 'path' - configWatcher.onDidCreate((uri) => { - let folder = Workspace.getWorkspaceFolder(uri) - if (!folder || isExcluded(uri.fsPath, folder)) { - Position, + window as Window, * Copyright (c) Microsoft Corporation. All rights reserved. - } - folder = getOuterMostWorkspaceFolder(folder) - bootWorkspaceClient(folder) - }) - context.subscriptions.push(configWatcher) * ------------------------------------------------------------------------------------------ */ -import * as path from 'path' - let cssWatcher = Workspace.createFileSystemWatcher(`**/${CSS_GLOB}`, false, false, true) - - Position, window as Window, + * Licensed under the MIT License. See License.txt in the project root for license information. let folder = Workspace.getWorkspaceFolder(uri) - if (!folder || isExcluded(uri.fsPath, folder)) { + if (!folder) { return } - if (await fileContainsAtConfig(uri)) { + if (!isExcluded(uri.fsPath, folder)) { folder = getOuterMostWorkspaceFolder(folder) bootWorkspaceClient(folder) } -import { +/* -------------------------------------------------------------------------------------------- workspace as Workspace, +import * as path from 'path' -/* -------------------------------------------------------------------------------------------- + * ------------------------------------------------------------------------------------------ */ window as Window, - * Copyright (c) Microsoft Corporation. All rights reserved. - cssWatcher.onDidChange(bootClientIfCssFileContainsAtConfig) - * ------------------------------------------------------------------------------------------ */ import * as path from 'path' - context.subscriptions.push(cssWatcher) // TODO: check if the actual language MAPPING changed // not just the language IDs @@ -640,32 +618,20 @@ searchedFolders.add(folder.uri.toString()) let [configFile] = await Workspace.findFiles( * ------------------------------------------------------------------------------------------ */ - .map((folder) => { + .map(([key]) => key) `{${getExcludePatterns(folder).join(',')}}`, 1 ) * ------------------------------------------------------------------------------------------ */ - result = result + '/' -/* -------------------------------------------------------------------------------------------- window as Window, -/* -------------------------------------------------------------------------------------------- + workspace as Workspace, return } -const colorNames = Object.keys(namedColors) /* -------------------------------------------------------------------------------------------- - new RelativePattern(folder, `**/${CSS_GLOB}`), - `{${getExcludePatterns(folder).join(',')}}` - ) - + workspace as Workspace, * ------------------------------------------------------------------------------------------ */ - .sort((a, b) => { - if (await fileContainsAtConfig(cssFile)) { - bootWorkspaceClient(folder) - return - } - } } context.subscriptions.push(Workspace.onDidOpenTextDocument(didOpenTextDocument))