@@ -6,6 +6,31 @@ use termcolor::{self, Color, ColorSpec, StandardStream, WriteColor};
6
6
7
7
use crate :: util:: errors:: CargoResult ;
8
8
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
+
9
34
/// The requested verbosity of output.
10
35
#[ derive( Debug , Clone , Copy , PartialEq ) ]
11
36
pub enum Verbosity {
@@ -125,12 +150,12 @@ impl Shell {
125
150
}
126
151
127
152
/// 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 {
129
154
match self . output {
130
155
ShellOut :: Stream {
131
156
stderr_tty : true , ..
132
157
} => imp:: stderr_width ( ) ,
133
- _ => None ,
158
+ _ => TtyWidth :: NoTty ,
134
159
}
135
160
}
136
161
@@ -408,21 +433,21 @@ impl ColorChoice {
408
433
409
434
#[ cfg( unix) ]
410
435
mod imp {
411
- use super :: Shell ;
436
+ use super :: { Shell , TtyWidth } ;
412
437
use std:: mem;
413
438
414
- pub fn stderr_width ( ) -> Option < usize > {
439
+ pub fn stderr_width ( ) -> TtyWidth {
415
440
unsafe {
416
441
let mut winsize: libc:: winsize = mem:: zeroed ( ) ;
417
442
// The .into() here is needed for FreeBSD which defines TIOCGWINSZ
418
443
// as c_uint but ioctl wants c_ulong.
419
444
if libc:: ioctl ( libc:: STDERR_FILENO , libc:: TIOCGWINSZ . into ( ) , & mut winsize) < 0 {
420
- return None ;
445
+ return TtyWidth :: NoTty ;
421
446
}
422
447
if winsize. ws_col > 0 {
423
- Some ( winsize. ws_col as usize )
448
+ TtyWidth :: Known ( winsize. ws_col as usize )
424
449
} else {
425
- None
450
+ TtyWidth :: NoTty
426
451
}
427
452
}
428
453
}
@@ -445,14 +470,14 @@ mod imp {
445
470
use winapi:: um:: wincon:: * ;
446
471
use winapi:: um:: winnt:: * ;
447
472
448
- pub ( super ) use super :: default_err_erase_line as err_erase_line;
473
+ pub ( super ) use super :: { default_err_erase_line as err_erase_line, TtyWidth } ;
449
474
450
- pub fn stderr_width ( ) -> Option < usize > {
475
+ pub fn stderr_width ( ) -> TtyWidth {
451
476
unsafe {
452
477
let stdout = GetStdHandle ( STD_ERROR_HANDLE ) ;
453
478
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
454
479
if GetConsoleScreenBufferInfo ( stdout, & mut csbi) != 0 {
455
- return Some ( ( csbi. srWindow . Right - csbi. srWindow . Left ) as usize ) ;
480
+ return TtyWidth :: Known ( ( csbi. srWindow . Right - csbi. srWindow . Left ) as usize ) ;
456
481
}
457
482
458
483
// On mintty/msys/cygwin based terminals, the above fails with
@@ -468,7 +493,7 @@ mod imp {
468
493
ptr:: null_mut ( ) ,
469
494
) ;
470
495
if h == INVALID_HANDLE_VALUE {
471
- return None ;
496
+ return TtyWidth :: NoTty ;
472
497
}
473
498
474
499
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
@@ -484,17 +509,21 @@ mod imp {
484
509
// resize the console correctly, but there's no reasonable way
485
510
// to detect which kind of terminal we are running in, or if
486
511
// GetConsoleScreenBufferInfo returns accurate information.
487
- return Some ( cmp:: min ( 60 , width) ) ;
512
+ return TtyWidth :: Guess ( cmp:: min ( 60 , width) ) ;
488
513
}
489
- None
514
+
515
+ TtyWidth :: NoTty
490
516
}
491
517
}
492
518
}
493
519
494
520
#[ cfg( windows) ]
495
521
fn default_err_erase_line ( shell : & mut Shell ) {
496
- if let Some ( max_width) = imp:: stderr_width ( ) {
497
- let blank = " " . repeat ( max_width) ;
498
- 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
+ _ => ( ) ,
499
528
}
500
529
}
0 commit comments