Skip to content

Commit beea563

Browse files
committed
Fix double prompt display when integrated console starts up
This change fixes an issue where the user's custom prompt function is displayed twice when the integrated console host starts up. This issue was a timing issue caused by the ConsoleService not being appropriately aware of when the input loop had been started. Resolves PowerShell/vscode-powershell#770.
1 parent 4adb231 commit beea563

File tree

1 file changed

+50
-34
lines changed

1 file changed

+50
-34
lines changed

src/PowerShellEditorServices/Console/ConsoleService.cs

+50-34
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ConsoleService : IConsoleHost
2424
{
2525
#region Fields
2626

27+
private bool isReadLoopStarted;
2728
private ConsoleReadLine consoleReadLine;
2829
private PowerShellContext powerShellContext;
2930

@@ -106,21 +107,8 @@ public void StartReadLoop()
106107
{
107108
if (this.EnableConsoleRepl)
108109
{
109-
if (this.readLineCancellationToken == null)
110-
{
111-
this.readLineCancellationToken = new CancellationTokenSource();
112-
113-
var terminalThreadTask =
114-
Task.Factory.StartNew(
115-
async () =>
116-
{
117-
await this.StartReplLoop(this.readLineCancellationToken.Token);
118-
});
119-
}
120-
else
121-
{
122-
Logger.Write(LogLevel.Verbose, "StartReadLoop called while read loop is already running");
123-
}
110+
this.isReadLoopStarted = true;
111+
this.InnerStartReadLoop();
124112
}
125113
}
126114

@@ -129,15 +117,8 @@ public void StartReadLoop()
129117
/// </summary>
130118
public void CancelReadLoop()
131119
{
132-
if (this.readLineCancellationToken != null)
133-
{
134-
// Set this to false so that Ctrl+C isn't trapped by any
135-
// lingering ReadKey
136-
Console.TreatControlCAsInput = false;
137-
138-
this.readLineCancellationToken.Cancel();
139-
this.readLineCancellationToken = null;
140-
}
120+
this.isReadLoopStarted = false;
121+
this.InnerCancelReadLoop();
141122
}
142123

143124
/// <summary>
@@ -148,7 +129,7 @@ public void CancelReadLoop()
148129
/// <returns>A Task that can be awaited for completion.</returns>
149130
public async Task ExecuteScriptAtPath(string scriptPath, string arguments = null)
150131
{
151-
this.CancelReadLoop();
132+
this.InnerCancelReadLoop();
152133

153134
// If we don't escape wildcard characters in the script path, the script can
154135
// fail to execute if say the script name was foo][.ps1.
@@ -161,7 +142,7 @@ await this.powerShellContext.ExecuteScriptString(
161142
true,
162143
false);
163144

164-
this.StartReadLoop();
145+
this.InnerStartReadLoop();
165146
}
166147

167148
/// <summary>
@@ -273,6 +254,41 @@ private void WriteDebuggerBanner(DebuggerStopEventArgs eventArgs)
273254
}
274255
}
275256

257+
private void InnerStartReadLoop()
258+
{
259+
if (this.EnableConsoleRepl)
260+
{
261+
if (this.readLineCancellationToken == null)
262+
{
263+
this.readLineCancellationToken = new CancellationTokenSource();
264+
265+
var terminalThreadTask =
266+
Task.Factory.StartNew(
267+
async () =>
268+
{
269+
await this.StartReplLoop(this.readLineCancellationToken.Token);
270+
});
271+
}
272+
else
273+
{
274+
Logger.Write(LogLevel.Verbose, "InnerStartReadLoop called while read loop is already running");
275+
}
276+
}
277+
}
278+
279+
private void InnerCancelReadLoop()
280+
{
281+
if (this.readLineCancellationToken != null)
282+
{
283+
// Set this to false so that Ctrl+C isn't trapped by any
284+
// lingering ReadKey
285+
Console.TreatControlCAsInput = false;
286+
287+
this.readLineCancellationToken.Cancel();
288+
this.readLineCancellationToken = null;
289+
}
290+
}
291+
276292
private async Task StartReplLoop(CancellationToken cancellationToken)
277293
{
278294
do
@@ -431,20 +447,20 @@ private void activePromptHandler_PromptCancelled(object sender, EventArgs e)
431447
private void PowerShellContext_DebuggerStop(object sender, System.Management.Automation.DebuggerStopEventArgs e)
432448
{
433449
// Cancel any existing prompt first
434-
this.CancelReadLoop();
450+
this.InnerCancelReadLoop();
435451

436452
this.WriteDebuggerBanner(e);
437-
this.StartReadLoop();
453+
this.InnerStartReadLoop();
438454
}
439455

440456
private void PowerShellContext_DebuggerResumed(object sender, System.Management.Automation.DebuggerResumeAction e)
441457
{
442-
this.CancelReadLoop();
458+
this.InnerCancelReadLoop();
443459
}
444460

445461
private void PowerShellContext_ExecutionStatusChanged(object sender, ExecutionStatusChangedEventArgs eventArgs)
446462
{
447-
if (this.EnableConsoleRepl)
463+
if (this.EnableConsoleRepl && this.isReadLoopStarted)
448464
{
449465
if (eventArgs.ExecutionStatus == ExecutionStatus.Aborted)
450466
{
@@ -464,12 +480,12 @@ private void PowerShellContext_ExecutionStatusChanged(object sender, ExecutionSt
464480
if (eventArgs.ExecutionStatus != ExecutionStatus.Running)
465481
{
466482
// Execution has completed, start the input prompt
467-
this.StartReadLoop();
483+
this.InnerStartReadLoop();
468484
}
469485
else
470486
{
471487
// A new command was started, cancel the input prompt
472-
this.CancelReadLoop();
488+
this.InnerCancelReadLoop();
473489
this.WriteOutput(string.Empty);
474490
}
475491
}
@@ -478,9 +494,9 @@ private void PowerShellContext_ExecutionStatusChanged(object sender, ExecutionSt
478494
(eventArgs.ExecutionStatus == ExecutionStatus.Failed ||
479495
eventArgs.HadErrors))
480496
{
481-
this.CancelReadLoop();
497+
this.InnerCancelReadLoop();
482498
this.WriteOutput(string.Empty);
483-
this.StartReadLoop();
499+
this.InnerStartReadLoop();
484500
}
485501
}
486502
}

0 commit comments

Comments
 (0)