@@ -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,21 +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 ,
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 ,
143
159
}
144
160
}
145
161
@@ -417,25 +433,21 @@ impl ColorChoice {
417
433
418
434
#[ cfg( unix) ]
419
435
mod imp {
420
- use super :: Shell ;
436
+ use super :: { Shell , TtyWidth } ;
421
437
use std:: mem;
422
438
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 {
428
440
unsafe {
429
441
let mut winsize: libc:: winsize = mem:: zeroed ( ) ;
430
442
// The .into() here is needed for FreeBSD which defines TIOCGWINSZ
431
443
// as c_uint but ioctl wants c_ulong.
432
444
if libc:: ioctl ( libc:: STDERR_FILENO , libc:: TIOCGWINSZ . into ( ) , & mut winsize) < 0 {
433
- return None ;
445
+ return TtyWidth :: NoTty ;
434
446
}
435
447
if winsize. ws_col > 0 {
436
- Some ( winsize. ws_col as usize )
448
+ TtyWidth :: Known ( winsize. ws_col as usize )
437
449
} else {
438
- None
450
+ TtyWidth :: NoTty
439
451
}
440
452
}
441
453
}
@@ -458,18 +470,14 @@ mod imp {
458
470
use winapi:: um:: wincon:: * ;
459
471
use winapi:: um:: winnt:: * ;
460
472
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 } ;
466
474
467
- pub fn stderr_width ( ) -> Option < usize > {
475
+ pub fn stderr_width ( ) -> TtyWidth {
468
476
unsafe {
469
477
let stdout = GetStdHandle ( STD_ERROR_HANDLE ) ;
470
478
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
471
479
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 ) ;
473
481
}
474
482
475
483
// On mintty/msys/cygwin based terminals, the above fails with
@@ -485,7 +493,7 @@ mod imp {
485
493
ptr:: null_mut ( ) ,
486
494
) ;
487
495
if h == INVALID_HANDLE_VALUE {
488
- return None ;
496
+ return TtyWidth :: NoTty ;
489
497
}
490
498
491
499
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem:: zeroed ( ) ;
@@ -501,17 +509,21 @@ mod imp {
501
509
// resize the console correctly, but there's no reasonable way
502
510
// to detect which kind of terminal we are running in, or if
503
511
// GetConsoleScreenBufferInfo returns accurate information.
504
- return Some ( cmp:: min ( 60 , width) ) ;
512
+ return TtyWidth :: Guess ( cmp:: min ( 60 , width) ) ;
505
513
}
506
- None
514
+
515
+ TtyWidth :: NoTty
507
516
}
508
517
}
509
518
}
510
519
511
520
#[ cfg( windows) ]
512
521
fn 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
+ _ => ( ) ,
516
528
}
517
529
}
0 commit comments