Skip to content

Commit

Permalink
fix(handlers): Fix label position (#107)
Browse files Browse the repository at this point in the history
Fixes #106

While fixing the bug I've also extended the handler to print not just
where label starts but also where label ends.

Also implements #97, but for narratabble handler only.

This adds dependency on `unicode-width`, but it was already in the
dependency chain (`textwidth` depends on it). Although, previously it
was only for `"fancy"` feature, now it always required since narratable
handler is supported without `"fancy"`.
  • Loading branch information
tailhook authored Jan 17, 2022
1 parent 9dcce5f commit f158f4e
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 35 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exclude = ["images/", "tests/", "miette-derive/"]
thiserror = "1.0.26"
miette-derive = { path = "miette-derive", version = "=3.3.1-alpha.0"}
once_cell = "1.8.0"
unicode-width = "0.1.9"

owo-colors = { version = "3.0.0", optional = true }
atty = { version = "0.2.14", optional = true }
Expand Down Expand Up @@ -45,7 +46,7 @@ fancy = [
"supports-hyperlinks",
"supports-color",
"supports-unicode",
"backtrace"
"backtrace",
]

[workspace]
Expand Down
112 changes: 93 additions & 19 deletions src/handlers/narratable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::fmt;

use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

use crate::chain::Chain;
use crate::protocol::{Diagnostic, Severity};
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
Expand Down Expand Up @@ -208,23 +210,44 @@ impl NarratableReportHandler {
writeln!(f)?;
for line in &lines {
writeln!(f, "snippet line {}: {}", line.line_number, line.text)?;
let relevant = labels.iter().filter(|l| line.span_starts(l.inner()));
for label in relevant {
let contents = source
.read_span(label.inner(), self.context_lines, self.context_lines)
.map_err(|_| fmt::Error)?;
if contents.line() + 1 == line.line_number {
write!(
f,
" label starting at line {}, column {}",
contents.line() + 1,
contents.column() + 1
)?;
if let Some(label) = label.label() {
write!(f, ": {}", label)?;
let relevant = labels
.iter()
.filter_map(|l| line.span_attach(l.inner()).map(|a| (a, l)));
for (attach, label) in relevant {
match attach {
SpanAttach::Contained { col_start, col_end } if col_start == col_end => {
write!(
f,
" label at line {}, column {}",
line.line_number, col_start,
)?;
}
SpanAttach::Contained { col_start, col_end } => {
write!(
f,
" label at line {}, columns {} to {}",
line.line_number, col_start, col_end,
)?;
}
SpanAttach::Starts { col_start } => {
write!(
f,
" label starting at line {}, column {}",
line.line_number, col_start,
)?;
}
writeln!(f)?;
SpanAttach::Ends { col_end } => {
write!(
f,
" label ending at line {}, column {}",
line.line_number, col_end,
)?;
}
}
if let Some(label) = label.label() {
write!(f, ": {}", label)?;
}
writeln!(f)?;
}
}
Ok(())
Expand Down Expand Up @@ -281,6 +304,7 @@ impl NarratableReportHandler {
line_number: line,
offset: line_offset,
text: line_str.clone(),
at_end_of_file,
});
line_str.clear();
line_offset = offset;
Expand Down Expand Up @@ -308,12 +332,62 @@ struct Line {
line_number: usize,
offset: usize,
text: String,
at_end_of_file: bool,
}

enum SpanAttach {
Contained { col_start: usize, col_end: usize },
Starts { col_start: usize },
Ends { col_end: usize },
}

/// Returns column at offset, and nearest boundary if offset is in the middle of the character
fn safe_get_column(text: &str, offset: usize, start: bool) -> usize {
let mut column = text.get(0..offset).map(|s| s.width()).unwrap_or_else(|| {
let mut column = 0;
for (idx, c) in text.char_indices() {
if offset <= idx {
break;
}
column += c.width().unwrap_or(0);
}
column
});
if start {
// Offset are zero-based, so plus one
column += 1;
} // On the other hand for end span, offset refers for the next column
// So we should do -1. column+1-1 == column
column
}

impl Line {
// Does this line contain the *beginning* of this multiline span?
// This assumes self.span_applies() is true already.
fn span_starts(&self, span: &SourceSpan) -> bool {
span.offset() >= self.offset
fn span_attach(&self, span: &SourceSpan) -> Option<SpanAttach> {
let span_end = span.offset() + span.len();
let line_end = self.offset + self.text.len();

let start_after = span.offset() >= self.offset;
let end_before = self.at_end_of_file || span_end <= line_end;

if start_after && end_before {
let col_start = safe_get_column(&self.text, span.offset() - self.offset, true);
let col_end = if span.is_empty() {
col_start
} else {
// span_end refers to the next character after token
// while col_end refers to the exact character, so -1
safe_get_column(&self.text, span_end - self.offset, false)
};
return Some(SpanAttach::Contained { col_start, col_end });
}
if start_after && span.offset() <= line_end {
let col_start = safe_get_column(&self.text, span.offset() - self.offset, true);
return Some(SpanAttach::Starts { col_start });
}
if end_before && span_end >= self.offset {
let col_end = safe_get_column(&self.text, span_end - self.offset, false);
return Some(SpanAttach::Ends { col_end });
}
None
}
}
37 changes: 22 additions & 15 deletions tests/narrated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ fn single_line_with_wide_char() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: 👼🏼text
label at line 2, columns 3 to 6: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -82,8 +82,8 @@ fn single_line_highlight() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: text
label at line 2, columns 3 to 6: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -118,7 +118,7 @@ fn single_line_highlight_offset_zero() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
label at line 1, column 1: this bit here
snippet line 2: text
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -153,8 +153,8 @@ fn single_line_highlight_with_empty_span() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: text
label at line 2, column 3: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -189,8 +189,8 @@ fn single_line_highlight_no_label() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1
snippet line 2: text
label at line 2, columns 3 to 6
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -225,8 +225,8 @@ fn single_line_highlight_at_line_start() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: text
label at line 2, columns 1 to 4: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -267,10 +267,10 @@ fn multiple_same_line_highlights() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: x
label starting at line 1, column 1: y
label starting at line 1, column 1: z
snippet line 2: text text text text text
label at line 2, columns 3 to 6: x
label at line 2, columns 8 to 11: y
label at line 2, columns 18 to 21: z
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down Expand Up @@ -305,9 +305,10 @@ fn multiline_highlight_adjacent() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: these two lines
snippet line 2: text
label starting at line 2, column 3: these two lines
snippet line 3: here
label ending at line 3, column 6: these two lines
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
"#
Expand Down Expand Up @@ -352,11 +353,13 @@ Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: line1
label starting at line 1, column 1: block 1
label starting at line 1, column 1: block 2
snippet line 2: line2
label starting at line 2, column 5: block 2
snippet line 3: line3
snippet line 4: line4
label ending at line 4, column 1: block 2
snippet line 5: line5
label ending at line 5, column 5: block 1
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
"#
Expand Down Expand Up @@ -418,11 +421,13 @@ Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: line1
label starting at line 1, column 1: block 1
label starting at line 1, column 1
snippet line 2: line2
label starting at line 2, column 5
snippet line 3: line3
snippet line 4: line4
label ending at line 4, column 1
snippet line 5: line5
label ending at line 5, column 5: block 1
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
"
Expand Down Expand Up @@ -461,9 +466,11 @@ Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: text
label starting at line 2, column 1: also this bit
label ending at line 2, column 3: this bit here
snippet line 3: here
label starting at line 3, column 7: also this bit
snippet line 4: more here
label ending at line 4, column 3: also this bit
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
"
Expand Down Expand Up @@ -575,8 +582,8 @@ fn related() -> Result<(), MietteError> {
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
snippet line 2: text
label at line 2, columns 3 to 6: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand All @@ -587,7 +594,7 @@ Error: oops!
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label starting at line 1, column 1: this bit here
label at line 1, columns 1 to 6: this bit here
snippet line 2: text
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Expand Down

0 comments on commit f158f4e

Please sign in to comment.