Skip to content

Commit b7989e6

Browse files
authored
Merge pull request #264 from Muscraft/file-start-continuation
fix: Draw file start continuation if not first in group
2 parents dc65194 + 645746b commit b7989e6

File tree

2 files changed

+94
-10
lines changed

2 files changed

+94
-10
lines changed

src/renderer/mod.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,10 @@ impl Renderer {
263263
source_map_annotated_lines.push_back((source_map, annotated_lines));
264264
}
265265
}
266-
let mut message_iter = group.elements.iter().peekable();
266+
let mut message_iter = group.elements.iter().enumerate().peekable();
267267
let mut last_was_suggestion = false;
268268
if let Some(title) = &group.title {
269-
let peek = message_iter.peek().copied();
269+
let peek = message_iter.peek().map(|(_, s)| s).copied();
270270
let title_style = if g == 0 {
271271
TitleStyle::MainHeader
272272
} else {
@@ -299,8 +299,9 @@ impl Renderer {
299299
}
300300
}
301301
let mut seen_primary = false;
302-
while let Some(section) = message_iter.next() {
303-
let peek = message_iter.peek().copied();
302+
while let Some((i, section)) = message_iter.next() {
303+
let peek = message_iter.peek().map(|(_, s)| s).copied();
304+
let is_first = i == 0;
304305
match &section {
305306
Element::Message(title) => {
306307
let title_style = TitleStyle::Secondary;
@@ -331,6 +332,7 @@ impl Renderer {
331332
&annotated_lines,
332333
max_depth,
333334
peek.is_some() || (g == 0 && group_len > 1),
335+
is_first,
334336
);
335337

336338
if g == 0 {
@@ -365,6 +367,7 @@ impl Renderer {
365367
&source_map,
366368
primary_path.or(og_primary_path),
367369
last_was_suggestion,
370+
is_first,
368371
);
369372
last_was_suggestion = true;
370373
}
@@ -378,6 +381,7 @@ impl Renderer {
378381
max_line_num_len,
379382
origin,
380383
is_primary,
384+
is_first,
381385
buffer_msg_line_offset,
382386
);
383387
last_was_suggestion = false;
@@ -484,7 +488,7 @@ impl Renderer {
484488
}
485489
}
486490

487-
self.render_origin(&mut buffer, 0, &origin, true, 0);
491+
self.render_origin(&mut buffer, 0, &origin, true, true, 0);
488492
buffer.append(0, ": ", ElementStyle::LineAndColumn);
489493
}
490494
}
@@ -633,12 +637,13 @@ impl Renderer {
633637
max_line_num_len: usize,
634638
origin: &Origin<'_>,
635639
is_primary: bool,
640+
is_first: bool,
636641
buffer_msg_line_offset: usize,
637642
) {
638643
if is_primary && !self.short_message {
639644
buffer.prepend(
640645
buffer_msg_line_offset,
641-
self.file_start(),
646+
self.file_start(is_first),
642647
ElementStyle::LineNumber,
643648
);
644649
} else if !self.short_message {
@@ -696,6 +701,7 @@ impl Renderer {
696701
annotated_lines: &[AnnotatedLineInfo<'_>],
697702
multiline_depth: usize,
698703
is_cont: bool,
704+
is_first: bool,
699705
) {
700706
if let Some(path) = &snippet.path {
701707
let mut origin = Origin::path(path.as_ref());
@@ -748,6 +754,7 @@ impl Renderer {
748754
max_line_num_len,
749755
&origin,
750756
is_primary,
757+
is_first,
751758
buffer_msg_line_offset,
752759
);
753760
// Put in the spacer between the location and annotated source
@@ -763,7 +770,7 @@ impl Renderer {
763770
buffer.puts(
764771
buffer_msg_line_offset,
765772
max_line_num_len,
766-
self.file_start(),
773+
self.file_start(is_first),
767774
ElementStyle::LineNumber,
768775
);
769776
} else {
@@ -1599,6 +1606,7 @@ impl Renderer {
15991606
.collect::<Vec<_>>()
16001607
}
16011608

1609+
#[allow(clippy::too_many_arguments)]
16021610
fn emit_suggestion_default(
16031611
&self,
16041612
buffer: &mut StyledBuffer,
@@ -1607,6 +1615,7 @@ impl Renderer {
16071615
sm: &SourceMap<'_>,
16081616
primary_path: Option<&Cow<'_, str>>,
16091617
is_cont: bool,
1618+
is_first: bool,
16101619
) {
16111620
let suggestions = sm.splice_lines(suggestion.markers.clone());
16121621

@@ -1633,7 +1642,7 @@ impl Renderer {
16331642
let (loc, _) = sm.span_to_locations(parts[0].span.clone());
16341643
// --> file.rs:line:col
16351644
// |
1636-
let arrow = self.file_start();
1645+
let arrow = self.file_start(is_first);
16371646
buffer.puts(row_num - 1, 0, arrow, ElementStyle::LineNumber);
16381647
let message = format!("{}:{}:{}", path, loc.line, loc.char + 1);
16391648
if is_cont {
@@ -2444,10 +2453,11 @@ impl Renderer {
24442453
)
24452454
}
24462455

2447-
fn file_start(&self) -> &'static str {
2456+
fn file_start(&self, is_first: bool) -> &'static str {
24482457
match self.theme {
24492458
OutputTheme::Ascii => "--> ",
2450-
OutputTheme::Unicode => " ╭▸ ",
2459+
OutputTheme::Unicode if is_first => " ╭▸ ",
2460+
OutputTheme::Unicode => " ├▸ ",
24512461
}
24522462
}
24532463

tests/formatter.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,3 +3075,77 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
30753075
let renderer = Renderer::plain();
30763076
assert_data_eq!(renderer.render(input_new), expected);
30773077
}
3078+
3079+
#[test]
3080+
fn message_before_primary_snippet() {
3081+
let source = r#"struct Thing {
3082+
a0: Foo,
3083+
a1: Foo,
3084+
a2: Foo,
3085+
a3: Foo,
3086+
a4: Foo,
3087+
a5: Foo,
3088+
a6: Foo,
3089+
a7: Foo,
3090+
a8: Foo,
3091+
a9: Foo,
3092+
}
3093+
3094+
struct Foo {
3095+
field: Field,
3096+
}
3097+
3098+
struct Field;
3099+
3100+
impl Foo {
3101+
fn bar(&self) {}
3102+
}
3103+
3104+
fn bar(t: Thing) {
3105+
t.bar();
3106+
t.field;
3107+
}
3108+
3109+
fn main() {}
3110+
"#;
3111+
3112+
let input = &[Group::with_title(
3113+
Level::ERROR
3114+
.title("no field `field` on type `Thing`")
3115+
.id("E0609"),
3116+
)
3117+
.element(Level::NOTE.message("a `Title` then a `Message`!?!?"))
3118+
.element(
3119+
Snippet::source(source)
3120+
.path("$DIR/too-many-field-suggestions.rs")
3121+
.annotation(
3122+
AnnotationKind::Primary
3123+
.span(270..275)
3124+
.label("unknown field"),
3125+
),
3126+
)];
3127+
3128+
let expected_ascii = str![[r#"
3129+
error[E0609]: no field `field` on type `Thing`
3130+
|
3131+
= note: a `Title` then a `Message`!?!?
3132+
--> $DIR/too-many-field-suggestions.rs:26:7
3133+
|
3134+
LL | t.field;
3135+
| ^^^^^ unknown field
3136+
"#]];
3137+
let renderer = Renderer::plain().anonymized_line_numbers(true);
3138+
assert_data_eq!(renderer.render(input), expected_ascii);
3139+
3140+
let expected_unicode = str![[r#"
3141+
error[E0609]: no field `field` on type `Thing`
3142+
3143+
├ note: a `Title` then a `Message`!?!?
3144+
├▸ $DIR/too-many-field-suggestions.rs:26:7
3145+
3146+
LL │ t.field;
3147+
╰╴ ━━━━━ unknown field
3148+
"#]];
3149+
let renderer = renderer.theme(OutputTheme::Unicode);
3150+
assert_data_eq!(renderer.render(input), expected_unicode);
3151+
}

0 commit comments

Comments
 (0)