From adf6740579307847d4687cf2bef382e64b065e9a Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Sat, 10 Aug 2019 16:54:45 -0700 Subject: [PATCH 1/6] support $psEditor --- PowerShellEditorServices.build.ps1 | 43 ++--- .../PowerShellEditorServices.psm1 | 3 - .../Hosting/EditorServicesHost.cs | 26 ++- .../LanguageServer/OmnisharpLanguageServer.cs | 22 ++- .../PowerShellEditorServices.Engine.csproj | 2 - .../Components/ComponentRegistry.cs | 84 -------- .../Components/IComponentRegistry.cs | 61 ------ .../IComponentRegistryExtensions.cs | 87 --------- .../EditorOperationsService.cs | 182 ++++++++++++++++++ .../{Extensions => }/ExtensionService.cs | 51 ++++- .../Extensions/EditorObject.cs | 44 +++-- .../Extensions/EditorRequests.cs | 156 +++++++++++++++ .../IInvokeExtensionCommandHandler.cs | 30 +++ .../Handlers/InvokeExtensionCommandHandler.cs | 40 ++++ .../PSHostProcessAndRunspaceHandlers.cs | 7 +- .../Handlers/ConfigurationHandler.cs | 2 +- 16 files changed, 531 insertions(+), 309 deletions(-) delete mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/ComponentRegistry.cs delete mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistry.cs delete mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistryExtensions.cs create mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/EditorOperationsService.cs rename src/PowerShellEditorServices.Engine/Services/PowerShellContext/{Extensions => }/ExtensionService.cs (80%) create mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs create mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/IInvokeExtensionCommandHandler.cs create mode 100644 src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/InvokeExtensionCommandHandler.cs diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index 972a17766..9629dab9b 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -51,46 +51,27 @@ Schema is: #> $script:RequiredBuildAssets = @{ $script:ModuleBinPath = @{ - 'PowerShellEditorServices' = @( - 'publish/Serilog.dll', - 'publish/Serilog.Sinks.Async.dll', - 'publish/Serilog.Sinks.Console.dll', - 'publish/Serilog.Sinks.File.dll', - 'publish/Microsoft.Extensions.FileSystemGlobbing.dll', - 'Microsoft.PowerShell.EditorServices.dll', - 'Microsoft.PowerShell.EditorServices.pdb' - ) - - 'PowerShellEditorServices.Host' = @( - 'publish/UnixConsoleEcho.dll', - 'publish/runtimes/osx-64/native/libdisablekeyecho.dylib', - 'publish/runtimes/linux-64/native/libdisablekeyecho.so', - 'publish/Newtonsoft.Json.dll', - 'Microsoft.PowerShell.EditorServices.Host.dll', - 'Microsoft.PowerShell.EditorServices.Host.pdb' - ) - - 'PowerShellEditorServices.Protocol' = @( - 'Microsoft.PowerShell.EditorServices.Protocol.dll', - 'Microsoft.PowerShell.EditorServices.Protocol.pdb' - ) - 'PowerShellEditorServices.Engine' = @( + 'publish/Microsoft.Extensions.DependencyInjection.Abstractions.dll', + 'publish/Microsoft.Extensions.DependencyInjection.dll', + 'publish/Microsoft.Extensions.FileSystemGlobbing.dll', + 'publish/Microsoft.Extensions.Logging.Abstractions.dll', + 'publish/Microsoft.Extensions.Logging.dll', + 'publish/Microsoft.Extensions.Options.dll', + 'publish/Microsoft.Extensions.Primitives.dll', 'publish/Microsoft.PowerShell.EditorServices.Engine.dll', 'publish/Microsoft.PowerShell.EditorServices.Engine.pdb', + 'publish/Newtonsoft.Json.dll', 'publish/OmniSharp.Extensions.JsonRpc.dll', 'publish/OmniSharp.Extensions.LanguageProtocol.dll', 'publish/OmniSharp.Extensions.LanguageServer.dll', + 'publish/runtimes/linux-64/native/libdisablekeyecho.so', + 'publish/runtimes/osx-64/native/libdisablekeyecho.dylib', 'publish/Serilog.dll', 'publish/Serilog.Extensions.Logging.dll', 'publish/Serilog.Sinks.File.dll', - 'publish/Microsoft.Extensions.DependencyInjection.Abstractions.dll', - 'publish/Microsoft.Extensions.DependencyInjection.dll', - 'publish/Microsoft.Extensions.Logging.Abstractions.dll', - 'publish/Microsoft.Extensions.Logging.dll', - 'publish/Microsoft.Extensions.Options.dll', - 'publish/Microsoft.Extensions.Primitives.dll', - 'publish/System.Reactive.dll' + 'publish/System.Reactive.dll', + 'publish/UnixConsoleEcho.dll' ) } diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 2d05b73ea..431e208b9 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -10,9 +10,6 @@ if ($PSEdition -eq 'Desktop') { Microsoft.PowerShell.Utility\Add-Type -Path "$PSScriptRoot/bin/Desktop/System.Security.Principal.Windows.dll" } -Microsoft.PowerShell.Utility\Add-Type -Path "$PSScriptRoot/bin/Microsoft.PowerShell.EditorServices.dll" -Microsoft.PowerShell.Utility\Add-Type -Path "$PSScriptRoot/bin/Microsoft.PowerShell.EditorServices.Host.dll" -Microsoft.PowerShell.Utility\Add-Type -Path "$PSScriptRoot/bin/Microsoft.PowerShell.EditorServices.Protocol.dll" Microsoft.PowerShell.Utility\Add-Type -Path "$PSScriptRoot/bin/Microsoft.PowerShell.EditorServices.Engine.dll" function Start-EditorServicesHost { diff --git a/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs b/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs index 017f99a60..3615ebb86 100644 --- a/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs @@ -17,6 +17,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.PowerShell.EditorServices.Extensions; using Serilog; namespace Microsoft.PowerShell.EditorServices.Engine @@ -244,7 +245,7 @@ public void StartLanguageService( // ? (EditorServicesPSHostUserInterface)new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost) // : new ProtocolPSHostUserInterface(powerShellContext, messageSender, logger); EditorServicesPSHostUserInterface hostUserInterface = - (EditorServicesPSHostUserInterface)new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost); + new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost); EditorServicesPSHost psHost = @@ -282,14 +283,27 @@ public void StartLanguageService( .AddSingleton() .AddSingleton() .AddSingleton(powerShellContext) + .AddSingleton() + .AddSingleton( + (provider) => + { + var extensionService = new ExtensionService( + provider.GetService(), + provider.GetService()); + extensionService.InitializeAsync( + serviceProvider: provider, + editorOperations: provider.GetService()) + .Wait(); + return extensionService; + }) .AddSingleton( - (provider) => { + (provider) => + { return AnalysisService.Create( provider.GetService(), provider.GetService(), _factory.CreateLogger()); - } - ); + }); _languageServer = new OmnisharpLanguageServerBuilder(_serviceCollection) { @@ -303,10 +317,6 @@ public void StartLanguageService( _logger.LogInformation("Starting language server"); Task.Run(_languageServer.StartAsync); - //Task.Factory.StartNew(() => _languageServer.StartAsync(), - // CancellationToken.None, - // TaskCreationOptions.LongRunning, - // TaskScheduler.Default); _logger.LogInformation( string.Format( diff --git a/src/PowerShellEditorServices.Engine/LanguageServer/OmnisharpLanguageServer.cs b/src/PowerShellEditorServices.Engine/LanguageServer/OmnisharpLanguageServer.cs index ccf221008..3bbf26dff 100644 --- a/src/PowerShellEditorServices.Engine/LanguageServer/OmnisharpLanguageServer.cs +++ b/src/PowerShellEditorServices.Engine/LanguageServer/OmnisharpLanguageServer.cs @@ -14,6 +14,7 @@ using OmniSharp.Extensions.LanguageServer.Server; using PowerShellEditorServices.Engine.Services.Handlers; using Microsoft.PowerShell.EditorServices.TextDocument; +using System.IO; namespace Microsoft.PowerShell.EditorServices.Engine { @@ -95,7 +96,26 @@ public async Task StartAsync() .WithHandler() .WithHandler() .WithHandler() - .WithHandler(); + .WithHandler() + .WithHandler() + .OnInitialize( + async (languageServer, request) => + { + var serviceProvider = languageServer.Services; + var workspaceService = serviceProvider.GetService(); + + // Grab the workspace path from the parameters + workspaceService.WorkspacePath = request.RootPath; + + // Set the working directory of the PowerShell session to the workspace path + if (workspaceService.WorkspacePath != null + && Directory.Exists(workspaceService.WorkspacePath)) + { + await serviceProvider.GetService().SetWorkingDirectoryAsync( + workspaceService.WorkspacePath, + isPathAlreadyEscaped: false); + } + }); logger.LogInformation("Handlers added"); }); diff --git a/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj b/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj index a7d6b35ca..0b034b8d4 100644 --- a/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj +++ b/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj @@ -28,7 +28,6 @@ - @@ -36,6 +35,5 @@ - diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/ComponentRegistry.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/ComponentRegistry.cs deleted file mode 100644 index 9a1de6d01..000000000 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/ComponentRegistry.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.PowerShell.EditorServices.Components -{ - /// - /// Provides a default implementation for the IComponentRegistry - /// interface. - /// - public class ComponentRegistry : IComponentRegistry - { - private Dictionary componentRegistry = - new Dictionary(); - - /// - /// Registers an instance of the specified component type - /// or throws an ArgumentException if an instance has - /// already been registered. - /// - /// - /// The component type that the instance represents. - /// - /// - /// The instance of the component to be registered. - /// - /// - /// The provided component instance for convenience in assignment - /// statements. - /// - public object Register(Type componentType, object componentInstance) - { - this.componentRegistry.Add(componentType, componentInstance); - return componentInstance; - } - - - /// - /// Gets the registered instance of the specified - /// component type or throws a KeyNotFoundException if - /// no instance has been registered. - /// - /// - /// The component type for which an instance will be retrieved. - /// - /// The implementation of the specified type. - public object Get(Type componentType) - { - return this.componentRegistry[componentType]; - } - - /// - /// Attempts to retrieve the instance of the specified - /// component type and, if found, stores it in the - /// componentInstance parameter. - /// - /// - /// The out parameter in which the found instance will be stored. - /// - /// - /// The component type for which an instance will be retrieved. - /// - /// - /// True if a registered instance was found, false otherwise. - /// - public bool TryGet(Type componentType, out object componentInstance) - { - componentInstance = null; - - if (this.componentRegistry.TryGetValue(componentType, out componentInstance)) - { - return componentInstance != null; - } - - return false; - } - } -} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistry.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistry.cs deleted file mode 100644 index c9f99000f..000000000 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistry.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; - -namespace Microsoft.PowerShell.EditorServices.Components -{ - /// - /// Specifies the contract for a registry of component interfaces. - /// - public interface IComponentRegistry - { - /// - /// Registers an instance of the specified component type - /// or throws an ArgumentException if an instance has - /// already been registered. - /// - /// - /// The component type that the instance represents. - /// - /// - /// The instance of the component to be registered. - /// - /// - /// The provided component instance for convenience in assignment - /// statements. - /// - object Register( - Type componentType, - object componentInstance); - - /// - /// Gets the registered instance of the specified - /// component type or throws a KeyNotFoundException if - /// no instance has been registered. - /// - /// - /// The component type for which an instance will be retrieved. - /// - /// The implementation of the specified type. - object Get(Type componentType); - - /// - /// Attempts to retrieve the instance of the specified - /// component type and, if found, stores it in the - /// componentInstance parameter. - /// - /// - /// The component type for which an instance will be retrieved. - /// - /// - /// The out parameter in which the found instance will be stored. - /// - /// - /// True if a registered instance was found, false otherwise. - /// - bool TryGet(Type componentType, out object componentInstance); - } -} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistryExtensions.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistryExtensions.cs deleted file mode 100644 index 0c6307d5a..000000000 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Components/IComponentRegistryExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.PowerShell.EditorServices.Components -{ - /// - /// Provides generic helper methods for working with IComponentRegistry - /// methods. - /// - public static class IComponentRegistryExtensions - { - /// - /// Registers an instance of the specified component type - /// or throws an ArgumentException if an instance has - /// already been registered. - /// - /// - /// The IComponentRegistry instance. - /// - /// - /// The instance of the component to be registered. - /// - /// - /// The provided component instance for convenience in assignment - /// statements. - /// - public static TComponent Register( - this IComponentRegistry componentRegistry, - TComponent componentInstance) - where TComponent : class - { - return - (TComponent)componentRegistry.Register( - typeof(TComponent), - componentInstance); - } - - /// - /// Gets the registered instance of the specified - /// component type or throws a KeyNotFoundException if - /// no instance has been registered. - /// - /// - /// The IComponentRegistry instance. - /// - /// The implementation of the specified type. - public static TComponent Get( - this IComponentRegistry componentRegistry) - where TComponent : class - { - return (TComponent)componentRegistry.Get(typeof(TComponent)); - } - - /// - /// Attempts to retrieve the instance of the specified - /// component type and, if found, stores it in the - /// componentInstance parameter. - /// - /// - /// The IComponentRegistry instance. - /// - /// - /// The out parameter in which the found instance will be stored. - /// - /// - /// True if a registered instance was found, false otherwise. - /// - public static bool TryGet( - this IComponentRegistry componentRegistry, - out TComponent componentInstance) - where TComponent : class - { - object componentObject = null; - componentInstance = null; - - if (componentRegistry.TryGet(typeof(TComponent), out componentObject)) - { - componentInstance = componentObject as TComponent; - return componentInstance != null; - } - - return false; - } - } -} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/EditorOperationsService.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/EditorOperationsService.cs new file mode 100644 index 000000000..6d651acde --- /dev/null +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/EditorOperationsService.cs @@ -0,0 +1,182 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.PowerShell.EditorServices.Protocol.LanguageServer; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using PowerShellEditorServices.Engine.Services.Handlers; +using System.Threading.Tasks; + +namespace Microsoft.PowerShell.EditorServices.Extensions +{ + internal class EditorOperationsService : IEditorOperations + { + private const bool DefaultPreviewSetting = true; + + private WorkspaceService _workspaceService; + private ILanguageServer _languageServer; + + public EditorOperationsService( + WorkspaceService workspaceService, + ILanguageServer languageServer) + { + this._workspaceService = workspaceService; + this._languageServer = languageServer; + } + + public async Task GetEditorContextAsync() + { + ClientEditorContext clientContext = + await _languageServer.SendRequest( + "editor/getEditorContext", + new GetEditorContextRequest()); + + return this.ConvertClientEditorContext(clientContext); + } + + public async Task InsertTextAsync(string filePath, string text, BufferRange insertRange) + { + await _languageServer.SendRequest("editor/insertText", new InsertTextRequest + { + FilePath = filePath, + InsertText = text, + InsertRange = + new Range + { + Start = new Position + { + Line = insertRange.Start.Line - 1, + Character = insertRange.Start.Column - 1 + }, + End = new Position + { + Line = insertRange.End.Line - 1, + Character = insertRange.End.Column - 1 + } + } + }); + } + + public async Task SetSelectionAsync(BufferRange selectionRange) + { + + await _languageServer.SendRequest("editor/setSelection", new SetSelectionRequest + { + SelectionRange = + new Range + { + Start = new Position + { + Line = selectionRange.Start.Line - 1, + Character = selectionRange.Start.Column - 1 + }, + End = new Position + { + Line = selectionRange.End.Line - 1, + Character = selectionRange.End.Column - 1 + } + } + }); + } + + public EditorContext ConvertClientEditorContext( + ClientEditorContext clientContext) + { + ScriptFile scriptFile = _workspaceService.CreateScriptFileFromFileBuffer( + clientContext.CurrentFilePath, + clientContext.CurrentFileContent); + + return + new EditorContext( + this, + scriptFile, + new BufferPosition( + (int) clientContext.CursorPosition.Line + 1, + (int) clientContext.CursorPosition.Character + 1), + new BufferRange( + (int) clientContext.SelectionRange.Start.Line + 1, + (int) clientContext.SelectionRange.Start.Character + 1, + (int) clientContext.SelectionRange.End.Line + 1, + (int) clientContext.SelectionRange.End.Character + 1), + clientContext.CurrentFileLanguage); + } + + public async Task NewFileAsync() + { + await _languageServer.SendRequest("editor/newFile", null); + } + + public async Task OpenFileAsync(string filePath) + { + await _languageServer.SendRequest("editor/openFile", new OpenFileDetails + { + FilePath = filePath, + Preview = DefaultPreviewSetting + }); + } + + public async Task OpenFileAsync(string filePath, bool preview) + { + await _languageServer.SendRequest("editor/openFile", new OpenFileDetails + { + FilePath = filePath, + Preview = preview + }); + } + + public async Task CloseFileAsync(string filePath) + { + await _languageServer.SendRequest("editor/closeFile", filePath); + } + + public async Task SaveFileAsync(string filePath) + { + await SaveFileAsync(filePath, null); + } + + public async Task SaveFileAsync(string currentPath, string newSavePath) + { + await _languageServer.SendRequest("editor/saveFile", new SaveFileDetails + { + FilePath = currentPath, + NewPath = newSavePath + }); + } + + public string GetWorkspacePath() + { + return _workspaceService.WorkspacePath; + } + + public string GetWorkspaceRelativePath(string filePath) + { + return _workspaceService.GetRelativePath(filePath); + } + + public async Task ShowInformationMessageAsync(string message) + { + await _languageServer.SendRequest("editor/showInformationMessage", message); + } + + public async Task ShowErrorMessageAsync(string message) + { + await _languageServer.SendRequest("editor/showErrorMessage", message); + } + + public async Task ShowWarningMessageAsync(string message) + { + await _languageServer.SendRequest("editor/showWarningMessage", message); + } + + public async Task SetStatusBarMessageAsync(string message, int? timeout) + { + await _languageServer.SendRequest("editor/setStatusBarMessage", new StatusBarMessageDetails + { + Message = message, + Timeout = timeout + }); + } + } +} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/ExtensionService.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/ExtensionService.cs similarity index 80% rename from src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/ExtensionService.cs rename to src/PowerShellEditorServices.Engine/Services/PowerShellContext/ExtensionService.cs index b96ac9e12..8ecc19300 100644 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/ExtensionService.cs +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/ExtensionService.cs @@ -3,7 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.PowerShell.EditorServices.Components; +using Microsoft.PowerShell.EditorServices.Protocol.LanguageServer; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; using System; using System.Collections.Generic; using System.Management.Automation; @@ -22,6 +23,8 @@ public class ExtensionService private Dictionary editorCommands = new Dictionary(); + private readonly ILanguageServer _languageServer; + #endregion #region Properties @@ -52,9 +55,10 @@ public class ExtensionService /// PowerShellContext for loading and executing extension code. /// /// A PowerShellContext used to execute extension code. - public ExtensionService(PowerShellContextService powerShellContext) + public ExtensionService(PowerShellContextService powerShellContext, ILanguageServer languageServer) { this.PowerShellContext = powerShellContext; + _languageServer = languageServer; } #endregion @@ -66,17 +70,21 @@ public ExtensionService(PowerShellContextService powerShellContext) /// implementation for future interaction with the host editor. /// /// An IEditorOperations implementation. - /// An IComponentRegistry instance which provides components in the session. /// A Task that can be awaited for completion. public async Task InitializeAsync( - IEditorOperations editorOperations, - IComponentRegistry componentRegistry) + IServiceProvider serviceProvider, + IEditorOperations editorOperations) { + // Attach to ExtensionService events + this.CommandAdded += ExtensionService_ExtensionAddedAsync; + this.CommandUpdated += ExtensionService_ExtensionUpdatedAsync; + this.CommandRemoved += ExtensionService_ExtensionRemovedAsync; + this.EditorObject = new EditorObject( + serviceProvider, this, - editorOperations, - componentRegistry); + editorOperations); // Register the editor object in the runspace PSCommand variableCommand = new PSCommand(); @@ -177,6 +185,7 @@ public EditorCommand[] GetCommands() this.editorCommands.Values.CopyTo(commands,0); return commands; } + #endregion #region Events @@ -211,6 +220,34 @@ private void OnCommandRemoved(EditorCommand command) this.CommandRemoved?.Invoke(this, command); } + private void ExtensionService_ExtensionAddedAsync(object sender, EditorCommand e) + { + _languageServer.SendNotification("powerShell/extensionCommandAdded", + new ExtensionCommandAddedNotification + { + Name = e.Name, + DisplayName = e.DisplayName + }); + } + + private void ExtensionService_ExtensionUpdatedAsync(object sender, EditorCommand e) + { + _languageServer.SendNotification("powerShell/extensionCommandUpdated", + new ExtensionCommandUpdatedNotification + { + Name = e.Name, + }); + } + + private void ExtensionService_ExtensionRemovedAsync(object sender, EditorCommand e) + { + _languageServer.SendNotification("powerShell/extensionCommandRemoved", + new ExtensionCommandRemovedNotification + { + Name = e.Name, + }); + } + #endregion } } diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorObject.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorObject.cs index 39da959cf..44a72a6c8 100644 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorObject.cs +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorObject.cs @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.PowerShell.EditorServices.Components; using System; using System.Reflection; @@ -17,8 +16,9 @@ public class EditorObject { #region Private Fields - private ExtensionService extensionService; - private IEditorOperations editorOperations; + private readonly IServiceProvider _serviceProvider; + private readonly ExtensionService _extensionService; + private readonly IEditorOperations _editorOperations; #endregion @@ -42,12 +42,6 @@ public Version EditorServicesVersion /// public EditorWindow Window { get; private set; } - /// - /// Gets the component registry for the session. - /// - /// - public IComponentRegistry Components { get; private set; } - #endregion /// @@ -55,19 +49,18 @@ public Version EditorServicesVersion /// /// An ExtensionService which handles command registration. /// An IEditorOperations implementation which handles operations in the host editor. - /// An IComponentRegistry instance which provides components in the session. public EditorObject( + IServiceProvider serviceProvider, ExtensionService extensionService, - IEditorOperations editorOperations, - IComponentRegistry componentRegistry) + IEditorOperations editorOperations) { - this.extensionService = extensionService; - this.editorOperations = editorOperations; - this.Components = componentRegistry; + this._serviceProvider = serviceProvider; + this._extensionService = extensionService; + this._editorOperations = editorOperations; // Create API area objects - this.Workspace = new EditorWorkspace(this.editorOperations); - this.Window = new EditorWindow(this.editorOperations); + this.Workspace = new EditorWorkspace(this._editorOperations); + this.Window = new EditorWindow(this._editorOperations); } /// @@ -77,7 +70,7 @@ public EditorObject( /// True if the command is newly registered, false if the command already exists. public bool RegisterCommand(EditorCommand editorCommand) { - return this.extensionService.RegisterCommand(editorCommand); + return this._extensionService.RegisterCommand(editorCommand); } /// @@ -86,7 +79,7 @@ public bool RegisterCommand(EditorCommand editorCommand) /// The name of the command to be unregistered. public void UnregisterCommand(string commandName) { - this.extensionService.UnregisterCommand(commandName); + this._extensionService.UnregisterCommand(commandName); } /// @@ -95,7 +88,7 @@ public void UnregisterCommand(string commandName) /// An Array of all registered EditorCommands. public EditorCommand[] GetCommands() { - return this.extensionService.GetCommands(); + return this._extensionService.GetCommands(); } /// /// Gets the EditorContext which contains the state of the editor @@ -104,7 +97,16 @@ public EditorCommand[] GetCommands() /// A instance of the EditorContext class. public EditorContext GetEditorContext() { - return this.editorOperations.GetEditorContextAsync().Result; + return this._editorOperations.GetEditorContextAsync().Result; + } + + /// + /// Get's the desired service which allows for advanced control of PowerShellEditorServices. + /// + /// The singleton service object of the type requested. + public object GetService(Type type) + { + return _serviceProvider.GetService(type); } } } diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs new file mode 100644 index 000000000..488ef01e4 --- /dev/null +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs @@ -0,0 +1,156 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + +namespace Microsoft.PowerShell.EditorServices.Protocol.LanguageServer +{ + public class ExtensionCommandAddedNotification + { + //public static readonly + // NotificationType Type = + // NotificationType.Create("powerShell/extensionCommandAdded"); + + public string Name { get; set; } + + public string DisplayName { get; set; } + } + + public class ExtensionCommandUpdatedNotification + { + //public static readonly + // NotificationType Type = + // NotificationType.Create("powerShell/extensionCommandUpdated"); + + public string Name { get; set; } + } + + public class ExtensionCommandRemovedNotification + { + //public static readonly + // NotificationType Type = + // NotificationType.Create("powerShell/extensionCommandRemoved"); + + public string Name { get; set; } + } + + + public class GetEditorContextRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/getEditorContext"); + } + + public enum EditorCommandResponse + { + Unsupported, + OK + } + + public class InsertTextRequest + { + public string FilePath { get; set; } + + public string InsertText { get; set; } + + public Range InsertRange { get; set; } + } + + public class SetSelectionRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/setSelection"); + + public Range SelectionRange { get; set; } + } + + public class SetCursorPositionRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/setCursorPosition"); + + public Position CursorPosition { get; set; } + } + + public class NewFileRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/newFile"); + } + + public class OpenFileRequest + { + //public static readonly + //RequestType Type = + // RequestType.Create("editor/openFile"); + } + + public class OpenFileDetails + { + public string FilePath { get; set; } + + public bool Preview { get; set; } + } + + public class CloseFileRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/closeFile"); + } + + public class SaveFileRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/saveFile"); + } + + public class SaveFileDetails + { + public string FilePath { get; set; } + + public string NewPath { get; set; } + } + + public class ShowInformationMessageRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/showInformationMessage"); + } + + public class ShowWarningMessageRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/showWarningMessage"); + } + + public class ShowErrorMessageRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/showErrorMessage"); + } + + public class SetStatusBarMessageRequest + { + //public static readonly + // RequestType Type = + // RequestType.Create("editor/setStatusBarMessage"); + } + + public class StatusBarMessageDetails + { + public string Message { get; set; } + + public int? Timeout { get; set; } + } +} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/IInvokeExtensionCommandHandler.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/IInvokeExtensionCommandHandler.cs new file mode 100644 index 000000000..e44825c95 --- /dev/null +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/IInvokeExtensionCommandHandler.cs @@ -0,0 +1,30 @@ +using OmniSharp.Extensions.Embedded.MediatR; +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + +namespace PowerShellEditorServices.Engine.Services.Handlers +{ + [Serial, Method("powerShell/invokeExtensionCommand")] + public interface IInvokeExtensionCommandHandler : IJsonRpcNotificationHandler { } + + public class InvokeExtensionCommandParams : IRequest + { + public string Name { get; set; } + + public ClientEditorContext Context { get; set; } + } + + public class ClientEditorContext + { + public string CurrentFileContent { get; set; } + + public string CurrentFileLanguage { get; set; } + + public string CurrentFilePath { get; set; } + + public Position CursorPosition { get; set; } + + public Range SelectionRange { get; set; } + + } +} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/InvokeExtensionCommandHandler.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/InvokeExtensionCommandHandler.cs new file mode 100644 index 000000000..fee04ff84 --- /dev/null +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/InvokeExtensionCommandHandler.cs @@ -0,0 +1,40 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.PowerShell.EditorServices.Extensions; +using OmniSharp.Extensions.Embedded.MediatR; + +namespace PowerShellEditorServices.Engine.Services.Handlers +{ + internal class InvokeExtensionCommandHandler : IInvokeExtensionCommandHandler + { + private readonly ILogger _logger; + private readonly ExtensionService _extensionService; + private readonly EditorOperationsService _editorOperationsService; + + public InvokeExtensionCommandHandler( + ILoggerFactory factory, + ExtensionService extensionService, + EditorOperationsService editorOperationsService + ) + { + _logger = factory.CreateLogger(); + _extensionService = extensionService; + _editorOperationsService = editorOperationsService; + } + + public async Task Handle(InvokeExtensionCommandParams request, CancellationToken cancellationToken) + { + // We can now await here because we handle asynchronous message handling. + EditorContext editorContext = + _editorOperationsService.ConvertClientEditorContext( + request.Context); + + await _extensionService.InvokeCommandAsync( + request.Name, + editorContext); + + return await Unit.Task; + } + } +} diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs index b24e2c7aa..1171d3a57 100644 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs @@ -55,7 +55,8 @@ public Task Handle(GetRunspaceParams request, CancellationTo { IEnumerable runspaces = null; - if (request.ProcessId == null) { + if (request.ProcessId == null) + { request.ProcessId = "current"; } @@ -64,8 +65,8 @@ public Task Handle(GetRunspaceParams request, CancellationTo if (int.TryParse(request.ProcessId, out int pid)) { // Create a remote runspace that we will invoke Get-Runspace in. - using(var rs = RunspaceFactory.CreateRunspace(new NamedPipeConnectionInfo(pid))) - using(var ps = PowerShell.Create()) + using (var rs = RunspaceFactory.CreateRunspace(new NamedPipeConnectionInfo(pid))) + using (var ps = PowerShell.Create()) { rs.Open(); ps.Runspace = rs; diff --git a/src/PowerShellEditorServices.Engine/Services/Workspace/Handlers/ConfigurationHandler.cs b/src/PowerShellEditorServices.Engine/Services/Workspace/Handlers/ConfigurationHandler.cs index 652bb9ce4..c22ea8d90 100644 --- a/src/PowerShellEditorServices.Engine/Services/Workspace/Handlers/ConfigurationHandler.cs +++ b/src/PowerShellEditorServices.Engine/Services/Workspace/Handlers/ConfigurationHandler.cs @@ -47,7 +47,7 @@ public async Task Handle(DidChangeConfigurationParams request, Cancellatio { return await Unit.Task; } - // TODO ADD THIS BACK IN + bool oldLoadProfiles = _configurationService.CurrentSettings.EnableProfileLoading; bool oldScriptAnalysisEnabled = _configurationService.CurrentSettings.ScriptAnalysis.Enable ?? false; From 07ae2c228f1f599a2b0cf268d6e63d98c20c834c Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Sat, 10 Aug 2019 17:11:29 -0700 Subject: [PATCH 2/6] deleted commented out code --- .../Extensions/EditorRequests.cs | 82 +------------------ 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs index 488ef01e4..38e5c80f8 100644 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Extensions/EditorRequests.cs @@ -9,10 +9,6 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.LanguageServer { public class ExtensionCommandAddedNotification { - //public static readonly - // NotificationType Type = - // NotificationType.Create("powerShell/extensionCommandAdded"); - public string Name { get; set; } public string DisplayName { get; set; } @@ -20,29 +16,17 @@ public class ExtensionCommandAddedNotification public class ExtensionCommandUpdatedNotification { - //public static readonly - // NotificationType Type = - // NotificationType.Create("powerShell/extensionCommandUpdated"); - public string Name { get; set; } } public class ExtensionCommandRemovedNotification { - //public static readonly - // NotificationType Type = - // NotificationType.Create("powerShell/extensionCommandRemoved"); - public string Name { get; set; } } public class GetEditorContextRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/getEditorContext"); - } + {} public enum EditorCommandResponse { @@ -61,36 +45,14 @@ public class InsertTextRequest public class SetSelectionRequest { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/setSelection"); - public Range SelectionRange { get; set; } } public class SetCursorPositionRequest { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/setCursorPosition"); - public Position CursorPosition { get; set; } } - public class NewFileRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/newFile"); - } - - public class OpenFileRequest - { - //public static readonly - //RequestType Type = - // RequestType.Create("editor/openFile"); - } - public class OpenFileDetails { public string FilePath { get; set; } @@ -98,20 +60,6 @@ public class OpenFileDetails public bool Preview { get; set; } } - public class CloseFileRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/closeFile"); - } - - public class SaveFileRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/saveFile"); - } - public class SaveFileDetails { public string FilePath { get; set; } @@ -119,34 +67,6 @@ public class SaveFileDetails public string NewPath { get; set; } } - public class ShowInformationMessageRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/showInformationMessage"); - } - - public class ShowWarningMessageRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/showWarningMessage"); - } - - public class ShowErrorMessageRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/showErrorMessage"); - } - - public class SetStatusBarMessageRequest - { - //public static readonly - // RequestType Type = - // RequestType.Create("editor/setStatusBarMessage"); - } - public class StatusBarMessageDetails { public string Message { get; set; } From 96c1cfb47cfeec20ccbef064475ee42c35c63c4f Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 12 Aug 2019 09:22:00 -0700 Subject: [PATCH 3/6] fix initial build failures due to lack of certain assemblies --- tools/PsesPsClient/PsesPsClient.psd1 | 5 ++++- tools/PsesPsClient/build.ps1 | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/PsesPsClient/PsesPsClient.psd1 b/tools/PsesPsClient/PsesPsClient.psd1 index 34c3921fe..2d1f65aaa 100644 --- a/tools/PsesPsClient/PsesPsClient.psd1 +++ b/tools/PsesPsClient/PsesPsClient.psd1 @@ -54,7 +54,10 @@ PowerShellVersion = '5.1' # RequiredModules = @() # Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() +RequiredAssemblies = @( + 'Microsoft.PowerShell.EditorServices.dll' + 'Microsoft.PowerShell.EditorServices.Protocol.dll' +) # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() diff --git a/tools/PsesPsClient/build.ps1 b/tools/PsesPsClient/build.ps1 index a9da9a778..82874ab3e 100644 --- a/tools/PsesPsClient/build.ps1 +++ b/tools/PsesPsClient/build.ps1 @@ -19,6 +19,8 @@ $script:ModuleComponents = @{ "bin/Debug/netstandard2.0/publish/Newtonsoft.Json.dll" = "Newtonsoft.Json.dll" "PsesPsClient.psm1" = "PsesPsClient.psm1" "PsesPsClient.psd1" = "PsesPsClient.psd1" + "bin/Debug/netstandard2.0/Microsoft.PowerShell.EditorServices.Protocol.dll" = "Microsoft.PowerShell.EditorServices.Protocol.dll" + "bin/Debug/netstandard2.0/Microsoft.PowerShell.EditorServices.dll" = "Microsoft.PowerShell.EditorServices.dll" } $binDir = "$PSScriptRoot/bin" From 8006acf933354c71dac8c344004f4e4f91ae1352 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 12 Aug 2019 14:25:06 -0700 Subject: [PATCH 4/6] use different RootPath --- .../PSHostProcessAndRunspaceHandlers.cs | 19 +++++++++++-------- .../Services/Symbols/SymbolsService.cs | 4 ---- .../EditorServices.Integration.Tests.ps1 | 4 ++-- tools/PsesPsClient/PsesPsClient.psm1 | 1 + 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs index 1171d3a57..52b8b3411 100644 --- a/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs +++ b/src/PowerShellEditorServices.Engine/Services/PowerShellContext/Handlers/PSHostProcessAndRunspaceHandlers.cs @@ -1,19 +1,23 @@ using System.Collections.Generic; using System.Management.Automation; using System.Management.Automation.Runspaces; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.PowerShell.EditorServices; namespace PowerShellEditorServices.Engine.Services.Handlers { public class PSHostProcessAndRunspaceHandlers : IGetPSHostProcessesHandler, IGetRunspaceHandler { private readonly ILogger _logger; + private readonly PowerShellContextService _powerShellContextService; - public PSHostProcessAndRunspaceHandlers(ILoggerFactory factory) + public PSHostProcessAndRunspaceHandlers(ILoggerFactory factory, PowerShellContextService powerShellContextService) { _logger = factory.CreateLogger(); + _powerShellContextService = powerShellContextService; } public Task Handle(GetPSHostProcesssesParams request, CancellationToken cancellationToken) @@ -51,7 +55,7 @@ public Task Handle(GetPSHostProcesssesParams request, C return Task.FromResult(psHostProcesses.ToArray()); } - public Task Handle(GetRunspaceParams request, CancellationToken cancellationToken) + public async Task Handle(GetRunspaceParams request, CancellationToken cancellationToken) { IEnumerable runspaces = null; @@ -76,11 +80,10 @@ public Task Handle(GetRunspaceParams request, CancellationTo } else { - // TODO: Bring back - // var psCommand = new PSCommand().AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace"); - // var sb = new StringBuilder(); - // // returns (not deserialized) Runspaces. For simpler code, we use PSObject and rely on dynamic later. - // runspaces = await editorSession.PowerShellContext.ExecuteCommandAsync(psCommand, sb); + var psCommand = new PSCommand().AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace"); + var sb = new StringBuilder(); + // returns (not deserialized) Runspaces. For simpler code, we use PSObject and rely on dynamic later. + runspaces = await _powerShellContextService.ExecuteCommandAsync(psCommand, sb); } var runspaceResponses = new List(); @@ -99,7 +102,7 @@ public Task Handle(GetRunspaceParams request, CancellationTo } } - return Task.FromResult(runspaceResponses.ToArray()); + return runspaceResponses.ToArray(); } } } diff --git a/src/PowerShellEditorServices.Engine/Services/Symbols/SymbolsService.cs b/src/PowerShellEditorServices.Engine/Services/Symbols/SymbolsService.cs index 92508adb2..468bfb62e 100644 --- a/src/PowerShellEditorServices.Engine/Services/Symbols/SymbolsService.cs +++ b/src/PowerShellEditorServices.Engine/Services/Symbols/SymbolsService.cs @@ -118,10 +118,6 @@ public List FindReferencesOfSymbol( return null; } - int symbolOffset = referencedFiles[0].GetOffsetAtPosition( - foundSymbol.ScriptRegion.StartLineNumber, - foundSymbol.ScriptRegion.StartColumnNumber); - // NOTE: we use to make sure aliases were loaded but took it out because we needed the pipeline thread. // We want to look for references first in referenced files, hence we use ordered dictionary diff --git a/test/Pester/EditorServices.Integration.Tests.ps1 b/test/Pester/EditorServices.Integration.Tests.ps1 index edc53f684..1054c8268 100644 --- a/test/Pester/EditorServices.Integration.Tests.ps1 +++ b/test/Pester/EditorServices.Integration.Tests.ps1 @@ -98,7 +98,8 @@ Describe "Loading and running PowerShellEditorServices" { # This test MUST be first It "Starts and responds to an initialization request" { - $request = Send-LspInitializeRequest -Client $client + $startDir = New-Item -ItemType Directory TestDrive:\start + $request = Send-LspInitializeRequest -Client $client -RootPath ($startDir.FullName) $response = Get-LspResponse -Client $client -Id $request.Id #-WaitMillis 99999 $response.Id | Should -BeExactly $request.Id @@ -301,7 +302,6 @@ Get-Bar -Uri ([Uri]::new($filePath).AbsoluteUri) ` -LineNumber 5 ` -CharacterNumber 0 - $response = Get-LspResponse -Client $client -Id $request.Id $response.Result.Count | Should -BeExactly 2 diff --git a/tools/PsesPsClient/PsesPsClient.psm1 b/tools/PsesPsClient/PsesPsClient.psm1 index 099007ad9..b9eb52cde 100644 --- a/tools/PsesPsClient/PsesPsClient.psm1 +++ b/tools/PsesPsClient/PsesPsClient.psm1 @@ -160,6 +160,7 @@ function Start-PsesServer } $serverProcess = Start-Process @startProcParams + # $job = Start-Job -ScriptBlock ([scriptblock]::Create($startPsesCommand)) $sessionPath = $editorServicesOptions.SessionDetailsPath From e9e9807463b4584e29c9635bc51d9234adb77a2e Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 12 Aug 2019 14:39:32 -0700 Subject: [PATCH 5/6] wait an extra 5 seconds just in case --- tools/PsesPsClient/PsesPsClient.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PsesPsClient/PsesPsClient.psm1 b/tools/PsesPsClient/PsesPsClient.psm1 index b9eb52cde..7c4df1381 100644 --- a/tools/PsesPsClient/PsesPsClient.psm1 +++ b/tools/PsesPsClient/PsesPsClient.psm1 @@ -682,7 +682,7 @@ function Get-LspResponse [Parameter()] [int] - $WaitMillis = 5000 + $WaitMillis = 10000 ) $lspResponse = $null From 19c78b2dcc310c7f46c813da6712f89ba2659ae0 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 12 Aug 2019 15:09:09 -0700 Subject: [PATCH 6/6] refactor initialize script --- .../Hosting/EditorServicesHost.cs | 93 ++++++++++--------- .../PowerShellEditorServices.Engine.csproj | 5 - tools/PsesPsClient/PsesPsClient.psm1 | 1 - 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs b/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs index 3615ebb86..f67f28c08 100644 --- a/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Engine/Hosting/EditorServicesHost.cs @@ -234,49 +234,7 @@ public void StartLanguageService( _logger.LogInformation($"LSP NamedPipe: {config.InOutPipeName}\nLSP OutPipe: {config.OutPipeName}"); - var logger = _factory.CreateLogger(); - var powerShellContext = new PowerShellContextService( - logger, - _featureFlags.Contains("PSReadLine")); - - // TODO: Bring this back - //EditorServicesPSHostUserInterface hostUserInterface = - // _enableConsoleRepl - // ? (EditorServicesPSHostUserInterface)new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost) - // : new ProtocolPSHostUserInterface(powerShellContext, messageSender, logger); - EditorServicesPSHostUserInterface hostUserInterface = - new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost); - - - EditorServicesPSHost psHost = - new EditorServicesPSHost( - powerShellContext, - _hostDetails, - hostUserInterface, - logger); - - Runspace initialRunspace = PowerShellContextService.CreateRunspace(psHost); - powerShellContext.Initialize(profilePaths, initialRunspace, true, hostUserInterface); - - powerShellContext.ImportCommandsModuleAsync( - Path.Combine( - Path.GetDirectoryName(this.GetType().GetTypeInfo().Assembly.Location), - @"..\Commands")); - - // TODO: This can be moved to the point after the $psEditor object - // gets initialized when that is done earlier than LanguageServer.Initialize - foreach (string module in this._additionalModules) - { - var command = - new System.Management.Automation.PSCommand() - .AddCommand("Microsoft.PowerShell.Core\\Import-Module") - .AddParameter("Name", module); - - powerShellContext.ExecuteCommandAsync( - command, - sendOutputToHost: false, - sendErrorToHost: true); - } + var powerShellContext = GetFullyInitializedPowerShellContext(profilePaths); _serviceCollection .AddSingleton() @@ -324,6 +282,55 @@ public void StartLanguageService( config.TransportType, config.Endpoint)); } + private PowerShellContextService GetFullyInitializedPowerShellContext(ProfilePaths profilePaths) + { + var logger = _factory.CreateLogger(); + var powerShellContext = new PowerShellContextService( + logger, + _featureFlags.Contains("PSReadLine")); + + // TODO: Bring this back + //EditorServicesPSHostUserInterface hostUserInterface = + // _enableConsoleRepl + // ? (EditorServicesPSHostUserInterface)new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost) + // : new ProtocolPSHostUserInterface(powerShellContext, messageSender, logger); + EditorServicesPSHostUserInterface hostUserInterface = + new TerminalPSHostUserInterface(powerShellContext, logger, _internalHost); + + + EditorServicesPSHost psHost = + new EditorServicesPSHost( + powerShellContext, + _hostDetails, + hostUserInterface, + logger); + + Runspace initialRunspace = PowerShellContextService.CreateRunspace(psHost); + powerShellContext.Initialize(profilePaths, initialRunspace, true, hostUserInterface); + + powerShellContext.ImportCommandsModuleAsync( + Path.Combine( + Path.GetDirectoryName(this.GetType().GetTypeInfo().Assembly.Location), + @"..\Commands")); + + // TODO: This can be moved to the point after the $psEditor object + // gets initialized when that is done earlier than LanguageServer.Initialize + foreach (string module in this._additionalModules) + { + var command = + new PSCommand() + .AddCommand("Microsoft.PowerShell.Core\\Import-Module") + .AddParameter("Name", module); + + powerShellContext.ExecuteCommandAsync( + command, + sendOutputToHost: false, + sendErrorToHost: true); + } + + return powerShellContext; + } + /// /// Starts the debug service with the specified config. /// diff --git a/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj b/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj index 0b034b8d4..3c219d986 100644 --- a/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj +++ b/src/PowerShellEditorServices.Engine/PowerShellEditorServices.Engine.csproj @@ -31,9 +31,4 @@ - - - - - diff --git a/tools/PsesPsClient/PsesPsClient.psm1 b/tools/PsesPsClient/PsesPsClient.psm1 index 7c4df1381..132e912a5 100644 --- a/tools/PsesPsClient/PsesPsClient.psm1 +++ b/tools/PsesPsClient/PsesPsClient.psm1 @@ -160,7 +160,6 @@ function Start-PsesServer } $serverProcess = Start-Process @startProcParams - # $job = Start-Job -ScriptBlock ([scriptblock]::Create($startPsesCommand)) $sessionPath = $editorServicesOptions.SessionDetailsPath