From a3d087633a3767445483fddab71471b1c31e464a Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 8 Jan 2020 19:52:13 -0800 Subject: [PATCH 1/2] Fix temp debugging after it broke bringing in $psEditor --- .../Commands/Public/CmdletInterface.ps1 | 11 ++- .../Commands/StartEditorServicesCommand.cs | 12 ++- .../Hosting/EditorServicesServerFactory.cs | 11 +++ .../EditorOperationsService.cs | 83 ++++++++++++++++++- .../PowerShellContext/ExtensionService.cs | 6 +- .../PowerShellContextService.cs | 2 +- 6 files changed, 116 insertions(+), 9 deletions(-) diff --git a/module/PowerShellEditorServices/Commands/Public/CmdletInterface.ps1 b/module/PowerShellEditorServices/Commands/Public/CmdletInterface.ps1 index 9018680d9..690506bd3 100644 --- a/module/PowerShellEditorServices/Commands/Public/CmdletInterface.ps1 +++ b/module/PowerShellEditorServices/Commands/Public/CmdletInterface.ps1 @@ -124,6 +124,13 @@ function New-EditorFile { } end { + # If editorContext is null, then we're in a Temp session and + # this cmdlet won't work so return early. + $editorContext = $psEditor.GetEditorContext() + if (!$editorContext) { + return + } + if ($Path) { foreach ($fileName in $Path) { @@ -142,7 +149,7 @@ function New-EditorFile { } $psEditor.Workspace.OpenFile($fileName, $preview) - $psEditor.GetEditorContext().CurrentFile.InsertText(($valueList | Out-String)) + $editorContext.CurrentFile.InsertText(($valueList | Out-String)) } else { $PSCmdlet.WriteError( ( New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList @( @@ -154,7 +161,7 @@ function New-EditorFile { } } else { $psEditor.Workspace.NewFile() - $psEditor.GetEditorContext().CurrentFile.InsertText(($valueList | Out-String)) + $editorContext.CurrentFile.InsertText(($valueList | Out-String)) } } } diff --git a/src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs b/src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs index 22addea79..09d643e3b 100644 --- a/src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs +++ b/src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs @@ -256,7 +256,17 @@ private void StartLogging() _loggerUnsubscribers.Add(_logger.Subscribe(hostLogger)); } - string logPath = Path.Combine(GetLogDirPath(), "StartEditorServices.log"); + string logDirPath = GetLogDirPath(); + string logPath = Path.Combine(logDirPath, "StartEditorServices.log"); + + // Temp debugging sessions may try to reuse this same path, + // so we ensure they have a unique path + if (File.Exists(logPath)) + { + int randomInt = new Random().Next(); + logPath = Path.Combine(logDirPath, $"StartEditorServices-temp{randomInt.ToString("X")}.log"); + } + var fileLogger = StreamLogger.CreateWithNewFile(logPath); _disposableResources.Add(fileLogger); IDisposable fileLoggerUnsubscriber = _logger.Subscribe(fileLogger); diff --git a/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs b/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs index af783abf6..19886ce9e 100644 --- a/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs +++ b/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs @@ -13,6 +13,7 @@ using System.IO; using Microsoft.Extensions.DependencyInjection; using OmniSharp.Extensions.LanguageServer.Server; +using Microsoft.PowerShell.EditorServices.Services; #if DEBUG using Serilog.Debugging; @@ -123,8 +124,18 @@ public PsesDebugServer CreateDebugServerForTempSession(Stream inputStream, Strea .SetMinimumLevel(LogLevel.Trace)) .AddSingleton(provider => null) .AddPsesLanguageServices(hostStartupInfo) + // For a Temp session, there is no LanguageServer so just set it to null + .AddSingleton( + typeof(OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServer), + _ => null) .BuildServiceProvider(); + // This gets the ExtensionService which triggers the creation of the `$psEditor` variable. + // (because services are created only when they are first retrieved) + // Keep in mind, for Temp sessions, the `$psEditor` API is a no-op and the user is warned + // to run the command in the main PS Integrated Console. + serviceProvider.GetService(); + return new PsesDebugServer( _loggerFactory, inputStream, diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs index 01b28b745..1625d0f07 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs @@ -17,18 +17,26 @@ internal class EditorOperationsService : IEditorOperations private const bool DefaultPreviewSetting = true; private WorkspaceService _workspaceService; + private PowerShellContextService _powerShellContextService; private ILanguageServer _languageServer; public EditorOperationsService( WorkspaceService workspaceService, + PowerShellContextService powerShellContextService, ILanguageServer languageServer) { - this._workspaceService = workspaceService; - this._languageServer = languageServer; + _workspaceService = workspaceService; + _powerShellContextService = powerShellContextService; + _languageServer = languageServer; } public async Task GetEditorContextAsync() { + if (!TestHasLanguageServer()) + { + return null; + }; + ClientEditorContext clientContext = await _languageServer.SendRequest( "editor/getEditorContext", @@ -39,6 +47,11 @@ await _languageServer.SendRequest( public async Task InsertTextAsync(string filePath, string text, BufferRange insertRange) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/insertText", new InsertTextRequest { FilePath = filePath, @@ -62,6 +75,10 @@ public async Task InsertTextAsync(string filePath, string text, BufferRange inse public async Task SetSelectionAsync(BufferRange selectionRange) { + if (!TestHasLanguageServer()) + { + return; + }; await _languageServer.SendRequest("editor/setSelection", new SetSelectionRequest { @@ -106,11 +123,21 @@ public EditorContext ConvertClientEditorContext( public async Task NewFileAsync() { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/newFile", null); } public async Task OpenFileAsync(string filePath) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/openFile", new OpenFileDetails { FilePath = filePath, @@ -120,6 +147,11 @@ public async Task OpenFileAsync(string filePath) public async Task OpenFileAsync(string filePath, bool preview) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/openFile", new OpenFileDetails { FilePath = filePath, @@ -129,6 +161,11 @@ public async Task OpenFileAsync(string filePath, bool preview) public async Task CloseFileAsync(string filePath) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/closeFile", filePath); } @@ -139,6 +176,11 @@ public async Task SaveFileAsync(string filePath) public async Task SaveFileAsync(string currentPath, string newSavePath) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/saveFile", new SaveFileDetails { FilePath = currentPath, @@ -158,21 +200,41 @@ public string GetWorkspaceRelativePath(string filePath) public async Task ShowInformationMessageAsync(string message) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/showInformationMessage", message); } public async Task ShowErrorMessageAsync(string message) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/showErrorMessage", message); } public async Task ShowWarningMessageAsync(string message) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/showWarningMessage", message); } public async Task SetStatusBarMessageAsync(string message, int? timeout) { + if (!TestHasLanguageServer()) + { + return; + }; + await _languageServer.SendRequest("editor/setStatusBarMessage", new StatusBarMessageDetails { Message = message, @@ -182,7 +244,24 @@ public async Task SetStatusBarMessageAsync(string message, int? timeout) public void ClearTerminal() { + if (!TestHasLanguageServer()) + { + return; + }; + _languageServer.SendNotification("editor/clearTerminal"); } + + private bool TestHasLanguageServer() + { + if (_languageServer != null) + { + return true; + } + + _powerShellContextService.ExternalHost.UI.WriteWarningLine( + "Editor operations are not supported in temporary consoles. Re-run the command in the main PowerShell Intergrated Console."); + return false; + } } } diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/ExtensionService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/ExtensionService.cs index 4399a5eb9..baeffd925 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/ExtensionService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/ExtensionService.cs @@ -222,7 +222,7 @@ private void OnCommandRemoved(EditorCommand command) private void ExtensionService_ExtensionAddedAsync(object sender, EditorCommand e) { - _languageServer.SendNotification("powerShell/extensionCommandAdded", + _languageServer?.SendNotification("powerShell/extensionCommandAdded", new ExtensionCommandAddedNotification { Name = e.Name, @@ -232,7 +232,7 @@ private void ExtensionService_ExtensionAddedAsync(object sender, EditorCommand e private void ExtensionService_ExtensionUpdatedAsync(object sender, EditorCommand e) { - _languageServer.SendNotification("powerShell/extensionCommandUpdated", + _languageServer?.SendNotification("powerShell/extensionCommandUpdated", new ExtensionCommandUpdatedNotification { Name = e.Name, @@ -241,7 +241,7 @@ private void ExtensionService_ExtensionUpdatedAsync(object sender, EditorCommand private void ExtensionService_ExtensionRemovedAsync(object sender, EditorCommand e) { - _languageServer.SendNotification("powerShell/extensionCommandRemoved", + _languageServer?.SendNotification("powerShell/extensionCommandRemoved", new ExtensionCommandRemovedNotification { Name = e.Name, diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs index 037b8427f..1d7648503 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs @@ -84,7 +84,7 @@ static PowerShellContextService() private EngineIntrinsics EngineIntrinsics { get; set; } - private PSHost ExternalHost { get; set; } + internal PSHost ExternalHost { get; set; } /// /// Gets a boolean that indicates whether the debugger is currently stopped, From abf1df7fa1fb7adfecbaed144f16bbc92207e441 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 9 Jan 2020 08:05:43 -0800 Subject: [PATCH 2/2] codacy --- .../Services/PowerShellContext/EditorOperationsService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs index 1625d0f07..0c1774065 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs @@ -16,9 +16,9 @@ internal class EditorOperationsService : IEditorOperations { private const bool DefaultPreviewSetting = true; - private WorkspaceService _workspaceService; - private PowerShellContextService _powerShellContextService; - private ILanguageServer _languageServer; + private readonly WorkspaceService _workspaceService; + private readonly PowerShellContextService _powerShellContextService; + private readonly ILanguageServer _languageServer; public EditorOperationsService( WorkspaceService workspaceService, @@ -233,7 +233,7 @@ public async Task SetStatusBarMessageAsync(string message, int? timeout) if (!TestHasLanguageServer()) { return; - }; + } await _languageServer.SendRequest("editor/setStatusBarMessage", new StatusBarMessageDetails {