From 55d2b9e8da44faa55971ef006c0750fed5f0da2d Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Thu, 20 Oct 2022 18:41:01 +0100 Subject: [PATCH] Improve `experimental.configFile` in multi-root workspaces (#640) --- .../tailwindcss-language-server/src/server.ts | 9 ++- packages/vscode-tailwindcss/src/extension.ts | 75 +++++++++++++------ 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts index bef3178..d40adf6 100644 --- a/packages/tailwindcss-language-server/src/server.ts +++ b/packages/tailwindcss-language-server/src/server.ts @@ -1592,6 +1592,11 @@ class TW { let cssFileConfigMap: Map = new Map() let configTailwindVersionMap: Map = new Map() + // base directory to resolve relative `experimental.configFile` paths against + let userDefinedConfigBase = this.initializeParams.initializationOptions?.workspaceFile + ? path.dirname(this.initializeParams.initializationOptions.workspaceFile) + : base + if (configFileOrFiles) { if ( typeof configFileOrFiles !== 'string' && @@ -1615,10 +1620,10 @@ class TW { ([relativeConfigPath, relativeDocumentSelectorOrSelectors]) => { return { folder: base, - configPath: path.resolve(base, relativeConfigPath), + configPath: path.resolve(userDefinedConfigBase, relativeConfigPath), documentSelector: [].concat(relativeDocumentSelectorOrSelectors).map((selector) => ({ priority: DocumentSelectorPriority.USER_CONFIGURED, - pattern: path.resolve(base, selector), + pattern: path.resolve(userDefinedConfigBase, selector), })), isUserConfigured: true, } diff --git a/packages/vscode-tailwindcss/src/extension.ts b/packages/vscode-tailwindcss/src/extension.ts index e618e06..9cbd779 100755 --- a/packages/vscode-tailwindcss/src/extension.ts +++ b/packages/vscode-tailwindcss/src/extension.ts @@ -246,6 +246,15 @@ export async function activate(context: ExtensionContext) { // e.g. "plaintext" already exists but you change it from "html" to "css" context.subscriptions.push( Workspace.onDidChangeConfiguration((event) => { + let toReboot = new Set() + + Workspace.textDocuments.forEach((document) => { + let folder = Workspace.getWorkspaceFolder(document.uri) + if (!folder) return + if (event.affectsConfiguration('tailwindCSS.experimental.configFile', folder)) { + toReboot.add(folder) + } + }) ;[...clients].forEach(([key, client]) => { const folder = Workspace.getWorkspaceFolder(Uri.parse(key)) let reboot = false @@ -267,11 +276,15 @@ export async function activate(context: ExtensionContext) { } if (reboot && client) { - clients.delete(folder.uri.toString()) - client.stop() - bootWorkspaceClient(folder) + toReboot.add(folder) } }) + + for (let folder of toReboot) { + clients.get(folder.uri.toString())?.stop() + clients.delete(folder.uri.toString()) + bootClientForFolderIfNeeded(folder) + } }) ) @@ -568,6 +581,8 @@ export async function activate(context: ExtensionContext) { }, initializationOptions: { userLanguages: getUserLanguages(folder), + workspaceFile: + Workspace.workspaceFile?.scheme === 'file' ? Workspace.workspaceFile.fsPath : undefined, }, synchronize: { configurationSection: ['files', 'editor', 'tailwindCSS'], @@ -602,30 +617,13 @@ export async function activate(context: ExtensionContext) { clients.set(folder.uri.toString(), client) } - async function didOpenTextDocument(document: TextDocument): Promise { - if (document.languageId === 'tailwindcss') { - bootCssServer() - } - - // We are only interested in language mode text - if (document.uri.scheme !== 'file') { + async function bootClientForFolderIfNeeded(folder: WorkspaceFolder): Promise { + let settings = Workspace.getConfiguration('tailwindCSS', folder) + if (settings.get('experimental.configFile') !== null) { + bootWorkspaceClient(folder) return } - let uri = document.uri - let folder = Workspace.getWorkspaceFolder(uri) - // Files outside a folder can't be handled. This might depend on the language. - // Single file languages like JSON might handle files outside the workspace folders. - if (!folder) { - return - } - // If we have nested workspace folders we only start a server on the outer most workspace folder. - folder = getOuterMostWorkspaceFolder(folder) - - if (searchedFolders.has(folder.uri.toString())) return - - searchedFolders.add(folder.uri.toString()) - let [configFile] = await Workspace.findFiles( new RelativePattern(folder, `**/${CONFIG_GLOB}`), `{${getExcludePatterns(folder).join(',')}}`, @@ -650,6 +648,35 @@ export async function activate(context: ExtensionContext) { } } + async function didOpenTextDocument(document: TextDocument): Promise { + if (document.languageId === 'tailwindcss') { + bootCssServer() + } + + // We are only interested in language mode text + if (document.uri.scheme !== 'file') { + return + } + + let uri = document.uri + let folder = Workspace.getWorkspaceFolder(uri) + // Files outside a folder can't be handled. This might depend on the language. + // Single file languages like JSON might handle files outside the workspace folders. + if (!folder) { + return + } + // If we have nested workspace folders we only start a server on the outer most workspace folder. + folder = getOuterMostWorkspaceFolder(folder) + + if (searchedFolders.has(folder.uri.toString())) { + return + } + + searchedFolders.add(folder.uri.toString()) + + await bootClientForFolderIfNeeded(folder) + } + context.subscriptions.push(Workspace.onDidOpenTextDocument(didOpenTextDocument)) Workspace.textDocuments.forEach(didOpenTextDocument) context.subscriptions.push(