66using System . Management . Automation ;
77using System . Management . Automation . Host ;
88using System . Management . Automation . Internal ;
9+ using System . Text ;
10+
11+ using Microsoft . PowerShell . Commands . Internal . Format ;
912
1013using Dbg = System . Management . Automation . Diagnostics ;
1114
@@ -20,7 +23,7 @@ namespace Microsoft.PowerShell
2023 ProgressNode : ProgressRecord
2124 {
2225 /// <summary>
23- /// Indicates the various layouts for rendering a particular node. Each style is progressively less terse.
26+ /// Indicates the various layouts for rendering a particular node.
2427 /// </summary>
2528 internal
2629 enum
@@ -40,6 +43,11 @@ namespace Microsoft.PowerShell
4043 /// The node will be displayed the same as Full, plus, the whole StatusDescription and CurrentOperation will be displayed (in multiple lines if needed).
4144 /// </summary>
4245 FullPlus = 4 ,
46+
47+ /// <summary>
48+ /// The node will be displayed using ANSI escape sequences.
49+ /// </summary>
50+ Ansi = 5 ,
4351 }
4452
4553 /// <summary>
@@ -56,7 +64,11 @@ namespace Microsoft.PowerShell
5664 this . PercentComplete = Math . Min ( record . PercentComplete , 100 ) ;
5765 this . SecondsRemaining = record . SecondsRemaining ;
5866 this . RecordType = record . RecordType ;
59- this . Style = RenderStyle . FullPlus ;
67+
68+ this . Style = IsMinimalProgressRenderingEnabled ( )
69+ ? RenderStyle . Ansi
70+ : this . Style = RenderStyle . FullPlus ;
71+
6072 this . SourceId = sourceId ;
6173 }
6274
@@ -98,6 +110,9 @@ namespace Microsoft.PowerShell
98110 case RenderStyle . Minimal :
99111 RenderMinimal ( strCollection , indentation , maxWidth , rawUI ) ;
100112 break ;
113+ case RenderStyle . Ansi :
114+ RenderAnsi ( strCollection , indentation , maxWidth ) ;
115+ break ;
101116 case RenderStyle . Invisible :
102117 // do nothing
103118 break ;
@@ -336,6 +351,88 @@ private static void RenderFullDescription(string description, string indent, int
336351 maxWidth ) ) ;
337352 }
338353
354+ internal static bool IsMinimalProgressRenderingEnabled ( )
355+ {
356+ return ExperimentalFeature . IsEnabled ( ExperimentalFeature . PSAnsiProgressFeatureName ) && PSStyle . Instance . Progress . View == ProgressView . Minimal ;
357+ }
358+
359+ /// <summary>
360+ /// Renders a node in the "ANSI" style.
361+ /// </summary>
362+ /// <param name="strCollection">
363+ /// List of strings to which the node's rendering will be appended.
364+ /// </param>
365+ /// <param name="indentation">
366+ /// The indentation level in chars at which the node should be rendered.
367+ /// </param>
368+ /// <param name="maxWidth">
369+ /// The maximum number of chars that the rendering is allowed to consume.
370+ /// </param>
371+ private
372+ void
373+ RenderAnsi ( ArrayList strCollection , int indentation , int maxWidth )
374+ {
375+ string indent = StringUtil . Padding ( indentation ) ;
376+ string secRemain = string . Empty ;
377+ if ( SecondsRemaining >= 0 )
378+ {
379+ secRemain = SecondsRemaining . ToString ( ) + "s" ;
380+ }
381+
382+ int secRemainLength = secRemain . Length + 1 ;
383+
384+ // limit progress bar to 120 chars as no need to render full width
385+ if ( PSStyle . Instance . Progress . MaxWidth > 0 && maxWidth > PSStyle . Instance . Progress . MaxWidth )
386+ {
387+ maxWidth = PSStyle . Instance . Progress . MaxWidth ;
388+ }
389+
390+ // 4 is for the extra space and square brackets below and one extra space
391+ int barWidth = maxWidth - Activity . Length - indentation - 4 ;
392+
393+ var sb = new StringBuilder ( ) ;
394+ int padding = maxWidth + PSStyle . Instance . Progress . Style . Length + PSStyle . Instance . Reverse . Length + PSStyle . Instance . ReverseOff . Length ;
395+ sb . Append ( PSStyle . Instance . Reverse ) ;
396+
397+ if ( StatusDescription . Length > barWidth - secRemainLength )
398+ {
399+ sb . Append ( StatusDescription . Substring ( 0 , barWidth - secRemainLength - 1 ) ) ;
400+ sb . Append ( PSObjectHelper . Ellipsis ) ;
401+ }
402+ else
403+ {
404+ sb . Append ( StatusDescription ) ;
405+ }
406+
407+ sb . Append ( string . Empty . PadRight ( barWidth + PSStyle . Instance . Reverse . Length - sb . Length - secRemainLength ) ) ;
408+ sb . Append ( secRemain ) ;
409+
410+ if ( PercentComplete > 0 && PercentComplete < 100 )
411+ {
412+ int barLength = PercentComplete * barWidth / 100 ;
413+ if ( barLength >= barWidth )
414+ {
415+ barLength = barWidth - 1 ;
416+ }
417+
418+ sb . Insert ( barLength + PSStyle . Instance . Reverse . Length , PSStyle . Instance . ReverseOff ) ;
419+ }
420+ else
421+ {
422+ sb . Append ( PSStyle . Instance . ReverseOff ) ;
423+ }
424+
425+ strCollection . Add (
426+ StringUtil . Format (
427+ "{0}{1}{2} [{3}]{4}" ,
428+ indent ,
429+ PSStyle . Instance . Progress . Style ,
430+ Activity ,
431+ sb . ToString ( ) ,
432+ PSStyle . Instance . Reset )
433+ . PadRight ( padding ) ) ;
434+ }
435+
339436 /// <summary>
340437 /// The nodes that have this node as their parent.
341438 /// </summary>
@@ -396,6 +493,9 @@ internal int LinesRequiredMethod(PSHostRawUserInterface rawUi, int maxWidth)
396493 case RenderStyle . Invisible :
397494 return 0 ;
398495
496+ case RenderStyle . Ansi :
497+ return 1 ;
498+
399499 default :
400500 Dbg . Assert ( false , "Unknown RenderStyle value" ) ;
401501 break ;
0 commit comments