Skip to content

Commit f835cca

Browse files
authored
Merge pull request #211 from Muscraft/fix-primary-color
Color Primary annotations by their group level
2 parents f3b6eb8 + 33f44ae commit f835cca

File tree

4 files changed

+99
-55
lines changed

4 files changed

+99
-55
lines changed

examples/highlight_title.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ fn main() {
55
let source = r#"// Make sure "highlighted" code is colored purple
66
77
//@ compile-flags: --error-format=human --color=always
8-
//@ error-pattern:for<'a> 
98
//@ edition:2018
109
1110
use core::pin::Pin;
@@ -24,8 +23,7 @@ fn wrapped_fn<'a>(_: Box<(dyn Any + Send)>) -> Pin<Box<(
2423
2524
fn main() {
2625
query(wrapped_fn);
27-
}
28-
"#;
26+
}"#;
2927

3028
let magenta = annotate_snippets::renderer::AnsiColor::Magenta
3129
.on_default()
@@ -43,25 +41,39 @@ fn main() {
4341
magenta.render_reset()
4442
);
4543

46-
let message = Level::ERROR.header("mismatched types").id("E0308").group(
47-
Group::new()
48-
.element(
49-
Snippet::source(source)
50-
.fold(true)
51-
.origin("$DIR/highlighting.rs")
52-
.annotation(
53-
AnnotationKind::Primary
54-
.span(589..599)
55-
.label("one type is more general than the other"),
56-
)
57-
.annotation(
58-
AnnotationKind::Context
59-
.span(583..588)
60-
.label("arguments to this function are incorrect"),
61-
),
62-
)
63-
.element(Level::NOTE.title(&title)),
64-
);
44+
let message = Level::ERROR
45+
.header("mismatched types")
46+
.id("E0308")
47+
.group(
48+
Group::new()
49+
.element(
50+
Snippet::source(source)
51+
.fold(true)
52+
.origin("$DIR/highlighting.rs")
53+
.annotation(
54+
AnnotationKind::Primary
55+
.span(553..563)
56+
.label("one type is more general than the other"),
57+
)
58+
.annotation(
59+
AnnotationKind::Context
60+
.span(547..552)
61+
.label("arguments to this function are incorrect"),
62+
),
63+
)
64+
.element(Level::NOTE.title(&title)),
65+
)
66+
.group(
67+
Group::new()
68+
.element(Level::NOTE.title("function defined here"))
69+
.element(
70+
Snippet::source(source)
71+
.fold(true)
72+
.origin("$DIR/highlighting.rs")
73+
.annotation(AnnotationKind::Context.span(200..333).label(""))
74+
.annotation(AnnotationKind::Primary.span(194..199)),
75+
),
76+
);
6577

6678
let renderer = Renderer::styled().anonymized_line_numbers(true);
6779
anstream::println!("{}", renderer.render(message));

examples/highlight_title.svg

Lines changed: 24 additions & 5 deletions
Loading

src/renderer/mod.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use margin::Margin;
5252
use std::borrow::Cow;
5353
use std::cmp::{max, min, Ordering, Reverse};
5454
use std::collections::{HashMap, VecDeque};
55+
use std::fmt;
5556
use std::ops::Range;
5657
use stylesheet::Stylesheet;
5758

@@ -198,35 +199,28 @@ impl Renderer {
198199

199200
impl Renderer {
200201
pub fn render(&self, mut message: Message<'_>) -> String {
201-
let mut buffer = StyledBuffer::new();
202202
let max_line_num_len = if self.anonymized_line_numbers {
203203
ANONYMIZED_LINE_NUM.len()
204204
} else {
205205
let n = message.max_line_number();
206206
num_decimal_digits(n)
207207
};
208208
let title = message.groups.remove(0).elements.remove(0);
209-
let level = if let Element::Title(title) = &title {
210-
title.level.clone()
211-
} else {
212-
panic!("Expected a title as the first element of the message")
213-
};
214209
if let Some(first) = message.groups.first_mut() {
215210
first.elements.insert(0, title);
216211
} else {
217212
message.groups.push(Group::new().element(title));
218213
}
219-
self.render_message(&mut buffer, message, max_line_num_len);
220-
221-
buffer.render(level, &self.stylesheet).unwrap()
214+
self.render_message(message, max_line_num_len).unwrap()
222215
}
223216

224217
fn render_message(
225218
&self,
226-
buffer: &mut StyledBuffer,
227219
message: Message<'_>,
228220
max_line_num_len: usize,
229-
) {
221+
) -> Result<String, fmt::Error> {
222+
let mut out_string = String::new();
223+
230224
let og_primary_origin = message
231225
.groups
232226
.iter()
@@ -264,6 +258,7 @@ impl Renderer {
264258
);
265259
let group_len = message.groups.len();
266260
for (g, group) in message.groups.into_iter().enumerate() {
261+
let mut buffer = StyledBuffer::new();
267262
let primary_origin = group
268263
.elements
269264
.iter()
@@ -295,6 +290,14 @@ impl Renderer {
295290
})
296291
.unwrap_or_default(),
297292
);
293+
let level = group
294+
.elements
295+
.iter()
296+
.find_map(|s| match &s {
297+
Element::Title(title) => Some(title.level.clone()),
298+
_ => None,
299+
})
300+
.unwrap_or(Level::ERROR);
298301
let mut source_map_annotated_lines = VecDeque::new();
299302
let mut max_depth = 0;
300303
for e in &group.elements {
@@ -313,7 +316,7 @@ impl Renderer {
313316
match &section {
314317
Element::Title(title) => {
315318
self.render_title(
316-
buffer,
319+
&mut buffer,
317320
title,
318321
peek,
319322
max_line_num_len,
@@ -334,7 +337,7 @@ impl Renderer {
334337
source_map_annotated_lines.pop_front()
335338
{
336339
self.render_snippet_annotations(
337-
buffer,
340+
&mut buffer,
338341
max_line_num_len,
339342
cause,
340343
primary_origin,
@@ -345,19 +348,20 @@ impl Renderer {
345348
);
346349

347350
if g == 0 && group_len > 1 {
351+
let current_line = buffer.num_lines();
348352
if matches!(peek, Some(Element::Title(level)) if level.level.name != Some(None))
349353
{
350354
self.draw_col_separator_no_space(
351-
buffer,
352-
buffer.num_lines(),
355+
&mut buffer,
356+
current_line,
353357
max_line_num_len + 1,
354358
);
355359
// We want to draw the separator when it is
356360
// requested, or when it is the last element
357361
} else if peek.is_none() {
358362
self.draw_col_separator_end(
359-
buffer,
360-
buffer.num_lines(),
363+
&mut buffer,
364+
current_line,
361365
max_line_num_len + 1,
362366
);
363367
}
@@ -369,7 +373,7 @@ impl Renderer {
369373
Element::Suggestion(suggestion) => {
370374
let source_map = SourceMap::new(suggestion.source, suggestion.line_start);
371375
self.emit_suggestion_default(
372-
buffer,
376+
&mut buffer,
373377
suggestion,
374378
max_line_num_len,
375379
&source_map,
@@ -380,13 +384,14 @@ impl Renderer {
380384
}
381385

382386
Element::Origin(origin) => {
383-
self.render_origin(buffer, max_line_num_len, origin);
387+
self.render_origin(&mut buffer, max_line_num_len, origin);
384388
last_was_suggestion = false;
385389
}
386390
Element::Padding(_) => {
391+
let current_line = buffer.num_lines();
387392
self.draw_col_separator_no_space(
388-
buffer,
389-
buffer.num_lines(),
393+
&mut buffer,
394+
current_line,
390395
max_line_num_len + 1,
391396
);
392397
}
@@ -396,23 +401,31 @@ impl Renderer {
396401
|| (matches!(section, Element::Title(_)) && i == 0)
397402
|| matches!(section, Element::Title(level) if level.level.name == Some(None)))
398403
{
404+
let current_line = buffer.num_lines();
399405
if peek.is_none() && group_len > 1 {
400406
self.draw_col_separator_end(
401-
buffer,
402-
buffer.num_lines(),
407+
&mut buffer,
408+
current_line,
403409
max_line_num_len + 1,
404410
);
405411
} else if matches!(peek, Some(Element::Title(level)) if level.level.name != Some(None))
406412
{
407413
self.draw_col_separator_no_space(
408-
buffer,
409-
buffer.num_lines(),
414+
&mut buffer,
415+
current_line,
410416
max_line_num_len + 1,
411417
);
412418
}
413419
}
414420
}
421+
buffer.render(level, &self.stylesheet, &mut out_string)?;
422+
if g != group_len - 1 {
423+
use std::fmt::Write;
424+
425+
writeln!(out_string)?;
426+
}
415427
}
428+
Ok(out_string)
416429
}
417430

418431
#[allow(clippy::too_many_arguments)]

src/renderer/styled_buffer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ impl StyledBuffer {
4343
&self,
4444
level: Level<'_>,
4545
stylesheet: &Stylesheet,
46-
) -> Result<String, fmt::Error> {
47-
let mut str = String::new();
46+
str: &mut String,
47+
) -> Result<(), fmt::Error> {
4848
for (i, line) in self.lines.iter().enumerate() {
4949
let mut current_style = stylesheet.none;
5050
for StyledChar { ch, style } in line {
@@ -63,7 +63,7 @@ impl StyledBuffer {
6363
writeln!(str)?;
6464
}
6565
}
66-
Ok(str)
66+
Ok(())
6767
}
6868

6969
/// Sets `chr` with `style` for given `line`, `col`.

0 commit comments

Comments
 (0)