88using System . Text ;
99using System . Threading ;
1010using System . Threading . Tasks ;
11+ using UnixConsoleEcho ;
1112
1213namespace Microsoft . PowerShell . EditorServices . Console
1314{
@@ -20,8 +21,6 @@ internal class ConsoleReadLine
2021 {
2122 #region Private Field
2223
23- private object readKeyLock = new object ( ) ;
24- private ConsoleKeyInfo ? bufferedKey ;
2524 private PowerShellContext powerShellContext ;
2625
2726 #endregion
@@ -61,7 +60,7 @@ public async Task<SecureString> ReadSecureLine(CancellationToken cancellationTok
6160 {
6261 while ( ! cancellationToken . IsCancellationRequested )
6362 {
64- ConsoleKeyInfo keyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
63+ ConsoleKeyInfo keyInfo = await ReadKeyAsync ( cancellationToken ) ;
6564
6665 if ( ( int ) keyInfo . Key == 3 ||
6766 keyInfo . Key == ConsoleKey . C && keyInfo . Modifiers . HasFlag ( ConsoleModifiers . Control ) )
@@ -129,6 +128,28 @@ public async Task<SecureString> ReadSecureLine(CancellationToken cancellationTok
129128
130129 #region Private Methods
131130
131+ private static async Task < ConsoleKeyInfo > ReadKeyAsync ( CancellationToken cancellationToken )
132+ {
133+ await WaitForKeyAvailableAsync ( cancellationToken ) ;
134+ return Console . ReadKey ( true ) ;
135+ }
136+
137+ private static async Task WaitForKeyAvailableAsync ( CancellationToken cancellationToken )
138+ {
139+ InputEcho . Disable ( ) ;
140+ try
141+ {
142+ while ( ! Console . KeyAvailable )
143+ {
144+ await Task . Delay ( 50 , cancellationToken ) ;
145+ }
146+ }
147+ finally
148+ {
149+ InputEcho . Enable ( ) ;
150+ }
151+ }
152+
132153 private async Task < string > ReadLine ( bool isCommandLine , CancellationToken cancellationToken )
133154 {
134155 string inputBeforeCompletion = null ;
@@ -154,7 +175,7 @@ private async Task<string> ReadLine(bool isCommandLine, CancellationToken cancel
154175 {
155176 while ( ! cancellationToken . IsCancellationRequested )
156177 {
157- ConsoleKeyInfo keyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
178+ ConsoleKeyInfo keyInfo = await ReadKeyAsync ( cancellationToken ) ;
158179
159180 // Do final position calculation after the key has been pressed
160181 // because the window could have been resized before then
@@ -466,41 +487,6 @@ await this.powerShellContext.ExecuteCommand<PSObject>(
466487 return null ;
467488 }
468489
469- private async Task < ConsoleKeyInfo > ReadKeyAsync ( CancellationToken cancellationToken )
470- {
471- return await
472- Task . Factory . StartNew (
473- ( ) =>
474- {
475- ConsoleKeyInfo keyInfo ;
476-
477- lock ( this . readKeyLock )
478- {
479- if ( cancellationToken . IsCancellationRequested )
480- {
481- throw new TaskCanceledException ( ) ;
482- }
483- else if ( this . bufferedKey . HasValue )
484- {
485- keyInfo = this . bufferedKey . Value ;
486- this . bufferedKey = null ;
487- }
488- else
489- {
490- keyInfo = Console . ReadKey ( true ) ;
491-
492- if ( cancellationToken . IsCancellationRequested )
493- {
494- this . bufferedKey = keyInfo ;
495- throw new TaskCanceledException ( ) ;
496- }
497- }
498- }
499-
500- return keyInfo ;
501- } ) ;
502- }
503-
504490 private int CalculateIndexFromCursor (
505491 int promptStartCol ,
506492 int promptStartRow ,
0 commit comments