annotate-snippets-rs
                                
                                 annotate-snippets-rs copied to clipboard
                                
                                    annotate-snippets-rs copied to clipboard
                            
                            
                            
                        Weird formatting with `fold: true`
When rendering an annotation with fold: true the first 4 lines get rendered if the source has more than 7 lines.
If the source has 7 or less lines, the first lines do not get rendered.
Example with source = "\n\n\n\n\n\n\nFoo":
error
  |
...
8 | Foo
  | ^^^ Error here
  |
Example with source = "\n\n\n\n\n\n\n\nFoo":
error
  |
1 | 
2 | 
3 | 
4 | 
...
8 | 
9 | Foo
  | ^^^ Error here
  |
Minimal example: 
use annotate_snippets::{
    display_list::{DisplayList, FormatOptions},
    snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
};
fn print_snippet(source: &str, range: (usize, usize)) {
    let s = Snippet {
        title: Some(Annotation {
            label: None,
            id: None,
            annotation_type: AnnotationType::Error,
        }),
        footer: Vec::new(),
        slices: vec![Slice {
            fold: true,
            line_start: 1,
            source,
            origin: None,
            annotations: vec![SourceAnnotation {
                annotation_type: AnnotationType::Error,
                label: "Error here",
                range,
            }],
        }],
        opt: FormatOptions::default(),
    };
    println!("{}", DisplayList::from(s));
}
fn main() {
    print_snippet("\n\n\n\n\n\n\nFoo", (7, 10));
    println!("\nVs\n");
    print_snippet("\n\n\n\n\n\n\n\nFoo", (8, 11));
}
I am not sure if this is intended. In either case there should probably some way to disable this behavior.
Yeah, it's intentional. It could be configurable around DisplayLine::Fold.
Okay. Though I am still not quite sure why this is intentional. What is the advantage of displaying the first four lines of the file (only) if the error is far away from those?
fold: true works completely unreliably based on where the ends of the span I'm trying to print fall.
One thing is printing the first four lines, I can live with that however it works. My biggest problem is, that for certain inputs, the crate prints two empty lines, nothing more.
Example, may or may not require Windows
use annotate_snippets::{
    display_list::{DisplayList, FormatOptions},
    snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
};
fn main() {
    let source = "foo\r\nbar\r\n\r\nfoo\r\nbar\r\nbaz\r\n\r\nfoo\r\nbar\r\nbaz";
    println!("String in range: {}", &source[9..28]);
    println!("annotate-snippets output:");
    let snippet = Snippet {
        title: Some(Annotation {
            label: Some("error"),
            id: None,
            annotation_type: AnnotationType::Error,
        }),
        footer: vec![],
        slices: vec![Slice {
            line_start: 0,
            source: &source,
            origin: None,
            fold: true,
            annotations: vec![SourceAnnotation {
                label: "label",
                annotation_type: AnnotationType::Error,
                range: (9, 28),
            }],
        }],
        opt: FormatOptions {
            color: true,
            ..Default::default()
        },
    };
    println!("{}", &DisplayList::from(snippet))
}
Example output:

I strongly hope this is not intentional.
The latter issue is that the crate doesn't handle \r\n well. You can normalize it by replacing \r\n with \n and then pushing the result to format. (or file a separate issue about \r!)
As for the initial 4 lines. It is intended to show the above context, but I can see how it is useless in your example.
My intent was to show the begging of a snippet in case the snippet is long, and then cut to the part where the error occurs.
It's here: https://github.com/rust-lang/annotate-snippets-rs/blob/master/src/display_list/from_snippet.rs#L189
If your first annotation is in line 9, then why do you include the first 8 lines at all if not for context?