@@ -729,6 +729,19 @@ private void DoOneRepl(CancellationToken cancellationToken)
729729 return ;
730730 }
731731
732+ // TODO: We must remove this awful logic, it causes so much pain. The StopDebugContext()
733+ // requires that we're not in a prompt that we're skipping, otherwise the debugger is
734+ // "active" but we haven't yet hit a breakpoint.
735+ //
736+ // When a task must run in the foreground, we cancel out of the idle loop and return to
737+ // the top level. At that point, we would normally run a REPL, but we need to
738+ // immediately execute the task. So we set _skipNextPrompt to do that.
739+ if ( _skipNextPrompt )
740+ {
741+ _skipNextPrompt = false ;
742+ return ;
743+ }
744+ 732745 // We use the REPL as a poll to check if the debug context is active but PowerShell
733746 // indicates we're no longer debugging. This happens when PowerShell was used to start
734747 // the debugger (instead of using a Code launch configuration) via Wait-Debugger or
@@ -741,15 +754,6 @@ private void DoOneRepl(CancellationToken cancellationToken)
741754 StopDebugContext ( ) ;
742755 }
743756
744- // When a task must run in the foreground, we cancel out of the idle loop and return to the top level.
745- // At that point, we would normally run a REPL, but we need to immediately execute the task.
746- // So we set _skipNextPrompt to do that.
747- if ( _skipNextPrompt )
748- {
749- _skipNextPrompt = false ;
750- return ;
751- }
752- 753757 try
754758 {
755759 string prompt = GetPrompt ( cancellationToken ) ;
@@ -758,18 +762,22 @@ private void DoOneRepl(CancellationToken cancellationToken)
758762
759763 // If the user input was empty it's because:
760764 // - the user provided no input
761- // - the readline task was canceled
762- // - CtrlC was sent to readline (which does not propagate a cancellation)
765+ // - the ReadLine task was canceled
766+ // - CtrlC was sent to ReadLine (which does not propagate a cancellation)
763767 //
764- // In any event there's nothing to run in PowerShell, so we just loop back to the prompt again.
765- // However, we must distinguish the last two scenarios, since PSRL will not print a new line in those cases.
768+ // In any event there's nothing to run in PowerShell, so we just loop back to the
769+ // prompt again. However, PSReadLine will not print a newline for CtrlC, so we print
770+ // one, but we do not want to print one if the ReadLine task was canceled.
766771 if ( string . IsNullOrEmpty ( userInput ) )
767772 {
768- if ( cancellationToken . IsCancellationRequested || LastKeyWasCtrlC ( ) )
773+ if ( LastKeyWasCtrlC ( ) )
769774 {
770775 UI . WriteLine ( ) ;
771776 }
772- return ;
777+ // Propogate cancellation if that's what happened, since ReadLine won't.
778+ // TODO: We may not need to do this at all.
779+ cancellationToken . ThrowIfCancellationRequested ( ) ;
780+ return ; // Task wasn't canceled but there was no input.
773781 }
774782
775783 InvokeInput ( userInput , cancellationToken ) ;
@@ -783,10 +791,8 @@ private void DoOneRepl(CancellationToken cancellationToken)
783791 {
784792 throw ;
785793 }
786- catch ( FlowControlException )
787- {
788- // Do nothing, a break or continue statement was used outside of a loop.
789- }
794+ // Do nothing, a break or continue statement was used outside of a loop.
795+ catch ( FlowControlException ) { }
790796 catch ( Exception e )
791797 {
792798 UI . WriteErrorLine ( $ "An error occurred while running the REPL loop:{ Environment . NewLine } { e } ") ;
@@ -830,25 +836,14 @@ private string GetPrompt(CancellationToken cancellationToken)
830836 return prompt ;
831837 }
832838
833- /// <summary>
834- /// This is used to write the invocation text of a command with the user's prompt so that,
835- /// for example, F8 (evaluate selection) appears as if the user typed it. Used when
836- /// 'WriteInputToHost' is true.
837- /// </summary>
838- /// <param name="command">The PSCommand we'll print after the prompt.</param>
839- /// <param name="cancellationToken"></param>
840- public void WriteWithPrompt ( PSCommand command , CancellationToken cancellationToken )
841- {
842- UI . Write ( GetPrompt ( cancellationToken ) ) ;
843- UI . WriteLine ( command . GetInvocationText ( ) ) ;
844- }
845- 846839 private string InvokeReadLine ( CancellationToken cancellationToken )
847840 {
848- cancellationToken . ThrowIfCancellationRequested ( ) ;
849841 try
850842 {
843+ // TODO: If we can pass the cancellation token to ReadKey directly in PSReadLine, we
844+ // can remove this logic.
851845 _readKeyCancellationToken = cancellationToken ;
846+ cancellationToken . ThrowIfCancellationRequested ( ) ;
852847 return _readLineProvider . ReadLine . ReadLine ( cancellationToken ) ;
853848 }
854849 finally
0 commit comments