@@ -632,10 +632,20 @@ public Collection<int> PromptForChoice(
632
632
633
633
#region Private Methods
634
634
635
- private async Task WritePromptStringToHost ( )
635
+ private Coordinates lastPromptLocation ;
636
+
637
+ private async Task WritePromptStringToHost ( CancellationToken cancellationToken )
636
638
{
639
+ if ( this . lastPromptLocation != null &&
640
+ this . lastPromptLocation . X == await ConsoleProxy . GetCursorLeftAsync ( cancellationToken ) &&
641
+ this . lastPromptLocation . Y == await ConsoleProxy . GetCursorTopAsync ( cancellationToken ) )
642
+ {
643
+ return ;
644
+ }
645
+
637
646
PSCommand promptCommand = new PSCommand ( ) . AddScript ( "prompt" ) ;
638
647
648
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
639
649
string promptString =
640
650
( await this . powerShellContext . ExecuteCommand < PSObject > ( promptCommand , false , false ) )
641
651
. Select ( pso => pso . BaseObject )
@@ -665,8 +675,13 @@ private async Task WritePromptStringToHost()
665
675
promptString ) ;
666
676
}
667
677
678
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
679
+
668
680
// Write the prompt string
669
681
this . WriteOutput ( promptString , false ) ;
682
+ this . lastPromptLocation = new Coordinates (
683
+ await ConsoleProxy . GetCursorLeftAsync ( cancellationToken ) ,
684
+ await ConsoleProxy . GetCursorTopAsync ( cancellationToken ) ) ;
670
685
}
671
686
672
687
private void WriteDebuggerBanner ( DebuggerStopEventArgs eventArgs )
@@ -686,14 +701,23 @@ private void WriteDebuggerBanner(DebuggerStopEventArgs eventArgs)
686
701
687
702
private async Task StartReplLoop ( CancellationToken cancellationToken )
688
703
{
689
- do
704
+ while ( ! cancellationToken . IsCancellationRequested )
690
705
{
691
706
string commandString = null ;
707
+ int originalCursorTop = 0 ;
692
708
693
- await this . WritePromptStringToHost ( ) ;
709
+ try
710
+ {
711
+ await this . WritePromptStringToHost ( cancellationToken ) ;
712
+ }
713
+ catch ( OperationCanceledException )
714
+ {
715
+ break ;
716
+ }
694
717
695
718
try
696
719
{
720
+ originalCursorTop = await ConsoleProxy . GetCursorTopAsync ( cancellationToken ) ;
697
721
commandString = await this . ReadCommandLine ( cancellationToken ) ;
698
722
}
699
723
catch ( PipelineStoppedException )
@@ -718,29 +742,29 @@ private async Task StartReplLoop(CancellationToken cancellationToken)
718
742
719
743
Logger . WriteException ( "Caught exception while reading command line" , e ) ;
720
744
}
721
-
722
- if ( commandString != null )
745
+ finally
723
746
{
724
- if ( ! string . IsNullOrWhiteSpace ( commandString ) )
725
- {
726
- var unusedTask =
727
- this . powerShellContext
728
- . ExecuteScriptString (
729
- commandString ,
730
- false ,
731
- true ,
732
- true )
733
- . ConfigureAwait ( false ) ;
734
-
735
- break ;
736
- }
737
- else
747
+ if ( ! cancellationToken . IsCancellationRequested &&
748
+ originalCursorTop == await ConsoleProxy . GetCursorTopAsync ( cancellationToken ) )
738
749
{
739
- this . WriteOutput ( string . Empty ) ;
750
+ this . WriteLine ( ) ;
740
751
}
741
752
}
753
+
754
+ if ( ! string . IsNullOrWhiteSpace ( commandString ) )
755
+ {
756
+ var unusedTask =
757
+ this . powerShellContext
758
+ . ExecuteScriptString (
759
+ commandString ,
760
+ false ,
761
+ true ,
762
+ true )
763
+ . ConfigureAwait ( false ) ;
764
+
765
+ break ;
766
+ }
742
767
}
743
- while ( ! cancellationToken . IsCancellationRequested ) ;
744
768
}
745
769
746
770
private InputPromptHandler CreateInputPromptHandler ( )
@@ -835,6 +859,12 @@ private void WaitForPromptCompletion<TResult>(
835
859
836
860
private void PowerShellContext_DebuggerStop ( object sender , System . Management . Automation . DebuggerStopEventArgs e )
837
861
{
862
+ if ( ! this . IsCommandLoopRunning )
863
+ {
864
+ ( ( IHostInput ) this ) . StartCommandLoop ( ) ;
865
+ return ;
866
+ }
867
+
838
868
// Cancel any existing prompt first
839
869
this . CancelCommandPrompt ( ) ;
840
870
@@ -850,45 +880,50 @@ private void PowerShellContext_DebuggerResumed(object sender, System.Management.
850
880
private void PowerShellContext_ExecutionStatusChanged ( object sender , ExecutionStatusChangedEventArgs eventArgs )
851
881
{
852
882
// The command loop should only be manipulated if it's already started
853
- if ( this . IsCommandLoopRunning )
883
+ if ( eventArgs . ExecutionStatus == ExecutionStatus . Aborted )
854
884
{
855
- if ( eventArgs . ExecutionStatus == ExecutionStatus . Aborted )
885
+ // When aborted, cancel any lingering prompts
886
+ if ( this . activePromptHandler != null )
856
887
{
857
- // When aborted, cancel any lingering prompts
858
- if ( this . activePromptHandler != null )
859
- {
860
- this . activePromptHandler . CancelPrompt ( ) ;
861
- this . WriteOutput ( string . Empty ) ;
862
- }
888
+ this . activePromptHandler . CancelPrompt ( ) ;
889
+ this . WriteOutput ( string . Empty ) ;
863
890
}
864
- else if (
865
- eventArgs . ExecutionOptions . WriteOutputToHost ||
866
- eventArgs . ExecutionOptions . InterruptCommandPrompt )
891
+ }
892
+ else if (
893
+ eventArgs . ExecutionOptions . WriteOutputToHost ||
894
+ eventArgs . ExecutionOptions . InterruptCommandPrompt )
895
+ {
896
+ // Any command which writes output to the host will affect
897
+ // the display of the prompt
898
+ if ( eventArgs . ExecutionStatus != ExecutionStatus . Running )
867
899
{
868
- // Any command which writes output to the host will affect
869
- // the display of the prompt
870
- if ( eventArgs . ExecutionStatus != ExecutionStatus . Running )
871
- {
872
- // Execution has completed, start the input prompt
873
- this . ShowCommandPrompt ( ) ;
874
- }
875
- else
876
- {
877
- // A new command was started, cancel the input prompt
878
- this . CancelCommandPrompt ( ) ;
879
- this . WriteOutput ( string . Empty ) ;
880
- }
900
+ // Execution has completed, start the input prompt
901
+ this . ShowCommandPrompt ( ) ;
902
+ ( ( IHostInput ) this ) . StartCommandLoop ( ) ;
881
903
}
882
- else if (
883
- eventArgs . ExecutionOptions . WriteErrorsToHost &&
884
- ( eventArgs . ExecutionStatus == ExecutionStatus . Failed ||
885
- eventArgs . HadErrors ) )
904
+ else
886
905
{
906
+ // A new command was started, cancel the input prompt
907
+ ( ( IHostInput ) this ) . StopCommandLoop ( ) ;
887
908
this . CancelCommandPrompt ( ) ;
888
909
this . WriteOutput ( string . Empty ) ;
889
- this . ShowCommandPrompt ( ) ;
890
910
}
891
911
}
912
+ else if (
913
+ eventArgs . ExecutionOptions . WriteErrorsToHost &&
914
+ ( eventArgs . ExecutionStatus == ExecutionStatus . Failed ||
915
+ eventArgs . HadErrors ) )
916
+ {
917
+ // this.CancelCommandPrompt();
918
+ // this.WriteOutput(string.Empty);
919
+ // this.ShowCommandPrompt();
920
+ // ((IHostInput)this).StopCommandLoop();
921
+ // this.CancelCommandPrompt();
922
+ // ((IHostInput)this).StartCommandLoop();
923
+ // this.ShowCommandPrompt();
924
+ this . WriteOutput ( string . Empty , true ) ;
925
+ var unusedTask = this . WritePromptStringToHost ( CancellationToken . None ) ;
926
+ }
892
927
}
893
928
894
929
#endregion
0 commit comments