@@ -6,6 +6,31 @@ use termcolor::{self, Color, ColorSpec, StandardStream, WriteColor};
66
77use crate :: util:: errors:: CargoResult ;
88
9+ pub enum TtyWidth {
10+ NoTty ,
11+ Known ( usize ) ,
12+ Guess ( usize ) ,
13+ }
14+
15+ impl TtyWidth {
16+ /// Returns the width provided with `-Z terminal-width` to rustc to truncate diagnostics with
17+ /// long lines.
18+ pub fn diagnostic_terminal_width ( & self ) -> Option < usize > {
19+ match * self {
20+ TtyWidth :: NoTty | TtyWidth :: Guess ( _) => None ,
21+ TtyWidth :: Known ( width) => Some ( width) ,
22+ }
23+ }
24+
25+ /// Returns the width used by progress bars for the tty.
26+ pub fn progress_max_width ( & self ) -> Option < usize > {
27+ match * self {
28+ TtyWidth :: NoTty => None ,
29+ TtyWidth :: Known ( width) | TtyWidth :: Guess ( width) => Some ( width) ,
30+ }
31+ }
32+ }
33+
934/// The requested verbosity of output.
1035#[ derive( Debug , Clone , Copy , PartialEq ) ]
1136pub enum Verbosity {
@@ -125,21 +150,12 @@ impl Shell {
125150 }
126151
127152 /// Returns the width of the terminal in spaces, if any.
128- pub fn err_width ( & self ) -> Option < usize > {
153+ pub fn err_width ( & self ) -> TtyWidth {
129154 match self . output {
130155 ShellOut :: Stream {
131156 stderr_tty : true , ..
132157 } => imp:: stderr_width ( ) ,
133- _ => None ,
134- }
135- }
136-
137- /// Returns the width of the terminal in spaces, if any. Always `None` in Windows.
138- pub fn accurate_err_width ( & self ) -> Option < usize > {
139- if self . is_err_tty ( ) {
140- imp:: accurate_stderr_width ( )
141- } else {
142- None
158+ _ => TtyWidth :: NoTty ,
143159 }
144160 }
145161
@@ -417,25 +433,21 @@ impl ColorChoice {
417433
418434#[ cfg( unix) ]
419435mod imp {
420- use super :: Shell ;
436+ use super :: { Shell , TtyWidth } ;
421437 use std:: mem;
422438
423- pub fn accurate_stderr_width ( ) -> Option < usize > {
424- stderr_width ( )
425- }
426-
427- pub fn stderr_width ( ) -> Option < usize > {
439+ pub fn stderr_width ( ) -> TtyWidth {
428440 unsafe {
429441 let mut winsize: libc:: winsize = mem:: zeroed ( ) ;
430442 // The .into() here is needed for FreeBSD which defines TIOCGWINSZ
431443 // as c_uint but ioctl wants c_ulong.
432444 if libc:: ioctl ( libc:: STDERR_FILENO , libc:: TIOCGWINSZ . into ( ) , & mut winsize) < 0 {
433- return None ;
445+ return TtyWidth :: NoTty ;
434446 }
435447 if winsize. ws_col > 0 {
436- Some ( winsize. ws_col as usize )
448+ TtyWidth :: Known ( winsize. ws_col as usize )
437449 } else {
438- None
450+ TtyWidth :: NoTty
439451 }
440452 }
441453 }
@@ -458,18 +470,14 @@ mod imp {
458470 use winapi:: um:: wincon:: * ;
459471 use winapi:: um:: winnt:: * ;
460472
461- pub ( super ) use super :: default_err_erase_line as err_erase_line;
462-
463- pub fn accurate_stderr_width ( ) -> Option < usize > {
464- None
465- }
473+ pub ( super ) use super :: { default_err_erase_line as err_erase_line, TtyWidth } ;
466474
467- pub fn stderr_width ( ) -> Option < usize > {
475+ pub fn stderr_width ( ) -> TtyWidth {
468476 unsafe {
469477 let stdout = GetStdHandle ( STD_ERROR_HANDLE ) ;
470478 let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
471479 if GetConsoleScreenBufferInfo ( stdout, & mut csbi) != 0 {
472- return Some ( ( csbi. srWindow . Right - csbi. srWindow . Left ) as usize ) ;
480+ return TtyWidth :: Known ( ( csbi. srWindow . Right - csbi. srWindow . Left ) as usize ) ;
473481 }
474482
475483 // On mintty/msys/cygwin based terminals, the above fails with
@@ -485,7 +493,7 @@ mod imp {
485493 ptr:: null_mut ( ) ,
486494 ) ;
487495 if h == INVALID_HANDLE_VALUE {
488- return None ;
496+ return TtyWidth :: NoTty ;
489497 }
490498
491499 let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
@@ -501,17 +509,21 @@ mod imp {
501509 // resize the console correctly, but there's no reasonable way
502510 // to detect which kind of terminal we are running in, or if
503511 // GetConsoleScreenBufferInfo returns accurate information.
504- return Some ( cmp:: min ( 60 , width) ) ;
512+ return TtyWidth :: Guess ( cmp:: min ( 60 , width) ) ;
505513 }
506- None
514+
515+ TtyWidth :: NoTty
507516 }
508517 }
509518}
510519
511520#[ cfg( windows) ]
512521fn default_err_erase_line ( shell : & mut Shell ) {
513- if let Some ( max_width) = imp:: stderr_width ( ) {
514- let blank = " " . repeat ( max_width) ;
515- drop ( write ! ( shell. output. stderr( ) , "{}\r " , blank) ) ;
522+ match imp:: stderr_width ( ) {
523+ TtyWidth :: Known ( max_width) | TtyWidth :: Guess ( max_width) => {
524+ let blank = " " . repeat ( max_width) ;
525+ drop ( write ! ( shell. output. stderr( ) , "{}\r " , blank) ) ;
526+ }
527+ _ => ( ) ,
516528 }
517529}
0 commit comments