@@ -43,7 +43,7 @@ use checkstyle::{output_footer, output_header};
43
43
use config:: Config ;
44
44
use filemap:: FileMap ;
45
45
use issues:: { BadIssueSeeker , Issue } ;
46
- use utils:: { mk_sp, outer_attributes} ;
46
+ use utils:: { isatty , mk_sp, outer_attributes} ;
47
47
use visitor:: FmtVisitor ;
48
48
49
49
pub use self :: summary:: Summary ;
@@ -532,6 +532,76 @@ impl FormatReport {
532
532
pub fn has_warnings ( & self ) -> bool {
533
533
self . warning_count ( ) > 0
534
534
}
535
+
536
+ pub fn print_warnings_fancy (
537
+ & self ,
538
+ mut t : Box < term:: Terminal < Output = io:: Stderr > > ,
539
+ ) -> Result < ( ) , term:: Error > {
540
+ for ( file, errors) in & self . file_error_map {
541
+ for error in errors {
542
+ let prefix_space_len = error. line . to_string ( ) . len ( ) ;
543
+ let prefix_spaces: String = repeat ( " " ) . take ( 1 + prefix_space_len) . collect ( ) ;
544
+
545
+ // First line: the overview of error
546
+ t. fg ( term:: color:: RED ) ?;
547
+ t. attr ( term:: Attr :: Bold ) ?;
548
+ write ! ( t, "{} " , error. msg_prefix( ) ) ?;
549
+ t. reset ( ) ?;
550
+ t. attr ( term:: Attr :: Bold ) ?;
551
+ write ! ( t, "{}\n " , error. kind) ?;
552
+
553
+ // Second line: file info
554
+ write ! ( t, "{}--> " , & prefix_spaces[ 1 ..] ) ?;
555
+ t. reset ( ) ?;
556
+ write ! ( t, "{}:{}\n " , file, error. line) ?;
557
+
558
+ // Third to fifth lines: show the line which triggered error, if available.
559
+ if !error. line_buffer . is_empty ( ) {
560
+ let ( space_len, target_len) = error. format_len ( ) ;
561
+ t. attr ( term:: Attr :: Bold ) ?;
562
+ write ! ( t, "{}|\n {} | " , prefix_spaces, error. line) ?;
563
+ t. reset ( ) ?;
564
+ write ! ( t, "{}\n " , error. line_buffer) ?;
565
+ t. attr ( term:: Attr :: Bold ) ?;
566
+ write ! ( t, "{}| " , prefix_spaces) ?;
567
+ t. fg ( term:: color:: RED ) ?;
568
+ write ! ( t, "{}\n " , target_str( space_len, target_len) ) ?;
569
+ t. reset ( ) ?;
570
+ }
571
+
572
+ // The last line: show note if available.
573
+ let msg_suffix = error. msg_suffix ( ) ;
574
+ if !msg_suffix. is_empty ( ) {
575
+ t. attr ( term:: Attr :: Bold ) ?;
576
+ write ! ( t, "{}= note: " , prefix_spaces) ?;
577
+ t. reset ( ) ?;
578
+ write ! ( t, "{}\n " , error. msg_suffix( ) ) ?;
579
+ } else {
580
+ write ! ( t, "\n " ) ?;
581
+ }
582
+ t. reset ( ) ?;
583
+ }
584
+ }
585
+
586
+ if !self . file_error_map . is_empty ( ) {
587
+ t. attr ( term:: Attr :: Bold ) ?;
588
+ write ! ( t, "warning: " ) ?;
589
+ t. reset ( ) ?;
590
+ write ! (
591
+ t,
592
+ "rustfmt may have failed to format. See previous {} errors.\n \n " ,
593
+ self . warning_count( ) ,
594
+ ) ?;
595
+ }
596
+
597
+ Ok ( ( ) )
598
+ }
599
+ }
600
+
601
+ fn target_str ( space_len : usize , target_len : usize ) -> String {
602
+ let empty_line: String = repeat ( " " ) . take ( space_len) . collect ( ) ;
603
+ let overflowed: String = repeat ( "^" ) . take ( target_len) . collect ( ) ;
604
+ empty_line + & overflowed
535
605
}
536
606
537
607
impl fmt:: Display for FormatReport {
@@ -867,7 +937,15 @@ pub fn run(input: Input, config: &Config) -> Summary {
867
937
output_footer ( out, config. write_mode ( ) ) . ok ( ) ;
868
938
869
939
if report. has_warnings ( ) {
870
- msg ! ( "{}" , report) ;
940
+ match term:: stderr ( ) {
941
+ Some ( ref t) if isatty ( ) && t. supports_color ( ) => {
942
+ match report. print_warnings_fancy ( term:: stderr ( ) . unwrap ( ) ) {
943
+ Ok ( ..) => ( ) ,
944
+ Err ( ..) => panic ! ( "Unable to write to stderr: {}" , report) ,
945
+ }
946
+ }
947
+ _ => msg ! ( "{}" , report) ,
948
+ }
871
949
}
872
950
873
951
summary
0 commit comments