15
15
namespace Microsoft . PowerShell . EditorServices . Services . PowerShell . Console
16
16
{
17
17
using System ;
18
+ using System . Threading . Tasks ;
18
19
19
20
internal class LegacyReadLine : TerminalReadLine
20
21
{
21
22
private readonly PsesInternalHost _psesHost ;
22
23
23
24
private readonly IPowerShellDebugContext _debugContext ;
24
25
26
+ private readonly Task [ ] _readKeyTasks ;
27
+
25
28
private Func < bool , ConsoleKeyInfo > _readKeyFunc ;
26
29
30
+ private Action _onIdleAction ;
31
+
27
32
public LegacyReadLine (
28
33
PsesInternalHost psesHost ,
29
34
IPowerShellDebugContext debugContext )
30
35
{
31
36
_psesHost = psesHost ;
32
37
_debugContext = debugContext ;
38
+ _readKeyTasks = new Task [ 2 ] ;
33
39
}
34
40
35
41
public override string ReadLine ( CancellationToken cancellationToken )
@@ -383,6 +389,7 @@ public override string ReadLine(CancellationToken cancellationToken)
383
389
384
390
public override bool TryOverrideIdleHandler ( Action < CancellationToken > idleHandler )
385
391
{
392
+ _onIdleAction = idleHandler ;
386
393
return true ;
387
394
}
388
395
@@ -397,15 +404,47 @@ protected override ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)
397
404
cancellationToken . ThrowIfCancellationRequested ( ) ;
398
405
try
399
406
{
400
- // intercept = false means we display the key in the console
401
- return _readKeyFunc ( /* intercept */ false ) ;
407
+ return _onIdleAction is null
408
+ ? InvokeReadKeyFunc ( )
409
+ : ReadKeyWithIdleSupport ( cancellationToken ) ;
402
410
}
403
411
finally
404
412
{
405
413
cancellationToken . ThrowIfCancellationRequested ( ) ;
406
414
}
407
415
}
408
416
417
+ private ConsoleKeyInfo ReadKeyWithIdleSupport ( CancellationToken cancellationToken )
418
+ {
419
+ // We run the readkey function on another thread so we can run an idle handler
420
+ Task < ConsoleKeyInfo > readKeyTask = Task . Run ( InvokeReadKeyFunc ) ;
421
+
422
+ _readKeyTasks [ 0 ] = readKeyTask ;
423
+ _readKeyTasks [ 1 ] = Task . Delay ( millisecondsDelay : 300 , cancellationToken ) ;
424
+
425
+ while ( true )
426
+ {
427
+ switch ( Task . WaitAny ( _readKeyTasks , cancellationToken ) )
428
+ {
429
+ // ReadKey returned
430
+ case 0 :
431
+ return readKeyTask . Result ;
432
+
433
+ // The idle timed out
434
+ case 1 :
435
+ _onIdleAction ( ) ;
436
+ _readKeyTasks [ 1 ] = Task . Delay ( millisecondsDelay : 300 , cancellationToken ) ;
437
+ continue ;
438
+ }
439
+ }
440
+ }
441
+
442
+ private ConsoleKeyInfo InvokeReadKeyFunc ( )
443
+ {
444
+ // intercept = false means we display the key in the console
445
+ return _readKeyFunc ( /* intercept */ false ) ;
446
+ }
447
+
409
448
private static int InsertInput (
410
449
StringBuilder inputLine ,
411
450
int promptStartCol ,
0 commit comments