private void SendFeatureChangesTelemetry(LanguageServerSettingsWrapper incomingSettings) { if (incomingSettings is null) { this._logger.LogTrace("Incoming settings were null"); return; } var configChanges = new Dictionary <string, bool>(); // Send telemetry if the user opted-out of ScriptAnalysis if (incomingSettings.Powershell.ScriptAnalysis.Enable == false && _configurationService.CurrentSettings.ScriptAnalysis.Enable != incomingSettings.Powershell.ScriptAnalysis.Enable) { configChanges["ScriptAnalysis"] = incomingSettings.Powershell.ScriptAnalysis.Enable ?? false; } // Send telemetry if the user opted-out of CodeFolding if (!incomingSettings.Powershell.CodeFolding.Enable && _configurationService.CurrentSettings.CodeFolding.Enable != incomingSettings.Powershell.CodeFolding.Enable) { configChanges["CodeFolding"] = incomingSettings.Powershell.CodeFolding.Enable; } // Send telemetry if the user opted-out of the prompt to update PackageManagement if (!incomingSettings.Powershell.PromptToUpdatePackageManagement && _configurationService.CurrentSettings.PromptToUpdatePackageManagement != incomingSettings.Powershell.PromptToUpdatePackageManagement) { configChanges["PromptToUpdatePackageManagement"] = incomingSettings.Powershell.PromptToUpdatePackageManagement; } // Send telemetry if the user opted-out of Profile loading if (!incomingSettings.Powershell.EnableProfileLoading && _configurationService.CurrentSettings.EnableProfileLoading != incomingSettings.Powershell.EnableProfileLoading) { configChanges["ProfileLoading"] = incomingSettings.Powershell.EnableProfileLoading; } // Send telemetry if the user opted-in to Pester 5+ CodeLens if (!incomingSettings.Powershell.Pester.UseLegacyCodeLens && _configurationService.CurrentSettings.Pester.UseLegacyCodeLens != incomingSettings.Powershell.Pester.UseLegacyCodeLens) { // From our perspective we want to see how many people are opting in to this so we flip the value configChanges["Pester5CodeLens"] = !incomingSettings.Powershell.Pester.UseLegacyCodeLens; } // No need to send any telemetry since nothing changed if (configChanges.Count == 0) { return; } _languageServer.Window.SendTelemetryEvent(new TelemetryEventParams { ExtensionData = new PsesTelemetryEvent { EventName = "NonDefaultPsesFeatureConfiguration", Data = JObject.FromObject(configChanges) } }); }
public async Task <Unit> Handle(DidChangeConfigurationParams request, CancellationToken cancellationToken) { LanguageServerSettingsWrapper incomingSettings = request.Settings.ToObject <LanguageServerSettingsWrapper>(); if (incomingSettings == null) { return(await Unit.Task.ConfigureAwait(false)); } bool oldLoadProfiles = _configurationService.CurrentSettings.EnableProfileLoading; bool oldScriptAnalysisEnabled = _configurationService.CurrentSettings.ScriptAnalysis.Enable ?? false; string oldScriptAnalysisSettingsPath = _configurationService.CurrentSettings.ScriptAnalysis?.SettingsPath; _configurationService.CurrentSettings.Update( incomingSettings.Powershell, _workspaceService.WorkspacePath, _logger); if (!this._profilesLoaded && _configurationService.CurrentSettings.EnableProfileLoading && oldLoadProfiles != _configurationService.CurrentSettings.EnableProfileLoading) { await _powerShellContextService.LoadHostProfilesAsync().ConfigureAwait(false); this._profilesLoaded = true; } // Wait until after profiles are loaded (or not, if that's the // case) before starting the interactive console. if (!this._consoleReplStarted) { // Start the interactive terminal _powerShellContextService.ConsoleReader.StartCommandLoop(); this._consoleReplStarted = true; } // If there is a new settings file path, restart the analyzer with the new settings. bool settingsPathChanged = false; string newSettingsPath = _configurationService.CurrentSettings.ScriptAnalysis.SettingsPath; if (!string.Equals(oldScriptAnalysisSettingsPath, newSettingsPath, StringComparison.OrdinalIgnoreCase)) { if (_analysisService != null) { _analysisService.SettingsPath = newSettingsPath; settingsPathChanged = true; } } // If script analysis settings have changed we need to clear & possibly update the current diagnostic records. if ((oldScriptAnalysisEnabled != _configurationService.CurrentSettings.ScriptAnalysis?.Enable) || settingsPathChanged) { // If the user just turned off script analysis or changed the settings path, send a diagnostics // event to clear the analysis markers that they already have. if (!_configurationService.CurrentSettings.ScriptAnalysis.Enable.Value || settingsPathChanged) { foreach (var scriptFile in _workspaceService.GetOpenedFiles()) { _analysisService.ClearMarkers(scriptFile); } } } // Convert the editor file glob patterns into an array for the Workspace // Both the files.exclude and search.exclude hash tables look like (glob-text, is-enabled): // "files.exclude" : { // "Makefile": true, // "*.html": true, // "build/*": true // } var excludeFilePatterns = new List <string>(); if (incomingSettings.Files?.Exclude != null) { foreach (KeyValuePair <string, bool> patternEntry in incomingSettings.Files.Exclude) { if (patternEntry.Value) { excludeFilePatterns.Add(patternEntry.Key); } } } if (incomingSettings.Search?.Exclude != null) { foreach (KeyValuePair <string, bool> patternEntry in incomingSettings.Files.Exclude) { if (patternEntry.Value && !excludeFilePatterns.Contains(patternEntry.Key)) { excludeFilePatterns.Add(patternEntry.Key); } } } _workspaceService.ExcludeFilesGlob = excludeFilePatterns; // Convert the editor file search options to Workspace properties if (incomingSettings.Search?.FollowSymlinks != null) { _workspaceService.FollowSymlinks = incomingSettings.Search.FollowSymlinks; } return(await Unit.Task.ConfigureAwait(false)); }
public async Task <Unit> Handle(DidChangeConfigurationParams request, CancellationToken cancellationToken) { LanguageServerSettingsWrapper incomingSettings = request.Settings.ToObject <LanguageServerSettingsWrapper>(); if (incomingSettings == null) { return(await Unit.Task.ConfigureAwait(false)); } bool oldLoadProfiles = _configurationService.CurrentSettings.EnableProfileLoading; bool oldScriptAnalysisEnabled = _configurationService.CurrentSettings.ScriptAnalysis.Enable ?? false; string oldScriptAnalysisSettingsPath = _configurationService.CurrentSettings.ScriptAnalysis?.SettingsPath; _configurationService.CurrentSettings.Update( incomingSettings.Powershell, _workspaceService.WorkspacePath, _logger); if (!this._cwdSet) { if (!string.IsNullOrEmpty(_configurationService.CurrentSettings.Cwd) && Directory.Exists(_configurationService.CurrentSettings.Cwd)) { await _powerShellContextService.SetWorkingDirectoryAsync( _configurationService.CurrentSettings.Cwd, isPathAlreadyEscaped : false).ConfigureAwait(false); } else if (_workspaceService.WorkspacePath != null && Directory.Exists(_workspaceService.WorkspacePath)) { await _powerShellContextService.SetWorkingDirectoryAsync( _workspaceService.WorkspacePath, isPathAlreadyEscaped : false).ConfigureAwait(false); } this._cwdSet = true; } if (!this._profilesLoaded && _configurationService.CurrentSettings.EnableProfileLoading && oldLoadProfiles != _configurationService.CurrentSettings.EnableProfileLoading) { await _powerShellContextService.LoadHostProfilesAsync().ConfigureAwait(false); this._profilesLoaded = true; } // Wait until after profiles are loaded (or not, if that's the // case) before starting the interactive console. if (!this._consoleReplStarted) { // Start the interactive terminal _powerShellContextService.ConsoleReader.StartCommandLoop(); this._consoleReplStarted = true; } // Run any events subscribed to configuration updates ConfigurationUpdated(this, _configurationService.CurrentSettings); // Convert the editor file glob patterns into an array for the Workspace // Both the files.exclude and search.exclude hash tables look like (glob-text, is-enabled): // "files.exclude" : { // "Makefile": true, // "*.html": true, // "build/*": true // } var excludeFilePatterns = new List <string>(); if (incomingSettings.Files?.Exclude != null) { foreach (KeyValuePair <string, bool> patternEntry in incomingSettings.Files.Exclude) { if (patternEntry.Value) { excludeFilePatterns.Add(patternEntry.Key); } } } if (incomingSettings.Search?.Exclude != null) { foreach (KeyValuePair <string, bool> patternEntry in incomingSettings.Search.Exclude) { if (patternEntry.Value && !excludeFilePatterns.Contains(patternEntry.Key)) { excludeFilePatterns.Add(patternEntry.Key); } } } _workspaceService.ExcludeFilesGlob = excludeFilePatterns; // Convert the editor file search options to Workspace properties if (incomingSettings.Search?.FollowSymlinks != null) { _workspaceService.FollowSymlinks = incomingSettings.Search.FollowSymlinks; } return(await Unit.Task.ConfigureAwait(false)); }
public override async Task <Unit> Handle(DidChangeConfigurationParams request, CancellationToken cancellationToken) { LanguageServerSettingsWrapper incomingSettings = request.Settings.ToObject <LanguageServerSettingsWrapper>(); _logger.LogTrace("Handling DidChangeConfiguration"); if (incomingSettings is null || incomingSettings.Powershell is null) { _logger.LogTrace("Incoming settings were null"); return(await Unit.Task.ConfigureAwait(false)); } SendFeatureChangesTelemetry(incomingSettings); bool profileLoadingPreviouslyEnabled = _configurationService.CurrentSettings.EnableProfileLoading; bool oldScriptAnalysisEnabled = _configurationService.CurrentSettings.ScriptAnalysis.Enable; string oldScriptAnalysisSettingsPath = _configurationService.CurrentSettings.ScriptAnalysis?.SettingsPath; _configurationService.CurrentSettings.Update( incomingSettings.Powershell, _workspaceService.WorkspacePath, _logger); // We need to load the profiles if: // - Profile loading is configured, AND // - Profiles haven't been loaded before, OR // - The profile loading configuration just changed bool loadProfiles = _configurationService.CurrentSettings.EnableProfileLoading && (!_profilesLoaded || !profileLoadingPreviouslyEnabled); if (!_psesHost.IsRunning) { _logger.LogTrace("Starting command loop"); if (loadProfiles) { _logger.LogTrace("Loading profiles..."); } await _psesHost.TryStartAsync(new HostStartOptions { LoadProfiles = loadProfiles }, CancellationToken.None).ConfigureAwait(false); if (loadProfiles) { _profilesLoaded = true; _logger.LogTrace("Loaded!"); } } // TODO: Load profiles when the host is already running? Note that this might mess up // the ordering and require the foreground. if (!_cwdSet) { if (!string.IsNullOrEmpty(_configurationService.CurrentSettings.Cwd) && Directory.Exists(_configurationService.CurrentSettings.Cwd)) { _logger.LogTrace($"Setting CWD (from config) to {_configurationService.CurrentSettings.Cwd}"); await _psesHost.SetInitialWorkingDirectoryAsync( _configurationService.CurrentSettings.Cwd, CancellationToken.None).ConfigureAwait(false); } else if (_workspaceService.WorkspacePath is not null && Directory.Exists(_workspaceService.WorkspacePath)) { _logger.LogTrace($"Setting CWD (from workspace) to {_workspaceService.WorkspacePath}"); await _psesHost.SetInitialWorkingDirectoryAsync( _workspaceService.WorkspacePath, CancellationToken.None).ConfigureAwait(false); } else { _logger.LogTrace("Tried to set CWD but in bad state"); } _cwdSet = true; }