zesterer / ariadne

A fancy diagnostics & error reporting crate
https://crates.io/crates/ariadne
MIT License
1.74k stars 76 forks source link

Labels containing multiple lines of text are not handled well #37

Open Qqwy opened 2 years ago

Qqwy commented 2 years ago

Minimal example:

changing examples/multiline.rs to the following:

use ariadne::{Report, ReportKind, Label, Source, Color, ColorGenerator, Fmt};

fn main() {
    let mut colors = ColorGenerator::new();

    // Generate & choose some colours for each of our elements
    let a = colors.next();
    let b = colors.next();
    let out = Color::Fixed(81);
    let out2= colors.next();

    Report::build(ReportKind::Error, "sample.tao", 12)
        .with_code(3)
        .with_message(format!("Incompatible types"))
        .with_label(Label::new(("sample.tao", 32..33))
            .with_message(format!("This is of type {}", "Nat".fg(a)))
            .with_color(a))
        .with_label(Label::new(("sample.tao", 42..45))
            .with_message(format!("This is of type {}", "Str".fg(b)))
            .with_color(b))
        .with_label(Label::new(("sample.tao", 11..48))
            .with_message(format!(
                "The values are outputs of this {} expression",
                "match".fg(out),
            ))
            .with_color(out))
        .with_label(Label::new(("sample.tao", 0..48))
            .with_message(format!(
                "The {} has a problem",
                "definition".fg(out2),
            ))
            .with_color(out2))
        .with_label(Label::new(("sample.tao", 50..76))
            .with_message(format!(
                "Usage of {} here\nfoo bar\nbaz",
                "definition".fg(out2),
            ))
            .with_color(out2))
        .with_note(format!("Outputs of {} expressions must coerce to the same type", "match".fg(out)))
        .finish()
        .print(("sample.tao", Source::from(include_str!("sample.tao"))))
        .unwrap();
}

Actual result:

Gives this output:

image

$ cargo run --example multiline 
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/examples/multiline`
[03] Error: Incompatible types
   ╭─[sample.tao:1:13]
   │
 1 │ ╭─────▶ def five = match () in {
   · │                  🭯               
   · │ ╭────────────────╯               
 2 │ │ │         () => 5,
   · │ │               ┬  
   · │ │               ╰── This is of type Nat
 3 │ │ │         () => "5",
   · │ │               ─┬─  
   · │ │                ╰─── This is of type Str
 4 │ │ ├───▶ }
   · │ │     🭯   
   · │ ╰───────── The values are outputs of this match expression
   · │       │   
   · ╰───────┴─── The definition has a problem
   · 
 6 │     ╭─▶ def six =
   ⋮     ⋮   
 8 │     ├─▶     + 1
   ·     │             
   ·     ╰───────────── Usage of definition here
foo bar
baz
   ·         
   ·         Note: Outputs of match expressions must coerce to the same type
───╯

Expected result

Newlines are indented to start at the same column as the previous line, and the arrows/line-drawing characters to the left of it are not disturbed.

zesterer commented 2 years ago

This is probably going to need to wait for a refactor of the crate internals. My plan is to have labels treated as their own independent layout systems.

BGR360 commented 1 year ago

Any pointers for a contributor who would like to try to get this working?