mirror of https://github.com/zkat/miette.git
Merge 638d0bde10 into b466948965
This commit is contained in:
commit
62bbfa5b61
|
|
@ -740,7 +740,7 @@ impl GraphicalReportHandler {
|
|||
max_gutter,
|
||||
line,
|
||||
&labels,
|
||||
LabelRenderMode::SingleLine,
|
||||
LabelRenderMode::MultiLineEndPending,
|
||||
)?;
|
||||
self.render_single_line_highlights(
|
||||
f,
|
||||
|
|
@ -930,32 +930,41 @@ impl GraphicalReportHandler {
|
|||
let applicable = highlights.iter().filter(|hl| line.span_applies_gutter(hl));
|
||||
for (i, hl) in applicable.enumerate() {
|
||||
if !line.span_line_only(hl) && line.span_ends(hl) {
|
||||
if render_mode == LabelRenderMode::MultiLineRest {
|
||||
// this is to make multiline labels work. We want to make the right amount
|
||||
// of horizontal space for them, but not actually draw the lines
|
||||
let horizontal_space = max_gutter.saturating_sub(i) + 2;
|
||||
for _ in 0..horizontal_space {
|
||||
gutter.push(' ');
|
||||
match render_mode {
|
||||
LabelRenderMode::MultiLineRest => {
|
||||
// this is to make multiline labels work. We want to make the right amount
|
||||
// of horizontal space for them, but not actually draw the lines
|
||||
let horizontal_space = max_gutter.saturating_sub(i) + 2;
|
||||
for _ in 0..horizontal_space {
|
||||
gutter.push(' ');
|
||||
}
|
||||
// account for one more horizontal space, since in multiline mode
|
||||
// we also add in the vertical line before the label like this:
|
||||
// 2 │ ╭─▶ text
|
||||
// 3 │ ├─▶ here
|
||||
// · ╰──┤ these two lines
|
||||
// · │ are the problem
|
||||
// ^this
|
||||
gutter_cols += horizontal_space + 1;
|
||||
}
|
||||
// account for one more horizontal space, since in multiline mode
|
||||
// we also add in the vertical line before the label like this:
|
||||
// 2 │ ╭─▶ text
|
||||
// 3 │ ├─▶ here
|
||||
// · ╰──┤ these two lines
|
||||
// · │ are the problem
|
||||
// ^this
|
||||
gutter_cols += horizontal_space + 1;
|
||||
} else {
|
||||
let num_repeat = max_gutter.saturating_sub(i) + 2;
|
||||
LabelRenderMode::MultiLineEndPending => {
|
||||
// we're rendering continuation lines for single-line highlights on a line
|
||||
// where a multiline span ends
|
||||
// render │ to show the span is still visually "open" until we render its own label with ╰──
|
||||
gutter.push_str(&chars.vbar.style(hl.style).to_string());
|
||||
gutter_cols += 1;
|
||||
}
|
||||
LabelRenderMode::SingleLine | LabelRenderMode::MultiLineFirst => {
|
||||
let num_repeat = max_gutter.saturating_sub(i) + 2;
|
||||
|
||||
gutter.push_str(&chars.lbot.style(hl.style).to_string());
|
||||
gutter.push_str(&chars.lbot.style(hl.style).to_string());
|
||||
|
||||
gutter.push_str(
|
||||
&chars
|
||||
.hbar
|
||||
.to_string()
|
||||
.repeat(
|
||||
num_repeat
|
||||
gutter.push_str(
|
||||
&chars
|
||||
.hbar
|
||||
.to_string()
|
||||
.repeat(
|
||||
num_repeat
|
||||
// if we are rendering a multiline label, then leave a bit of space for the
|
||||
// rcross character
|
||||
- if render_mode == LabelRenderMode::MultiLineFirst {
|
||||
|
|
@ -963,16 +972,17 @@ impl GraphicalReportHandler {
|
|||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
.style(hl.style)
|
||||
.to_string(),
|
||||
);
|
||||
)
|
||||
.style(hl.style)
|
||||
.to_string(),
|
||||
);
|
||||
|
||||
// we count 1 for the lbot char, and then a few more, the same number
|
||||
// as we just repeated for. For each repeat we only add 1, even though
|
||||
// due to ansi escape codes the number of bytes in the string could grow
|
||||
// a lot each time.
|
||||
gutter_cols += num_repeat + 1;
|
||||
// we count 1 for the lbot char, and then a few more, the same number
|
||||
// as we just repeated for. For each repeat we only add 1, even though
|
||||
// due to ansi escape codes the number of bytes in the string could grow
|
||||
// a lot each time.
|
||||
gutter_cols += num_repeat + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -1244,7 +1254,7 @@ impl GraphicalReportHandler {
|
|||
max_gutter,
|
||||
line,
|
||||
all_highlights,
|
||||
LabelRenderMode::SingleLine,
|
||||
LabelRenderMode::MultiLineEndPending,
|
||||
)?;
|
||||
let mut curr_offset = 1usize;
|
||||
for (offset_hl, vbar_offset) in vbar_offsets {
|
||||
|
|
@ -1257,7 +1267,7 @@ impl GraphicalReportHandler {
|
|||
curr_offset += 1;
|
||||
} else {
|
||||
let lines = match render_mode {
|
||||
LabelRenderMode::SingleLine => format!(
|
||||
LabelRenderMode::SingleLine | LabelRenderMode::MultiLineEndPending => format!(
|
||||
"{}{} {}",
|
||||
chars.lbot,
|
||||
chars.hbar.to_string().repeat(2),
|
||||
|
|
@ -1285,7 +1295,7 @@ impl GraphicalReportHandler {
|
|||
render_mode: LabelRenderMode,
|
||||
) -> fmt::Result {
|
||||
match render_mode {
|
||||
LabelRenderMode::SingleLine => {
|
||||
LabelRenderMode::SingleLine | LabelRenderMode::MultiLineEndPending => {
|
||||
writeln!(f, "{} {}", self.theme.characters.hbar.style(style), label)?;
|
||||
}
|
||||
LabelRenderMode::MultiLineFirst => {
|
||||
|
|
@ -1382,6 +1392,9 @@ enum LabelRenderMode {
|
|||
MultiLineFirst,
|
||||
/// we're rendering the rest of a multiline label
|
||||
MultiLineRest,
|
||||
/// we're rendering continuation lines for single-line highlights on a line where
|
||||
/// a multi-line span ends - render │ instead of ╰── for ending spans
|
||||
MultiLineEndPending,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -489,6 +489,54 @@ if true {
|
|||
assert_eq!(expected, out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_span_end_same_line_as_singleline() {
|
||||
#[derive(Error, Debug, Diagnostic)]
|
||||
#[error("oops!")]
|
||||
#[diagnostic(severity(Error))]
|
||||
struct MyBad {
|
||||
#[source_code]
|
||||
src: NamedSource<&'static str>,
|
||||
#[label("multiline label")]
|
||||
multiline: SourceSpan,
|
||||
#[label("singleline label")]
|
||||
singleline: SourceSpan,
|
||||
}
|
||||
let src = "\
|
||||
function test(
|
||||
bool a,
|
||||
) internal returns (uint256 helloWorld, Test someTest) {
|
||||
// oh hai
|
||||
}
|
||||
";
|
||||
let err = MyBad {
|
||||
src: NamedSource::new("issue", src),
|
||||
// multiline span from "function" to end of ")"
|
||||
multiline: (0, 38).into(),
|
||||
// singleline span on "uint256 helloWorld"
|
||||
singleline: (55, 18).into(),
|
||||
};
|
||||
let out = fmt_report(err.into());
|
||||
println!("Error: {}", out);
|
||||
|
||||
// The │ should continue on the underline and label lines until the multiline span's
|
||||
// own label is rendered with ╰────
|
||||
let expected = r#"
|
||||
× oops!
|
||||
╭─[issue:1:1]
|
||||
1 │ ╭─▶ function test(
|
||||
2 │ │ bool a,
|
||||
3 │ ├─▶ ) internal returns (uint256 helloWorld, Test someTest) {
|
||||
· │ ─────────┬────────
|
||||
· │ ╰── singleline label
|
||||
· ╰──── multiline label
|
||||
4 │ // oh hai
|
||||
╰────
|
||||
"#
|
||||
.trim_start_matches('\n');
|
||||
assert_eq!(expected, out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_line_highlight_span_full_line() {
|
||||
#[derive(Error, Debug, Diagnostic)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue