@@ -23,6 +23,9 @@ pub struct Shell {
2323 err : ShellOut ,
2424 /// How verbose messages should be
2525 verbosity : Verbosity ,
26+ /// Flag that indicates the current line needs to be cleared before
27+ /// printing. Used when a progress bar is currently displayed.
28+ needs_clear : bool ,
2629}
2730
2831impl fmt:: Debug for Shell {
@@ -75,6 +78,7 @@ impl Shell {
7578 tty : atty:: is ( atty:: Stream :: Stderr ) ,
7679 } ,
7780 verbosity : Verbosity :: Verbose ,
81+ needs_clear : false ,
7882 }
7983 }
8084
@@ -83,6 +87,7 @@ impl Shell {
8387 Shell {
8488 err : ShellOut :: Write ( out) ,
8589 verbosity : Verbosity :: Verbose ,
90+ needs_clear : false ,
8691 }
8792 }
8893
@@ -97,10 +102,25 @@ impl Shell {
97102 ) -> CargoResult < ( ) > {
98103 match self . verbosity {
99104 Verbosity :: Quiet => Ok ( ( ) ) ,
100- _ => self . err . print ( status, message, color, justified) ,
105+ _ => {
106+ if self . needs_clear {
107+ self . err_erase_line ( ) ;
108+ }
109+ self . err . print ( status, message, color, justified)
110+ }
101111 }
102112 }
103113
114+ /// Set whether or not the next print should clear the current line.
115+ pub fn set_needs_clear ( & mut self , needs_clear : bool ) {
116+ self . needs_clear = needs_clear;
117+ }
118+
119+ /// True if the `needs_clear` flag is not set.
120+ pub fn is_cleared ( & self ) -> bool {
121+ !self . needs_clear
122+ }
123+
104124 /// Returns the width of the terminal in spaces, if any
105125 pub fn err_width ( & self ) -> Option < usize > {
106126 match self . err {
@@ -119,13 +139,17 @@ impl Shell {
119139
120140 /// Get a reference to the underlying writer
121141 pub fn err ( & mut self ) -> & mut dyn Write {
142+ if self . needs_clear {
143+ self . err_erase_line ( ) ;
144+ }
122145 self . err . as_write ( )
123146 }
124147
125148 /// Erase from cursor to end of line.
126149 pub fn err_erase_line ( & mut self ) {
127150 if let ShellOut :: Stream { tty : true , .. } = self . err {
128151 imp:: err_erase_line ( self ) ;
152+ self . needs_clear = false ;
129153 }
130154 }
131155
@@ -251,6 +275,9 @@ impl Shell {
251275
252276 /// Prints a message and translates ANSI escape code into console colors.
253277 pub fn print_ansi ( & mut self , message : & [ u8 ] ) -> CargoResult < ( ) > {
278+ if self . needs_clear {
279+ self . err_erase_line ( ) ;
280+ }
254281 #[ cfg( windows) ]
255282 {
256283 if let ShellOut :: Stream { stream, .. } = & mut self . err {
@@ -361,7 +388,7 @@ mod imp {
361388 // This is the "EL - Erase in Line" sequence. It clears from the cursor
362389 // to the end of line.
363390 // https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
364- let _ = shell. err ( ) . write_all ( b"\x1B [K" ) ;
391+ let _ = shell. err . as_write ( ) . write_all ( b"\x1B [K" ) ;
365392 }
366393}
367394
@@ -434,6 +461,6 @@ mod imp {
434461fn default_err_erase_line ( shell : & mut Shell ) {
435462 if let Some ( max_width) = imp:: stderr_width ( ) {
436463 let blank = " " . repeat ( max_width) ;
437- drop ( write ! ( shell. err( ) , "{}\r " , blank) ) ;
464+ drop ( write ! ( shell. err. as_write ( ) , "{}\r " , blank) ) ;
438465 }
439466}
0 commit comments