22// Licensed under the MIT License.
33
44using System ;
5+ using System . Collections . Concurrent ;
56using System . Collections . Generic ;
67using System . Collections . ObjectModel ;
78using 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
0 commit comments