mirror of https://github.com/zkat/miette.git
Clean up render_snippets
This commit is contained in:
parent
7ff4f874d6
commit
d4f30ec501
|
|
@ -6,7 +6,7 @@ use unicode_width::UnicodeWidthChar;
|
|||
use crate::diagnostic_chain::{DiagnosticChain, ErrorKind};
|
||||
use crate::handlers::theme::*;
|
||||
use crate::protocol::{Diagnostic, Severity};
|
||||
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
||||
use crate::{LabeledSpan, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
||||
|
||||
/**
|
||||
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
|
||||
|
|
@ -377,66 +377,63 @@ impl GraphicalReportHandler {
|
|||
diagnostic: &(dyn Diagnostic),
|
||||
opt_source: Option<&dyn SourceCode>,
|
||||
) -> fmt::Result {
|
||||
if let Some(source) = opt_source {
|
||||
if let Some(labels) = diagnostic.labels() {
|
||||
let mut labels = labels.collect::<Vec<_>>();
|
||||
labels.sort_unstable_by_key(|l| l.inner().offset());
|
||||
if !labels.is_empty() {
|
||||
let contents = labels
|
||||
.iter()
|
||||
.map(|label| {
|
||||
source.read_span(label.inner(), self.context_lines, self.context_lines)
|
||||
})
|
||||
.collect::<Result<Vec<Box<dyn SpanContents<'_>>>, MietteError>>()
|
||||
.map_err(|_| fmt::Error)?;
|
||||
let mut contexts = Vec::with_capacity(contents.len());
|
||||
for (right, right_conts) in labels.iter().cloned().zip(contents.iter()) {
|
||||
if contexts.is_empty() {
|
||||
contexts.push((right, right_conts));
|
||||
} else {
|
||||
let (left, left_conts) = contexts.last().unwrap().clone();
|
||||
let left_end = left.offset() + left.len();
|
||||
let right_end = right.offset() + right.len();
|
||||
if left_conts.line() + left_conts.line_count() >= right_conts.line() {
|
||||
// The snippets will overlap, so we create one Big Chunky Boi
|
||||
let new_span = LabeledSpan::new(
|
||||
left.label().map(String::from),
|
||||
left.offset(),
|
||||
if right_end >= left_end {
|
||||
// Right end goes past left end
|
||||
right_end - left.offset()
|
||||
} else {
|
||||
// right is contained inside left
|
||||
left.len()
|
||||
},
|
||||
);
|
||||
if source
|
||||
.read_span(
|
||||
new_span.inner(),
|
||||
self.context_lines,
|
||||
self.context_lines,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
contexts.pop();
|
||||
contexts.push((
|
||||
// We'll throw this away later
|
||||
new_span, left_conts,
|
||||
));
|
||||
} else {
|
||||
contexts.push((right, right_conts));
|
||||
}
|
||||
} else {
|
||||
contexts.push((right, right_conts));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ctx, _) in contexts {
|
||||
self.render_context(f, source, &ctx, &labels[..])?;
|
||||
}
|
||||
let Some(source) = opt_source else {
|
||||
return Ok(());
|
||||
};
|
||||
let Some(labels) = diagnostic.labels() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mut labels = labels.collect::<Vec<_>>();
|
||||
labels.sort_unstable_by_key(|l| l.inner().offset());
|
||||
|
||||
let mut contexts = Vec::with_capacity(labels.len());
|
||||
for right in labels.iter().cloned() {
|
||||
let right_conts = source
|
||||
.read_span(right.inner(), self.context_lines, self.context_lines)
|
||||
.map_err(|_| fmt::Error)?;
|
||||
|
||||
if contexts.is_empty() {
|
||||
contexts.push((right, (right_conts.line(), right_conts.line_count())));
|
||||
continue;
|
||||
}
|
||||
|
||||
let (left, (left_line, left_line_count)) = contexts.last().unwrap().clone();
|
||||
if left_line + left_line_count >= right_conts.line() {
|
||||
// The snippets will overlap, so we create one Big Chunky Boi
|
||||
let left_end = left.offset() + left.len();
|
||||
let right_end = right.offset() + right.len();
|
||||
let new_span = LabeledSpan::new(
|
||||
left.label().map(String::from),
|
||||
left.offset(),
|
||||
if right_end >= left_end {
|
||||
// Right end goes past left end
|
||||
right_end - left.offset()
|
||||
} else {
|
||||
// right is contained inside left
|
||||
left.len()
|
||||
},
|
||||
);
|
||||
// Check that the two contexts can be combined
|
||||
if let Ok(new_conts) =
|
||||
source.read_span(new_span.inner(), self.context_lines, self.context_lines)
|
||||
{
|
||||
contexts.pop();
|
||||
contexts.push((
|
||||
// We'll throw this away later
|
||||
new_span,
|
||||
(new_conts.line(), new_conts.line_count()),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
contexts.push((right, (right_conts.line(), right_conts.line_count())));
|
||||
}
|
||||
for (ctx, _) in contexts {
|
||||
self.render_context(f, source, &ctx, &labels[..])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue