Skip to content

Commit 4e8c8a0

Browse files
authored
Add private contract delegate for PSES to handle idle (#1679)
1 parent 7edfa93 commit 4e8c8a0

File tree

2 files changed

+19
-31
lines changed

2 files changed

+19
-31
lines changed

PSReadLine.build.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ task LayoutModule BuildPolyfiller, BuildMainModule, {
144144
Copy-Item $binPath/Microsoft.PowerShell.PSReadLine2.dll $targetDir
145145
Copy-Item $binPath/Microsoft.PowerShell.Pager.dll $targetDir
146146

147+
if ($Configuration -eq 'Debug') {
148+
Copy-Item $binPath/*.pdb $targetDir
149+
}
150+
147151
if (Test-Path $binPath/System.Runtime.InteropServices.RuntimeInformation.dll) {
148152
Copy-Item $binPath/System.Runtime.InteropServices.RuntimeInformation.dll $targetDir
149153
} else {

PSReadLine/ReadLine.cs

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,17 @@ public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods
3535

3636
private const int CancellationRequested = 2;
3737

38-
private const int EventProcessingRequested = 3;
39-
4038
// *must* be initialized in the static ctor
4139
// because the static member _clipboard depends upon it
4240
// for its own initialization
4341
private static readonly PSConsoleReadLine _singleton;
4442

4543
private static readonly CancellationToken _defaultCancellationToken = new CancellationTokenSource().Token;
4644

45+
// This is used by PowerShellEditorServices (the backend of the PowerShell VSCode extension)
46+
// so that it can call PSReadLine from a delegate and not hit nested pipeline issues.
47+
private static Action<CancellationToken> _handleIdleOverride;
48+
4749
private bool _delayedOneTimeInitCompleted;
4850

4951
private IPSConsoleReadLineMockableMethods _mockableMethods;
@@ -55,7 +57,6 @@ public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods
5557
private Thread _readKeyThread;
5658
private AutoResetEvent _readKeyWaitHandle;
5759
private AutoResetEvent _keyReadWaitHandle;
58-
private AutoResetEvent _forceEventWaitHandle;
5960
private CancellationToken _cancelReadCancellationToken;
6061
internal ManualResetEvent _closingWaitHandle;
6162
private WaitHandle[] _threadProcWaitHandles;
@@ -195,12 +196,19 @@ internal static PSKeyInfo ReadKey()
195196
// Next, wait for one of three things:
196197
// - a key is pressed
197198
// - the console is exiting
198-
// - 300ms - to process events if we're idle
199-
// - processing of events is requested externally
199+
// - 300ms timeout - to process events if we're idle
200200
// - ReadLine cancellation is requested externally
201201
handleId = WaitHandle.WaitAny(_singleton._requestKeyWaitHandles, 300);
202-
if (handleId != WaitHandle.WaitTimeout && handleId != EventProcessingRequested)
202+
if (handleId != WaitHandle.WaitTimeout)
203+
{
203204
break;
205+
}
206+
207+
if (_handleIdleOverride is not null)
208+
{
209+
_handleIdleOverride(_singleton._cancelReadCancellationToken);
210+
continue;
211+
}
204212

205213
// If we timed out, check for event subscribers (which is just
206214
// a hint that there might be an event waiting to be processed.)
@@ -310,15 +318,6 @@ public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsi
310318
return ReadLine(runspace, engineIntrinsics, _defaultCancellationToken, lastRunStatus);
311319
}
312320

313-
/// <summary>
314-
/// Temporary entry point for PowerShell VSCode extension to avoid breaking the existing PSES.
315-
/// PSES will need to move away from this entry point to actually provide information about 'lastRunStatus'.
316-
/// </summary>
317-
public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken)
318-
{
319-
return ReadLine(runspace, engineIntrinsics, cancellationToken, lastRunStatus: null);
320-
}
321-
322321
/// <summary>
323322
/// Entry point - called by custom PSHost implementations that require the
324323
/// ability to cancel ReadLine.
@@ -666,10 +665,6 @@ private PSConsoleReadLine()
666665
_savedCurrentLine = new HistoryItem();
667666
_queuedKeys = new Queue<PSKeyInfo>();
668667

669-
// Initialize this event handler early because it could be used by PowerShell
670-
// Editor Services before 'DelayedOneTimeInitialize' runs.
671-
_forceEventWaitHandle = new AutoResetEvent(false);
672-
673668
string hostName = null;
674669
// This works mostly by luck - we're not doing anything to guarantee the constructor for our
675670
// singleton is called on a thread with a runspace, but it is happening by coincidence.
@@ -860,7 +855,7 @@ private void DelayedOneTimeInitialize()
860855
_singleton._readKeyWaitHandle = new AutoResetEvent(false);
861856
_singleton._keyReadWaitHandle = new AutoResetEvent(false);
862857
_singleton._closingWaitHandle = new ManualResetEvent(false);
863-
_singleton._requestKeyWaitHandles = new WaitHandle[] {_singleton._keyReadWaitHandle, _singleton._closingWaitHandle, _defaultCancellationToken.WaitHandle, _singleton._forceEventWaitHandle};
858+
_singleton._requestKeyWaitHandles = new WaitHandle[] {_singleton._keyReadWaitHandle, _singleton._closingWaitHandle, _defaultCancellationToken.WaitHandle};
864859
_singleton._threadProcWaitHandles = new WaitHandle[] {_singleton._readKeyWaitHandle, _singleton._closingWaitHandle};
865860

866861
// This is for a "being hosted in an alternate appdomain scenario" (the
@@ -880,17 +875,6 @@ private void DelayedOneTimeInitialize()
880875
_singleton._readKeyThread.Start();
881876
}
882877

883-
/// <summary>
884-
/// Used by PowerShellEditorServices to force immediate
885-
/// event handling during the <see cref="PSConsoleReadLine.ReadKey" />
886-
/// method. This is not a public API, but it is part of a private contract
887-
/// with that project.
888-
/// </summary>
889-
private static void ForcePSEventHandling()
890-
{
891-
_singleton._forceEventWaitHandle.Set();
892-
}
893-
894878
private static void Chord(ConsoleKeyInfo? key = null, object arg = null)
895879
{
896880
if (!key.HasValue)

0 commit comments

Comments
 (0)