Skip to content

Commit b956202

Browse files
committed
Finally get the REPL and completions back
1 parent 4a978d4 commit b956202

File tree

6 files changed

+72
-49
lines changed

6 files changed

+72
-49
lines changed

src/PowerShellEditorServices/Server/PsesLanguageServer.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public async Task StartAsync()
114114
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize
115115
.OnInitialize(
116116
// TODO: Either fix or ignore "method lacks 'await'" warning.
117-
async (languageServer, request, cancellationToken) =>
117+
(languageServer, request, cancellationToken) =>
118118
{
119119
Log.Logger.Debug("Initializing OmniSharp Language Server");
120120

@@ -138,17 +138,7 @@ public async Task StartAsync()
138138
}
139139
}
140140

141-
// Set the working directory of the PowerShell session to the workspace path
142-
if (workspaceService.WorkspacePath != null
143-
&& Directory.Exists(workspaceService.WorkspacePath))
144-
{
145-
await serviceProvider.GetService<PowerShellExecutionService>()
146-
.ExecutePSCommandAsync(
147-
new PSCommand().AddCommand("Set-Location").AddParameter("-LiteralPath", workspaceService.WorkspacePath),
148-
new PowerShellExecutionOptions(),
149-
cancellationToken)
150-
.ConfigureAwait(false);
151-
}
141+
return Task.CompletedTask;
152142
});
153143
}).ConfigureAwait(false);
154144

src/PowerShellEditorServices/Server/PsesServiceCollectionExtensions.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ public static IServiceCollection AddPsesLanguageServices(
3939
.AddSingleton<TemplateService>()
4040
.AddSingleton<EditorOperationsService>()
4141
.AddSingleton<RemoteFileManagerService>()
42-
.AddSingleton(async (provider) =>
42+
.AddSingleton<ExtensionService>((provider) =>
4343
{
4444
var extensionService = new ExtensionService(
45-
provider.GetService<PowerShellExecutionService>(),
46-
provider.GetService<OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServerFacade>());
47-
await extensionService.InitializeAsync(
48-
serviceProvider: provider,
49-
editorOperations: provider.GetService<EditorOperationsService>()).ConfigureAwait(false);
45+
provider.GetService<ILanguageServerFacade>(),
46+
provider,
47+
provider.GetService<EditorOperationsService>(),
48+
provider.GetService<PowerShellExecutionService>());
49+
50+
extensionService.InitializeAsync().GetAwaiter().GetResult();
5051

5152
return extensionService;
5253
})

src/PowerShellEditorServices/Services/Extension/ExtensionService.cs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,29 @@ internal sealed class ExtensionService
5656
/// Creates a new instance of the ExtensionService which uses the provided
5757
/// PowerShellContext for loading and executing extension code.
5858
/// </summary>
59-
/// <param name="powerShellContext">A PowerShellContext used to execute extension code.</param>
60-
internal ExtensionService(PowerShellExecutionService executionService, ILanguageServerFacade languageServer)
59+
/// <param name="languageServer">The PSES language server instance.</param>
60+
/// <param name="serviceProvider">Services for dependency injection into the editor object.</param>
61+
/// <param name="editorOptions">Options object to configure the editor.</param>
62+
/// <param name="executionService">PowerShell execution service to run PowerShell execution requests.</param>
63+
internal ExtensionService(
64+
ILanguageServerFacade languageServer,
65+
IServiceProvider serviceProvider,
66+
IEditorOperations editorOperations,
67+
PowerShellExecutionService executionService)
6168
{
6269
ExecutionService = executionService;
6370
_languageServer = languageServer;
71+
72+
EditorObject =
73+
new EditorObject(
74+
serviceProvider,
75+
this,
76+
editorOperations);
77+
78+
// Attach to ExtensionService events
79+
CommandAdded += ExtensionService_ExtensionAddedAsync;
80+
CommandUpdated += ExtensionService_ExtensionUpdatedAsync;
81+
CommandRemoved += ExtensionService_ExtensionRemovedAsync;
6482
}
6583

6684
#endregion
@@ -73,23 +91,10 @@ internal ExtensionService(PowerShellExecutionService executionService, ILanguage
7391
/// </summary>
7492
/// <param name="editorOperations">An IEditorOperations implementation.</param>
7593
/// <returns>A Task that can be awaited for completion.</returns>
76-
internal async Task InitializeAsync(
77-
IServiceProvider serviceProvider,
78-
IEditorOperations editorOperations)
94+
internal async Task InitializeAsync()
7995
{
80-
// Attach to ExtensionService events
81-
this.CommandAdded += ExtensionService_ExtensionAddedAsync;
82-
this.CommandUpdated += ExtensionService_ExtensionUpdatedAsync;
83-
this.CommandRemoved += ExtensionService_ExtensionRemovedAsync;
84-
85-
this.EditorObject =
86-
new EditorObject(
87-
serviceProvider,
88-
this,
89-
editorOperations);
90-
9196
// Assign the new EditorObject to be the static instance available to binary APIs
92-
this.EditorObject.SetAsStaticInstance();
97+
EditorObject.SetAsStaticInstance();
9398

9499
// Register the editor object in the runspace
95100
await ExecutionService.ExecuteDelegateAsync((pwsh, cancellationToken) =>

src/PowerShellEditorServices/Services/PowerShell/Execution/PipelineThreadExecutor.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public PipelineThreadExecutor(
6060
_psesHost = psesHost;
6161
_debugContext = psesHost.DebugContext;
6262
_readLineProvider = readLineProvider;
63+
_consumerThreadCancellationSource = new CancellationTokenSource();
64+
_executionQueue = new BlockingCollection<ISynchronousTask>();
65+
_loopCancellationContext = new CancellationContext();
66+
_commandCancellationContext = new CancellationContext();
67+
_taskProcessingLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
6368

6469
_pipelineThread = new Thread(Run)
6570
{
@@ -75,11 +80,9 @@ public Task<TResult> QueueTask<TResult>(SynchronousTask<TResult> synchronousTask
7580
_executionQueue.Add(synchronousTask);
7681
return synchronousTask.Task;
7782
}
83+
7884
public void Start()
7985
{
80-
// We need to override the idle handler here,
81-
// since readline will be overridden by this point
82-
_readLineProvider.ReadLine.TryOverrideIdleHandler(OnPowerShellIdle);
8386
_pipelineThread.Start();
8487
}
8588

@@ -107,6 +110,10 @@ public IDisposable TakeTaskWriterLock()
107110
private void Run()
108111
{
109112
_psesHost.PushInitialPowerShell();
113+
// We need to override the idle handler here,
114+
// since readline will be overridden when the initial Powershell runspace is instantiated above
115+
_readLineProvider.ReadLine.TryOverrideIdleHandler(OnPowerShellIdle);
116+
_psesHost.PushNewReplTask();
110117
RunTopLevelConsumerLoop();
111118
}
112119

src/PowerShellEditorServices/Services/PowerShell/Host/EditorServicesConsolePSHost.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public EditorServicesConsolePSHost(
100100

101101
public override void EnterNestedPrompt()
102102
{
103-
PushPowerShell(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Nested);
103+
PushPowerShellAndRunLoop(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Nested);
104104
}
105105

106106
public override void ExitNestedPrompt()
@@ -127,7 +127,7 @@ public void PopRunspace()
127127
public void PushRunspace(Runspace runspace)
128128
{
129129
IsRunspacePushed = true;
130-
PushPowerShell(_psFactory.CreatePowerShellForRunspace(runspace), PowerShellFrameType.Remote);
130+
PushPowerShellAndRunLoop(_psFactory.CreatePowerShellForRunspace(runspace), PowerShellFrameType.Remote);
131131
}
132132

133133
public override void SetShouldExit(int exitCode)
@@ -145,7 +145,7 @@ public void PushInitialPowerShell()
145145

146146
internal void PushNonInteractivePowerShell()
147147
{
148-
PushPowerShell(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Nested | PowerShellFrameType.NonInteractive);
148+
PushPowerShellAndRunLoop(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Nested | PowerShellFrameType.NonInteractive);
149149
}
150150

151151
internal void CancelCurrentPrompt()
@@ -193,8 +193,6 @@ await ExecutionService.ExecuteDelegateAsync((pwsh, delegateCancellation) =>
193193
{
194194
await SetInitialWorkingDirectoryAsync(hostStartOptions.InitialWorkingDirectory, CancellationToken.None).ConfigureAwait(false);
195195
}
196-
197-
_consoleReplRunner?.StartRepl();
198196
}
199197

200198
private void SetExit()
@@ -212,12 +210,18 @@ private void SetExit()
212210
}
213211
}
214212

215-
private void PushPowerShell(SMA.PowerShell pwsh, PowerShellFrameType frameType)
213+
private void PushPowerShellAndRunLoop(SMA.PowerShell pwsh, PowerShellFrameType frameType)
216214
{
217215
// TODO: Improve runspace origin detection here
218216
RunspaceOrigin runspaceOrigin = pwsh.Runspace.RunspaceIsRemote ? RunspaceOrigin.EnteredProcess : RunspaceOrigin.Local;
219217
var runspaceInfo = RunspaceInfo.CreateFromPowerShell(_logger, pwsh, runspaceOrigin, _localComputerName);
220-
PushPowerShell(new PowerShellContextFrame(pwsh, runspaceInfo, frameType));
218+
PushPowerShellAndRunLoop(new PowerShellContextFrame(pwsh, runspaceInfo, frameType));
219+
}
220+
221+
private void PushPowerShellAndRunLoop(PowerShellContextFrame frame)
222+
{
223+
PushPowerShell(frame);
224+
_pipelineExecutor.RunPowerShellLoop(frame.FrameType);
221225
}
222226

223227
private void PushPowerShell(PowerShellContextFrame frame)
@@ -229,8 +233,6 @@ private void PushPowerShell(PowerShellContextFrame frame)
229233
AddRunspaceEventHandlers(frame.PowerShell.Runspace);
230234

231235
_psFrameStack.Push(frame);
232-
233-
_pipelineExecutor.RunPowerShellLoop(frame.FrameType);
234236
}
235237

236238
internal void PopPowerShell()
@@ -271,7 +273,7 @@ private void OnDebuggerStopped(object sender, DebuggerStopEventArgs debuggerStop
271273
try
272274
{
273275
CurrentPowerShell.WaitForRemoteOutputIfNeeded();
274-
PushPowerShell(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Debug | PowerShellFrameType.Nested);
276+
PushPowerShellAndRunLoop(_psFactory.CreateNestedPowerShell(CurrentRunspace), PowerShellFrameType.Debug | PowerShellFrameType.Nested);
275277
CurrentPowerShell.ResumeRemoteOutputIfNeeded();
276278
}
277279
finally

src/PowerShellEditorServices/Services/Workspace/Handlers/ConfigurationHandler.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.IO;
2121
using Microsoft.PowerShell.EditorServices.Services.PowerShell;
2222
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host;
23+
using Microsoft.PowerShell.EditorServices.Services.Extension;
2324

2425

2526
namespace Microsoft.PowerShell.EditorServices.Handlers
@@ -29,11 +30,13 @@ internal class PsesConfigurationHandler : DidChangeConfigurationHandlerBase
2930
private readonly ILogger _logger;
3031
private readonly WorkspaceService _workspaceService;
3132
private readonly ConfigurationService _configurationService;
33+
private readonly ExtensionService _extensionService;
3234
private readonly EditorServicesConsolePSHost _psesHost;
3335
private readonly ILanguageServerFacade _languageServer;
3436
private DidChangeConfigurationCapability _capability;
3537
private bool _profilesLoaded;
3638
private bool _consoleReplStarted;
39+
private bool _extensionServiceInitialized;
3740
private bool _cwdSet;
3841

3942
public PsesConfigurationHandler(
@@ -42,12 +45,14 @@ public PsesConfigurationHandler(
4245
AnalysisService analysisService,
4346
ConfigurationService configurationService,
4447
ILanguageServerFacade languageServer,
48+
ExtensionService extensionService,
4549
EditorServicesConsolePSHost psesHost)
4650
{
4751
_logger = factory.CreateLogger<PsesConfigurationHandler>();
4852
_workspaceService = workspaceService;
4953
_configurationService = configurationService;
5054
_languageServer = languageServer;
55+
_extensionService = extensionService;
5156
_psesHost = psesHost;
5257

5358
ConfigurationUpdated += analysisService.OnConfigurationUpdated;
@@ -76,6 +81,14 @@ public override async Task<Unit> Handle(DidChangeConfigurationParams request, Ca
7681
_workspaceService.WorkspacePath,
7782
_logger);
7883

84+
if (!_psesHost.IsRunning)
85+
{
86+
await _psesHost.StartAsync(new HostStartOptions
87+
{
88+
LoadProfiles = _configurationService.CurrentSettings.EnableProfileLoading,
89+
}, CancellationToken.None).ConfigureAwait(false);
90+
}
91+
7992
if (!this._cwdSet)
8093
{
8194
if (!string.IsNullOrEmpty(_configurationService.CurrentSettings.Cwd)
@@ -130,9 +143,14 @@ await _psesHost.StartAsync(new HostStartOptions
130143
_logger.LogTrace("Loaded!");
131144
}
132145

146+
if (!_extensionServiceInitialized)
147+
{
148+
await _extensionService.InitializeAsync();
149+
}
150+
133151
// Run any events subscribed to configuration updates
134152
this._logger.LogTrace("Running configuration update event handlers");
135-
ConfigurationUpdated(this, _configurationService.CurrentSettings);
153+
ConfigurationUpdated?.Invoke(this, _configurationService.CurrentSettings);
136154

137155
// Convert the editor file glob patterns into an array for the Workspace
138156
// Both the files.exclude and search.exclude hash tables look like (glob-text, is-enabled):

0 commit comments

Comments
 (0)