diff --git a/PSReadLine.build.ps1 b/PSReadLine.build.ps1 index 23ec7f42..72f89c49 100644 --- a/PSReadLine.build.ps1 +++ b/PSReadLine.build.ps1 @@ -144,6 +144,10 @@ task LayoutModule BuildPolyfiller, BuildMainModule, { Copy-Item $binPath/Microsoft.PowerShell.PSReadLine2.dll $targetDir Copy-Item $binPath/Microsoft.PowerShell.Pager.dll $targetDir + if ($Configuration -eq 'Debug') { + Copy-Item $binPath/*.pdb $targetDir + } + if (Test-Path $binPath/System.Runtime.InteropServices.RuntimeInformation.dll) { Copy-Item $binPath/System.Runtime.InteropServices.RuntimeInformation.dll $targetDir } else { diff --git a/PSReadLine/ReadLine.cs b/PSReadLine/ReadLine.cs index 4b9ab462..017e1f72 100644 --- a/PSReadLine/ReadLine.cs +++ b/PSReadLine/ReadLine.cs @@ -35,8 +35,6 @@ public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods private const int CancellationRequested = 2; - private const int EventProcessingRequested = 3; - // *must* be initialized in the static ctor // because the static member _clipboard depends upon it // for its own initialization @@ -44,6 +42,10 @@ public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods private static readonly CancellationToken _defaultCancellationToken = new CancellationTokenSource().Token; + // This is used by PowerShellEditorServices (the backend of the PowerShell VSCode extension) + // so that it can call PSReadLine from a delegate and not hit nested pipeline issues. + private static Action _handleIdleOverride; + private bool _delayedOneTimeInitCompleted; private IPSConsoleReadLineMockableMethods _mockableMethods; @@ -55,7 +57,6 @@ public partial class PSConsoleReadLine : IPSConsoleReadLineMockableMethods private Thread _readKeyThread; private AutoResetEvent _readKeyWaitHandle; private AutoResetEvent _keyReadWaitHandle; - private AutoResetEvent _forceEventWaitHandle; private CancellationToken _cancelReadCancellationToken; internal ManualResetEvent _closingWaitHandle; private WaitHandle[] _threadProcWaitHandles; @@ -195,12 +196,19 @@ internal static PSKeyInfo ReadKey() // Next, wait for one of three things: // - a key is pressed // - the console is exiting - // - 300ms - to process events if we're idle - // - processing of events is requested externally + // - 300ms timeout - to process events if we're idle // - ReadLine cancellation is requested externally handleId = WaitHandle.WaitAny(_singleton._requestKeyWaitHandles, 300); - if (handleId != WaitHandle.WaitTimeout && handleId != EventProcessingRequested) + if (handleId != WaitHandle.WaitTimeout) + { break; + } + + if (_handleIdleOverride is not null) + { + _handleIdleOverride(_singleton._cancelReadCancellationToken); + continue; + } // If we timed out, check for event subscribers (which is just // a hint that there might be an event waiting to be processed.) @@ -310,15 +318,6 @@ public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsi return ReadLine(runspace, engineIntrinsics, _defaultCancellationToken, lastRunStatus); } - /// - /// Temporary entry point for PowerShell VSCode extension to avoid breaking the existing PSES. - /// PSES will need to move away from this entry point to actually provide information about 'lastRunStatus'. - /// - public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken) - { - return ReadLine(runspace, engineIntrinsics, cancellationToken, lastRunStatus: null); - } - /// /// Entry point - called by custom PSHost implementations that require the /// ability to cancel ReadLine. @@ -666,10 +665,6 @@ private PSConsoleReadLine() _savedCurrentLine = new HistoryItem(); _queuedKeys = new Queue(); - // Initialize this event handler early because it could be used by PowerShell - // Editor Services before 'DelayedOneTimeInitialize' runs. - _forceEventWaitHandle = new AutoResetEvent(false); - string hostName = null; // This works mostly by luck - we're not doing anything to guarantee the constructor for our // singleton is called on a thread with a runspace, but it is happening by coincidence. @@ -860,7 +855,7 @@ private void DelayedOneTimeInitialize() _singleton._readKeyWaitHandle = new AutoResetEvent(false); _singleton._keyReadWaitHandle = new AutoResetEvent(false); _singleton._closingWaitHandle = new ManualResetEvent(false); - _singleton._requestKeyWaitHandles = new WaitHandle[] {_singleton._keyReadWaitHandle, _singleton._closingWaitHandle, _defaultCancellationToken.WaitHandle, _singleton._forceEventWaitHandle}; + _singleton._requestKeyWaitHandles = new WaitHandle[] {_singleton._keyReadWaitHandle, _singleton._closingWaitHandle, _defaultCancellationToken.WaitHandle}; _singleton._threadProcWaitHandles = new WaitHandle[] {_singleton._readKeyWaitHandle, _singleton._closingWaitHandle}; // This is for a "being hosted in an alternate appdomain scenario" (the @@ -880,17 +875,6 @@ private void DelayedOneTimeInitialize() _singleton._readKeyThread.Start(); } - /// - /// Used by PowerShellEditorServices to force immediate - /// event handling during the - /// method. This is not a public API, but it is part of a private contract - /// with that project. - /// - private static void ForcePSEventHandling() - { - _singleton._forceEventWaitHandle.Set(); - } - private static void Chord(ConsoleKeyInfo? key = null, object arg = null) { if (!key.HasValue)