diff --git a/package-lock.json b/package-lock.json index fd99e95..3486876 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "psalm-vscode-plugin", "version": "2.6.0", "license": "MIT", "dependencies": { diff --git a/src/LanguageServer.ts b/src/LanguageServer.ts index e48a488..db5fc41 100644 --- a/src/LanguageServer.ts +++ b/src/LanguageServer.ts @@ -95,6 +95,22 @@ export class LanguageServer { this.languageClient.onTelemetry(this.onTelemetry.bind(this)); } + /** + * This will NOT restart the server. + * @param workspacePath + */ + public setWorkspacePath(workspacePath: string): void { + this.workspacePath = workspacePath; + } + + /** + * This will NOT restart the server. + * @param psalmConfigPath + */ + public setPsalmConfigPath(psalmConfigPath: string): void { + this.psalmConfigPath = psalmConfigPath; + } + public createDefaultErrorHandler(maxRestartCount?: number): ErrorHandler { if (maxRestartCount !== undefined && maxRestartCount < 0) { throw new Error(`Invalid maxRestartCount: ${maxRestartCount}`); diff --git a/src/LanguageServerErrorHandler.ts b/src/LanguageServerErrorHandler.ts index bac98ef..9ddf898 100644 --- a/src/LanguageServerErrorHandler.ts +++ b/src/LanguageServerErrorHandler.ts @@ -24,7 +24,7 @@ export default class LanguageServerErrorHandler implements ErrorHandler { if (this.restarts.length <= this.maxRestartCount) { return CloseAction.Restart; } else { - let diff = + const diff = this.restarts[this.restarts.length - 1] - this.restarts[0]; if (diff <= 3 * 60 * 1000) { void showReportIssueErrorMessage( diff --git a/src/commands.ts b/src/commands.ts index 8b077f2..413ac6a 100755 --- a/src/commands.ts +++ b/src/commands.ts @@ -73,7 +73,9 @@ function reportIssue( 'report_issue_template.md' ); - const userSettings = Object.entries(configurationService.getAll()) + const userSettings = Object.entries( + configurationService.getAll() + ) .map(([key, value]) => `${key}: ${JSON.stringify(value)}`) .join(EOL); const psalmLogs = loggingService.getContent().join(EOL); @@ -88,7 +90,8 @@ function reportIssue( let psalmVersion: string | null = 'unknown'; try { psalmVersion = - (await client.getPsalmLanguageServerVersion()) ?? 'unknown'; + (await client.getPsalmLanguageServerVersion()) ?? + 'unknown'; } catch (err) { psalmVersion = err.message; } diff --git a/src/extension.ts b/src/extension.ts index efa93df..5488fe1 100755 --- a/src/extension.ts +++ b/src/extension.ts @@ -20,7 +20,7 @@ export async function activate( const configurationService = new ConfigurationService(); await configurationService.init(); - //Set Logging Level + // Set Logging Level loggingService.setOutputLevel( configurationService.get('logLevel') ); @@ -37,9 +37,60 @@ export async function activate( return; } - const workspacePath = workspaceFolders[0].uri.fsPath; + const getCurrentWorkspace = ( + workspaceFolders: readonly vscode.WorkspaceFolder[] + ) => { + const activeWorkspace = vscode.window.activeTextEditor + ? vscode.workspace.getWorkspaceFolder( + vscode.window.activeTextEditor.document.uri + ) + : workspaceFolders[0]; - const configPaths = configurationService.get('configPaths') || []; + const workspacePath = activeWorkspace + ? activeWorkspace.uri.fsPath + : workspaceFolders[0].uri.fsPath; + + return { workspacePath }; + }; + + const getOptions = async () => { + const configPaths = + configurationService.get('configPaths') || []; + + const psalmXMLFiles = await vscode.workspace.findFiles( + `{${configPaths.join(',')}}` + // `**/vendor/**/{${configPaths.join(',')}}` + ); + + const psalmXMLPaths = psalmXMLFiles.map((uri) => { + if (process.platform === 'win32') { + return uri.path.replace(/\//g, '\\').replace(/^\\/g, ''); + } + return uri.path; + }); + + const { workspacePath } = getCurrentWorkspace(workspaceFolders); + + const configXml = + psalmXMLPaths.find((path) => path.startsWith(workspacePath)) ?? + psalmXMLPaths[0]; + + return { + configPaths, + psalmXMLFiles, + psalmXMLPaths, + configXml, + workspacePath, + }; + }; + + let { + configPaths, + // psalmXMLFiles, + psalmXMLPaths, + configXml, + workspacePath, + } = await getOptions(); if (!configPaths.length) { loggingService.logError( @@ -48,18 +99,6 @@ export async function activate( return; } - const psalmXMLFiles = await vscode.workspace.findFiles( - `{${configPaths.join(',')}}` - // `**/vendor/**/{${configPaths.join(',')}}` - ); - - const psalmXMLPaths = psalmXMLFiles.map((uri) => { - if (process.platform === 'win32') { - return uri.path.replace(/\//g, '\\').replace(/^\\/g, ''); - } - return uri.path; - }); - if (!psalmXMLPaths.length) { // no psalm.xml found loggingService.logError( @@ -73,11 +112,9 @@ export async function activate( psalmXMLPaths ); - const configXml = psalmXMLPaths[0]; - loggingService.logDebug(`Selecting first found config file: ${configXml}`); - const configWatcher = vscode.workspace.createFileSystemWatcher(configXml); + let configWatcher = vscode.workspace.createFileSystemWatcher(configXml); const languageServer = new LanguageServer( context, @@ -88,6 +125,17 @@ export async function activate( loggingService ); + // restart the language server when changing workspaces + const onWorkspacePathChange = async () => { + //kill the previous watcher + configWatcher.dispose(); + configWatcher = vscode.workspace.createFileSystemWatcher(configXml); + loggingService.logInfo(`Workspace changed: ${workspacePath}`); + languageServer.setWorkspacePath(workspacePath); + languageServer.setPsalmConfigPath(configXml); + languageServer.restart(); + }; + const onConfigChange = () => { loggingService.logInfo(`Config file changed: ${configXml}`); languageServer.restart(); @@ -129,5 +177,24 @@ export async function activate( await configurationService.init(); }); + vscode.window.onDidChangeActiveTextEditor(async (e) => { + if (!e) { + return; + } + + const options = await getOptions(); + + if (!options.workspacePath || workspacePath === options.workspacePath) + return; + + configPaths = options.configPaths; + configXml = options.configXml; + // psalmXMLFiles = options.psalmXMLFiles; + psalmXMLPaths = options.psalmXMLPaths; + workspacePath = options.workspacePath; + + onWorkspacePathChange(); + }); + loggingService.logDebug('Finished Extension Activation'); }