@@ -66,6 +66,7 @@ pub struct Renderer {
66
66
term_width : usize ,
67
67
theme : OutputTheme ,
68
68
stylesheet : Stylesheet ,
69
+ short_message : bool ,
69
70
}
70
71
71
72
impl Renderer {
@@ -76,6 +77,7 @@ impl Renderer {
76
77
term_width : DEFAULT_TERM_WIDTH ,
77
78
theme : OutputTheme :: Ascii ,
78
79
stylesheet : Stylesheet :: plain ( ) ,
80
+ short_message : false ,
79
81
}
80
82
}
81
83
@@ -137,6 +139,11 @@ impl Renderer {
137
139
self
138
140
}
139
141
142
+ pub const fn short_message ( mut self , short_message : bool ) -> Self {
143
+ self . short_message = short_message;
144
+ self
145
+ }
146
+
140
147
// Set the terminal width
141
148
pub const fn term_width ( mut self , term_width : usize ) -> Self {
142
149
self . term_width = term_width;
@@ -199,19 +206,23 @@ impl Renderer {
199
206
200
207
impl Renderer {
201
208
pub fn render ( & self , mut message : Message < ' _ > ) -> String {
202
- let max_line_num_len = if self . anonymized_line_numbers {
203
- ANONYMIZED_LINE_NUM . len ( )
209
+ if self . short_message {
210
+ self . render_short_message ( message ) . unwrap ( )
204
211
} else {
205
- let n = message. max_line_number ( ) ;
206
- num_decimal_digits ( n)
207
- } ;
208
- let title = message. groups . remove ( 0 ) . elements . remove ( 0 ) ;
209
- if let Some ( first) = message. groups . first_mut ( ) {
210
- first. elements . insert ( 0 , title) ;
211
- } else {
212
- message. groups . push ( Group :: new ( ) . element ( title) ) ;
212
+ let max_line_num_len = if self . anonymized_line_numbers {
213
+ ANONYMIZED_LINE_NUM . len ( )
214
+ } else {
215
+ let n = message. max_line_number ( ) ;
216
+ num_decimal_digits ( n)
217
+ } ;
218
+ let title = message. groups . remove ( 0 ) . elements . remove ( 0 ) ;
219
+ if let Some ( first) = message. groups . first_mut ( ) {
220
+ first. elements . insert ( 0 , title) ;
221
+ } else {
222
+ message. groups . push ( Group :: new ( ) . element ( title) ) ;
223
+ }
224
+ self . render_message ( message, max_line_num_len) . unwrap ( )
213
225
}
214
- self . render_message ( message, max_line_num_len) . unwrap ( )
215
226
}
216
227
217
228
fn render_message (
@@ -320,6 +331,7 @@ impl Renderer {
320
331
( true , false ) => TitleStyle :: Header ,
321
332
( false , _) => TitleStyle :: Secondary ,
322
333
} ;
334
+ let buffer_msg_line_offset = buffer. num_lines ( ) ;
323
335
self . render_title (
324
336
& mut buffer,
325
337
title,
@@ -333,6 +345,7 @@ impl Renderer {
333
345
}
334
346
} ) ,
335
347
matches ! ( peek, Some ( Element :: Title ( _) ) ) ,
348
+ buffer_msg_line_offset,
336
349
) ;
337
350
last_was_suggestion = false ;
338
351
}
@@ -390,7 +403,13 @@ impl Renderer {
390
403
}
391
404
392
405
Element :: Origin ( origin) => {
393
- self . render_origin ( & mut buffer, max_line_num_len, origin) ;
406
+ let buffer_msg_line_offset = buffer. num_lines ( ) ;
407
+ self . render_origin (
408
+ & mut buffer,
409
+ max_line_num_len,
410
+ origin,
411
+ buffer_msg_line_offset,
412
+ ) ;
394
413
last_was_suggestion = false ;
395
414
}
396
415
Element :: Padding ( _) => {
@@ -434,6 +453,91 @@ impl Renderer {
434
453
Ok ( out_string)
435
454
}
436
455
456
+ fn render_short_message ( & self , mut message : Message < ' _ > ) -> Result < String , fmt:: Error > {
457
+ let mut buffer = StyledBuffer :: new ( ) ;
458
+
459
+ let Element :: Title ( title) = message. groups . remove ( 0 ) . elements . remove ( 0 ) else {
460
+ panic ! (
461
+ "Expected first element to be a Title, got: {:?}" ,
462
+ message. groups
463
+ ) ;
464
+ } ;
465
+
466
+ let mut labels = None ;
467
+
468
+ if let Some ( Element :: Cause ( cause) ) = message. groups . first ( ) . and_then ( |group| {
469
+ group
470
+ . elements
471
+ . iter ( )
472
+ . find ( |e| matches ! ( e, Element :: Cause ( _) ) )
473
+ } ) {
474
+ let labels_inner = cause
475
+ . markers
476
+ . iter ( )
477
+ . filter_map ( |ann| match ann. label {
478
+ Some ( msg) if ann. kind . is_primary ( ) => {
479
+ if !msg. trim ( ) . is_empty ( ) {
480
+ Some ( msg. to_owned ( ) )
481
+ } else {
482
+ None
483
+ }
484
+ }
485
+ _ => None ,
486
+ } )
487
+ . collect :: < Vec < _ > > ( )
488
+ . join ( ", " ) ;
489
+ if !labels_inner. is_empty ( ) {
490
+ labels = Some ( labels_inner) ;
491
+ }
492
+
493
+ if let Some ( origin) = cause. origin {
494
+ let mut origin = Origin :: new ( origin) ;
495
+ origin. primary = true ;
496
+
497
+ let source_map = SourceMap :: new ( cause. source , cause. line_start ) ;
498
+ let ( _depth, annotated_lines) =
499
+ source_map. annotated_lines ( cause. markers . clone ( ) , cause. fold ) ;
500
+
501
+ if let Some ( primary_line) = annotated_lines
502
+ . iter ( )
503
+ . find ( |l| l. annotations . iter ( ) . any ( LineAnnotation :: is_primary) )
504
+ . or ( annotated_lines. iter ( ) . find ( |l| !l. annotations . is_empty ( ) ) )
505
+ {
506
+ origin. line = Some ( primary_line. line_index ) ;
507
+ if let Some ( first_annotation) = primary_line
508
+ . annotations
509
+ . iter ( )
510
+ . min_by_key ( |a| ( Reverse ( a. is_primary ( ) ) , a. start . char ) )
511
+ {
512
+ origin. char_column = Some ( first_annotation. start . char + 1 ) ;
513
+ }
514
+ }
515
+
516
+ self . render_origin ( & mut buffer, 0 , & origin, 0 ) ;
517
+ buffer. append ( 0 , ": " , ElementStyle :: LineAndColumn ) ;
518
+ }
519
+ }
520
+
521
+ self . render_title (
522
+ & mut buffer,
523
+ & title,
524
+ 0 , // No line numbers in short messages
525
+ TitleStyle :: MainHeader ,
526
+ message. id . as_ref ( ) ,
527
+ false ,
528
+ 0 ,
529
+ ) ;
530
+
531
+ if let Some ( labels) = labels {
532
+ buffer. append ( 0 , & format ! ( ": {labels}" ) , ElementStyle :: NoStyle ) ;
533
+ }
534
+
535
+ let mut out_string = String :: new ( ) ;
536
+ buffer. render ( title. level , & self . stylesheet , & mut out_string) ?;
537
+
538
+ Ok ( out_string)
539
+ }
540
+
437
541
#[ allow( clippy:: too_many_arguments) ]
438
542
fn render_title (
439
543
& self ,
@@ -443,23 +547,27 @@ impl Renderer {
443
547
title_style : TitleStyle ,
444
548
id : Option < & & str > ,
445
549
is_cont : bool ,
550
+ buffer_msg_line_offset : usize ,
446
551
) {
447
- let line_offset = buffer. num_lines ( ) ;
448
-
449
552
if title_style == TitleStyle :: Secondary {
450
553
// This is a secondary message with no span info
451
554
for _ in 0 ..max_line_num_len {
452
- buffer. prepend ( line_offset , " " , ElementStyle :: NoStyle ) ;
555
+ buffer. prepend ( buffer_msg_line_offset , " " , ElementStyle :: NoStyle ) ;
453
556
}
454
557
455
558
if title. level . name != Some ( None ) {
456
- self . draw_note_separator ( buffer, line_offset, max_line_num_len + 1 , is_cont) ;
559
+ self . draw_note_separator (
560
+ buffer,
561
+ buffer_msg_line_offset,
562
+ max_line_num_len + 1 ,
563
+ is_cont,
564
+ ) ;
457
565
buffer. append (
458
- line_offset ,
566
+ buffer_msg_line_offset ,
459
567
title. level . as_str ( ) ,
460
568
ElementStyle :: MainHeaderMsg ,
461
569
) ;
462
- buffer. append ( line_offset , ": " , ElementStyle :: NoStyle ) ;
570
+ buffer. append ( buffer_msg_line_offset , ": " , ElementStyle :: NoStyle ) ;
463
571
}
464
572
465
573
let printed_lines =
@@ -476,7 +584,7 @@ impl Renderer {
476
584
// │ bar
477
585
// ╰ note: foo
478
586
// bar
479
- for i in line_offset + 1 ..=printed_lines {
587
+ for i in buffer_msg_line_offset + 1 ..=printed_lines {
480
588
self . draw_col_separator_no_space ( buffer, i, max_line_num_len + 1 ) ;
481
589
}
482
590
}
@@ -485,31 +593,49 @@ impl Renderer {
485
593
486
594
if title. level . name != Some ( None ) {
487
595
buffer. append (
488
- line_offset ,
596
+ buffer_msg_line_offset ,
489
597
title. level . as_str ( ) ,
490
598
ElementStyle :: Level ( title. level . level ) ,
491
599
) ;
492
600
}
493
601
label_width += title. level . as_str ( ) . len ( ) ;
494
602
if let Some ( id) = id {
495
- buffer. append ( line_offset, "[" , ElementStyle :: Level ( title. level . level ) ) ;
496
- buffer. append ( line_offset, id, ElementStyle :: Level ( title. level . level ) ) ;
497
- buffer. append ( line_offset, "]" , ElementStyle :: Level ( title. level . level ) ) ;
603
+ buffer. append (
604
+ buffer_msg_line_offset,
605
+ "[" ,
606
+ ElementStyle :: Level ( title. level . level ) ,
607
+ ) ;
608
+ buffer. append (
609
+ buffer_msg_line_offset,
610
+ id,
611
+ ElementStyle :: Level ( title. level . level ) ,
612
+ ) ;
613
+ buffer. append (
614
+ buffer_msg_line_offset,
615
+ "]" ,
616
+ ElementStyle :: Level ( title. level . level ) ,
617
+ ) ;
498
618
label_width += 2 + id. len ( ) ;
499
619
}
500
620
let header_style = match title_style {
501
- TitleStyle :: MainHeader => ElementStyle :: MainHeaderMsg ,
621
+ TitleStyle :: MainHeader => {
622
+ if self . short_message {
623
+ ElementStyle :: NoStyle
624
+ } else {
625
+ ElementStyle :: MainHeaderMsg
626
+ }
627
+ }
502
628
TitleStyle :: Header => ElementStyle :: HeaderMsg ,
503
629
TitleStyle :: Secondary => unreachable ! ( ) ,
504
630
} ;
505
631
if title. level . name != Some ( None ) {
506
- buffer. append ( line_offset , ": " , header_style) ;
632
+ buffer. append ( buffer_msg_line_offset , ": " , header_style) ;
507
633
label_width += 2 ;
508
634
}
509
635
if !title. title . is_empty ( ) {
510
636
for ( line, text) in normalize_whitespace ( title. title ) . lines ( ) . enumerate ( ) {
511
637
buffer. append (
512
- line_offset + line,
638
+ buffer_msg_line_offset + line,
513
639
& format ! (
514
640
"{}{}" ,
515
641
if line == 0 {
@@ -600,15 +726,15 @@ impl Renderer {
600
726
buffer : & mut StyledBuffer ,
601
727
max_line_num_len : usize ,
602
728
origin : & Origin < ' _ > ,
729
+ buffer_msg_line_offset : usize ,
603
730
) {
604
- let buffer_msg_line_offset = buffer. num_lines ( ) ;
605
- if origin. primary {
731
+ if origin. primary && !self . short_message {
606
732
buffer. prepend (
607
733
buffer_msg_line_offset,
608
734
self . file_start ( ) ,
609
735
ElementStyle :: LineNumber ,
610
736
) ;
611
- } else {
737
+ } else if ! self . short_message {
612
738
// if !origin.standalone {
613
739
// // Add spacing line, as shown:
614
740
// // --> $DIR/file:54:15
@@ -643,9 +769,12 @@ impl Renderer {
643
769
( Some ( line) , None ) => format ! ( "{}:{}" , origin. origin, line) ,
644
770
_ => origin. origin . to_owned ( ) ,
645
771
} ;
772
+
646
773
buffer. append ( buffer_msg_line_offset, & str, ElementStyle :: LineAndColumn ) ;
647
- for _ in 0 ..max_line_num_len {
648
- buffer. prepend ( buffer_msg_line_offset, " " , ElementStyle :: NoStyle ) ;
774
+ if !self . short_message {
775
+ for _ in 0 ..max_line_num_len {
776
+ buffer. prepend ( buffer_msg_line_offset, " " , ElementStyle :: NoStyle ) ;
777
+ }
649
778
}
650
779
}
651
780
@@ -707,7 +836,8 @@ impl Renderer {
707
836
}
708
837
}
709
838
}
710
- self . render_origin ( buffer, max_line_num_len, & origin) ;
839
+ let buffer_msg_line_offset = buffer. num_lines ( ) ;
840
+ self . render_origin ( buffer, max_line_num_len, & origin, buffer_msg_line_offset) ;
711
841
}
712
842
713
843
// Put in the spacer between the location and annotated source
0 commit comments