8
8
using System . Text ;
9
9
using System . Threading ;
10
10
using System . Threading . Tasks ;
11
+ using UnixConsoleEcho ;
11
12
12
13
namespace Microsoft . PowerShell . EditorServices . Console
13
14
{
@@ -20,8 +21,6 @@ internal class ConsoleReadLine
20
21
{
21
22
#region Private Field
22
23
23
- private object readKeyLock = new object ( ) ;
24
- private ConsoleKeyInfo ? bufferedKey ;
25
24
private PowerShellContext powerShellContext ;
26
25
27
26
#endregion
@@ -61,7 +60,7 @@ public async Task<SecureString> ReadSecureLine(CancellationToken cancellationTok
61
60
{
62
61
while ( ! cancellationToken . IsCancellationRequested )
63
62
{
64
- ConsoleKeyInfo keyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
63
+ ConsoleKeyInfo keyInfo = await ReadKeyAsync ( cancellationToken ) ;
65
64
66
65
if ( ( int ) keyInfo . Key == 3 ||
67
66
keyInfo . Key == ConsoleKey . C && keyInfo . Modifiers . HasFlag ( ConsoleModifiers . Control ) )
@@ -129,6 +128,28 @@ public async Task<SecureString> ReadSecureLine(CancellationToken cancellationTok
129
128
130
129
#region Private Methods
131
130
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
+
132
153
private async Task < string > ReadLine ( bool isCommandLine , CancellationToken cancellationToken )
133
154
{
134
155
string inputBeforeCompletion = null ;
@@ -154,7 +175,7 @@ private async Task<string> ReadLine(bool isCommandLine, CancellationToken cancel
154
175
{
155
176
while ( ! cancellationToken . IsCancellationRequested )
156
177
{
157
- ConsoleKeyInfo keyInfo = await this . ReadKeyAsync ( cancellationToken ) ;
178
+ ConsoleKeyInfo keyInfo = await ReadKeyAsync ( cancellationToken ) ;
158
179
159
180
// Do final position calculation after the key has been pressed
160
181
// because the window could have been resized before then
@@ -466,41 +487,6 @@ await this.powerShellContext.ExecuteCommand<PSObject>(
466
487
return null ;
467
488
}
468
489
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
-
504
490
private int CalculateIndexFromCursor (
505
491
int promptStartCol ,
506
492
int promptStartRow ,
0 commit comments