Skip to content

Commit 24c8eaa

Browse files
authored
Merge pull request #229 from Muscraft/align-seconday-titles
fix: Align multi-line secondary titles by level text
2 parents 3f45b4d + e7c3b6b commit 24c8eaa

File tree

2 files changed

+125
-28
lines changed

2 files changed

+125
-28
lines changed

src/renderer/mod.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -555,23 +555,44 @@ impl Renderer {
555555
buffer.prepend(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
556556
}
557557

558-
if title.level.name != Some(None) {
559-
self.draw_note_separator(
560-
buffer,
561-
buffer_msg_line_offset,
562-
max_line_num_len + 1,
563-
is_cont,
564-
);
558+
self.draw_note_separator(
559+
buffer,
560+
buffer_msg_line_offset,
561+
max_line_num_len + 1,
562+
is_cont,
563+
);
564+
565+
let label_width = if title.level.name != Some(None) {
565566
buffer.append(
566567
buffer_msg_line_offset,
567568
title.level.as_str(),
568569
ElementStyle::MainHeaderMsg,
569570
);
570571
buffer.append(buffer_msg_line_offset, ": ", ElementStyle::NoStyle);
571-
}
572+
title.level.as_str().len() + 2
573+
} else {
574+
0
575+
};
576+
// The extra 3 ` ` is padding that's always needed to align to the
577+
// label i.e. `note: `:
578+
//
579+
// error: message
580+
// --> file.rs:13:20
581+
// |
582+
// 13 | <CODE>
583+
// | ^^^^
584+
// |
585+
// = note: multiline
586+
// message
587+
// ++^^^------
588+
// | | |
589+
// | | |
590+
// | | width of label
591+
// | magic `3`
592+
// `max_line_num_len`
593+
let padding = max_line_num_len + 3 + label_width;
572594

573-
let printed_lines =
574-
self.msgs_to_buffer(buffer, title.title, max_line_num_len, "note", None);
595+
let printed_lines = self.msgs_to_buffer(buffer, title.title, padding, None);
575596
if is_cont && matches!(self.theme, OutputTheme::Unicode) {
576597
// There's another note after this one, associated to the subwindow above.
577598
// We write additional vertical lines to join them:
@@ -659,26 +680,9 @@ impl Renderer {
659680
buffer: &mut StyledBuffer,
660681
title: &str,
661682
padding: usize,
662-
label: &str,
663683
override_style: Option<ElementStyle>,
664684
) -> usize {
665-
// The extra 5 ` ` is padding that's always needed to align to the `note: `:
666-
//
667-
// error: message
668-
// --> file.rs:13:20
669-
// |
670-
// 13 | <CODE>
671-
// | ^^^^
672-
// |
673-
// = note: multiline
674-
// message
675-
// ++^^^----xx
676-
// | | | |
677-
// | | | magic `2`
678-
// | | length of label
679-
// | magic `3`
680-
// `max_line_num_len`
681-
let padding = " ".repeat(padding + label.len() + 5);
685+
let padding = " ".repeat(padding);
682686

683687
let mut line_number = buffer.num_lines().saturating_sub(1);
684688

tests/formatter.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,3 +2494,96 @@ LL │ �|�␂!5�cc␕␂�Ӻi��WWj�ȥ�'�}�␒�J�ȉ��W
24942494
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
24952495
assert_data_eq!(renderer_unicode.render(input), expected_unicode);
24962496
}
2497+
2498+
#[test]
2499+
fn secondary_title_no_level_text() {
2500+
let source = r#"fn main() {
2501+
let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types
2502+
let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
2503+
}"#;
2504+
2505+
let input = Level::ERROR.header("mismatched types").id("E0308").group(
2506+
Group::new()
2507+
.element(
2508+
Snippet::source(source)
2509+
.path("$DIR/mismatched-types.rs")
2510+
.fold(true)
2511+
.annotation(
2512+
AnnotationKind::Primary
2513+
.span(105..131)
2514+
.label("expected `&str`, found `&[u8; 0]`"),
2515+
)
2516+
.annotation(
2517+
AnnotationKind::Context
2518+
.span(98..102)
2519+
.label("expected due to this"),
2520+
),
2521+
)
2522+
.element(
2523+
Level::NOTE
2524+
.text(None)
2525+
.title("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
2526+
),
2527+
);
2528+
2529+
let expected = str![[r#"
2530+
error[E0308]: mismatched types
2531+
--> $DIR/mismatched-types.rs:3:19
2532+
|
2533+
LL | let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
2534+
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `&[u8; 0]`
2535+
| |
2536+
| expected due to this
2537+
= expected reference `&str`
2538+
found reference `&'static [u8; 0]`
2539+
"#]];
2540+
let renderer = Renderer::plain().anonymized_line_numbers(true);
2541+
assert_data_eq!(renderer.render(input), expected);
2542+
}
2543+
2544+
#[test]
2545+
fn secondary_title_custom_level_text() {
2546+
let source = r#"fn main() {
2547+
let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types
2548+
let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
2549+
}"#;
2550+
2551+
let input = Level::ERROR.header("mismatched types").id("E0308").group(
2552+
Group::new()
2553+
.element(
2554+
Snippet::source(source)
2555+
.path("$DIR/mismatched-types.rs")
2556+
.fold(true)
2557+
.annotation(
2558+
AnnotationKind::Primary
2559+
.span(105..131)
2560+
.label("expected `&str`, found `&[u8; 0]`"),
2561+
)
2562+
.annotation(
2563+
AnnotationKind::Context
2564+
.span(98..102)
2565+
.label("expected due to this"),
2566+
),
2567+
)
2568+
.element(
2569+
Level::NOTE
2570+
.text(Some("custom"))
2571+
.title("expected reference `&str`\nfound reference `&'static [u8; 0]`"),
2572+
),
2573+
);
2574+
2575+
let expected = str![[r#"
2576+
error[E0308]: mismatched types
2577+
--> $DIR/mismatched-types.rs:3:19
2578+
|
2579+
LL | let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types
2580+
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `&[u8; 0]`
2581+
| |
2582+
| expected due to this
2583+
|
2584+
= custom: expected reference `&str`
2585+
found reference `&'static [u8; 0]`
2586+
"#]];
2587+
let renderer = Renderer::plain().anonymized_line_numbers(true);
2588+
assert_data_eq!(renderer.render(input), expected);
2589+
}

0 commit comments

Comments
 (0)