Description
I'm somewhat new to this crate, so apologies for any category or vernacular errors that I make.
I'm looking at migrating ruff from annotate-snippets 0.9
to annotate-snippets 0.11
. But I'm hitting an issue where we would like to use our own headers for snippets. This worked in 0.9
, but I can't find a way to replicate it in 0.11
. To make this concrete, consider this program using 0.9
:
use annotate_snippets::{
display_list::{DisplayList, FormatOptions},
snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
};
fn main() {
let snippet = Snippet {
title: None,
footer: vec![
Annotation {
id: None,
label: Some(
"Replace with `None`; initialize within function",
),
annotation_type: AnnotationType::Help,
},
],
slices: vec![
Slice {
source: "# Docstring followed by a newline\n\ndef foobar(foor, bar={}): \n \"\"\"\n \"\"\"\n",
line_start: 1,
origin: None,
annotations: vec![
SourceAnnotation {
range: (
56,
58,
),
label: "B006",
annotation_type: AnnotationType::Error,
},
],
fold: false,
},
],
opt: FormatOptions {
color: false,
anonymized_line_numbers: false,
margin: None,
},
};
println!("{message}", message = DisplayList::from(snippet));
}
It has this output:
|
1 | # Docstring followed by a newline
2 |
3 | def foobar(foor, bar={}):
| ^^ B006
4 | """
5 | """
|
= help: Replace with `None`; initialize within function
In ruff, this gets transformed slightly to include a header:
B006_1.py:3:22: B006 [*] Do not use mutable data structures for argument defaults
|
1 | # Docstring followed by a newline
2 |
3 | def foobar(foor, bar={}):
| ^^ B006
4 | """
5 | """
|
= help: Replace with `None`; initialize within function
Now consider this program, using 0.11
, which tries to mimic the above program:
use annotate_snippets::{Level, Renderer, Snippet};
fn main() {
let source = "# Docstring followed by a newline\n\ndef foobar(foor, bar={}): \n \"\"\"\n \"\"\"\n";
let src_annotation = Level::Error.span(56..58).label("B006");
let snippet = Snippet::source(source)
.line_start(1)
.annotation(src_annotation)
.fold(false);
let footer =
Level::Help.title("Replace with `None`; initialize within function");
let message =
Level::Error.title("<TITLE>").snippet(snippet).footer(footer);
println!("{}", Renderer::plain().render(message));
}
It has this output:
error: <TITLE>
|
1 | # Docstring followed by a newline
2 |
3 | def foobar(foor, bar={}):
| ^^ B006
4 | """
5 | """
|
= help: Replace with `None`; initialize within function
Which is... very close to what we had before. But it now has an error: <TITLE>
line that I don't think can be removed. At least, it seems to correspond to a requirement to create a message by providing a Level
with a title.
Is this an intended change to the library that isn't meant to be configurable? If so, I think our options are to either go our own way or to explore changing the formatting of our own diagnostics (which we could do, but I definitely want to see if I can de-couple upgrading annotate-snippets
from "let's reconsider our diagnostic formatting").
I do see some other issues and PRs seemingly related to this issue, but I wasn't 100% sure if this was a strict duplicate or not. So I wanted to put my use case in writing and see where that takes us.