Skip to content

Commit dcf7422

Browse files
committed
Reset progress messages at end of REPL
This seems to work. We needed to hold onto processed progress records, and then at the end of the REPL mark each as completed and re-write it (which uses the underlying host and effectively clears it).
1 parent 640eac8 commit dcf7422

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/PowerShellEditorServices/Services/PowerShell/Host/EditorServicesConsolePSHostUserInterface.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
using System;
5+
using System.Collections.Concurrent;
56
using System.Collections.Generic;
67
using System.Collections.ObjectModel;
78
using System.Management.Automation;
@@ -22,6 +23,12 @@ internal class EditorServicesConsolePSHostUserInterface : PSHostUserInterface
2223

2324
private readonly PSHostUserInterface _consoleHostUI;
2425

26+
/// <summary>
27+
/// We use a ConcurrentDictionary because ConcurrentHashSet does not exist, hence the value
28+
/// is never actually used, and `WriteProgress` must be thread-safe.
29+
/// </summary>
30+
private readonly ConcurrentDictionary<(long, int), object> _currentProgressRecords = new();
31+
2532
public EditorServicesConsolePSHostUserInterface(
2633
ILoggerFactory loggerFactory,
2734
IReadLineProvider readLineProvider,
@@ -103,7 +110,35 @@ public override PSCredential PromptForCredential(string caption, string message,
103110

104111
public override void WriteLine(string value) => _underlyingHostUI.WriteLine(value);
105112

106-
public override void WriteProgress(long sourceId, ProgressRecord record) => _underlyingHostUI.WriteProgress(sourceId, record);
113+
public override void WriteProgress(long sourceId, ProgressRecord record)
114+
{
115+
if (record.RecordType == ProgressRecordType.Completed)
116+
{
117+
_ = _currentProgressRecords.TryRemove((sourceId, record.ActivityId), out _);
118+
}
119+
else
120+
{
121+
_ = _currentProgressRecords.TryAdd((sourceId, record.ActivityId), null);
122+
}
123+
_underlyingHostUI.WriteProgress(sourceId, record);
124+
}
125+
126+
public void ResetProgress()
127+
{
128+
// Mark all processed progress records as completed.
129+
foreach ((long sourceId, int activityId) in _currentProgressRecords.Keys)
130+
{
131+
// NOTE: This initializer checks that string is not null nor empty, so it must have
132+
// some text in it.
133+
ProgressRecord record = new(activityId, "0", "0")
134+
{
135+
RecordType = ProgressRecordType.Completed
136+
};
137+
_underlyingHostUI.WriteProgress(sourceId, record);
138+
_currentProgressRecords.Clear();
139+
}
140+
// TODO: Maybe send the OSC sequence to turn off progress indicator.
141+
}
107142

108143
public override void WriteVerboseLine(string message) => _underlyingHostUI.WriteVerboseLine(message);
109144

src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,15 @@ private void DoOneRepl(CancellationToken cancellationToken)
662662
UI.WriteErrorLine($"An error occurred while running the REPL loop:{Environment.NewLine}{e}");
663663
_logger.LogError(e, "An error occurred while running the REPL loop");
664664
}
665+
finally
666+
{
667+
// At the end of each REPL we need to complete all progress records so that the
668+
// progress indicator is cleared.
669+
if (UI is EditorServicesConsolePSHostUserInterface ui)
670+
{
671+
ui.ResetProgress();
672+
}
673+
}
665674
}
666675

667676
private string GetPrompt(CancellationToken cancellationToken)

0 commit comments

Comments
 (0)