@@ -24,6 +24,10 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Host
24
24
{
25
25
using System . Management . Automation ;
26
26
using System . Management . Automation . Runspaces ;
27
+ // NOTE: These last three are for a workaround for temporary integrated consoles.
28
+ using Microsoft . PowerShell . EditorServices . Handlers ;
29
+ using Microsoft . PowerShell . EditorServices . Server ;
30
+ using OmniSharp . Extensions . DebugAdapter . Protocol . Server ;
27
31
28
32
internal class PsesInternalHost : PSHost , IHostSupportsInteractiveSession , IRunspaceContext , IInternalPowerShellExecutionService
29
33
{
@@ -41,6 +45,14 @@ internal class PsesInternalHost : PSHost, IHostSupportsInteractiveSession, IRuns
41
45
42
46
private readonly ILanguageServerFacade _languageServer ;
43
47
48
+ /// <summary>
49
+ /// TODO: Improve this coupling. It's assigned by <see cref="PsesDebugServer.StartAsync()" />
50
+ /// so that the PowerShell process started when <see cref="PsesLaunchRequestArguments.CreateTemporaryIntegratedConsole" />
51
+ /// is true can also receive the required 'sendKeyPress' notification to return from a
52
+ /// canceled <see cref="System.Console.ReadKey()" />.
53
+ /// </summary>
54
+ internal IDebugAdapterServerFacade DebugServer ;
55
+
44
56
private readonly HostStartupInfo _hostInfo ;
45
57
46
58
private readonly BlockingConcurrentDeque < ISynchronousTask > _taskQueue ;
@@ -1053,20 +1065,31 @@ private void OnCancelKeyPress(object sender, ConsoleCancelEventArgs args)
1053
1065
1054
1066
private ConsoleKeyInfo ReadKey ( bool intercept )
1055
1067
{
1056
- // PSRL doesn't tell us when CtrlC was sent.
1057
- // So instead we keep track of the last key here.
1058
- // This isn't functionally required,
1059
- // but helps us determine when the prompt needs a newline added
1060
-
1061
1068
// NOTE: This requests that the client (the Code extension) send a non-printing key back
1062
1069
// to the terminal on stdin, emulating a user pressing a button. This allows
1063
1070
// PSReadLine's thread waiting on Console.ReadKey to return. Normally we'd just cancel
1064
1071
// this call, but the .NET API ReadKey is not cancellable, and is stuck until we send
1065
1072
// input. This leads to a myriad of problems, but we circumvent them by pretending to
1066
1073
// press a key, thus allowing ReadKey to return, and us to ignore it.
1067
1074
using CancellationTokenRegistration registration = _readKeyCancellationToken . Register (
1068
- ( ) => _languageServer ? . SendNotification ( "powerShell/sendKeyPress" ) ) ;
1069
-
1075
+ ( ) =>
1076
+ {
1077
+ // For the regular integrated console, we have an associated language server on
1078
+ // which we can send a notification, and have the client subscribe an action to
1079
+ // send a key press.
1080
+ _languageServer ? . SendNotification ( "powerShell/sendKeyPress" ) ;
1081
+
1082
+ // When temporary integrated consoles are spawned, there will be no associated
1083
+ // language server, but instead a debug adaptor server. In this case, the
1084
+ // notification sent here will come across as a DebugSessionCustomEvent to which
1085
+ // we can subscribe in the same way.
1086
+ DebugServer ? . SendNotification ( "powerShell/sendKeyPress" ) ;
1087
+ } ) ;
1088
+
1089
+ // PSReadLine doesn't tell us when CtrlC was sent. So instead we keep track of the last
1090
+ // key here. This isn't functionally required, but helps us determine when the prompt
1091
+ // needs a newline added
1092
+ //
1070
1093
// TODO: We may want to allow users of PSES to override this method call.
1071
1094
_lastKey = System . Console . ReadKey ( intercept ) ;
1072
1095
return _lastKey . Value ;
0 commit comments