annotate-snippets-rs icon indicating copy to clipboard operation
annotate-snippets-rs copied to clipboard

Weird formatting with `fold: true`

Open Inky-developer opened this issue 3 years ago • 4 comments

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.

Inky-developer avatar Jan 03 '22 20:01 Inky-developer

Yeah, it's intentional. It could be configurable around DisplayLine::Fold.

zbraniecki avatar Jan 03 '22 21:01 zbraniecki

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?

Inky-developer avatar Jan 04 '22 22:01 Inky-developer

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: image

I strongly hope this is not intentional.

bugadani avatar Jan 25 '22 14:01 bugadani

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?

zbraniecki avatar Oct 30 '23 12:10 zbraniecki