diff --git a/codespan-reporting/src/term/renderer.rs b/codespan-reporting/src/term/renderer.rs index cb79443..b3acf0f 100644 --- a/codespan-reporting/src/term/renderer.rs +++ b/codespan-reporting/src/term/renderer.rs @@ -25,17 +25,18 @@ pub type SingleLabel<'diagnostic> = (LabelStyle, Range, &'diagnostic str) /// /// Locations are relative to the start of where the source code is rendered. pub enum MultiLabel<'diagnostic> { - /// Left top corner for multi-line labels. - /// - /// ```text - /// ╭ - /// ``` - TopLeft, /// Multi-line label top. /// /// ```text /// ╭────────────^ /// ``` + /// + /// Can also be rendered at the beginning of the line + /// if there is only whitespace before the label starts. + /// + /// /// ```text + /// ╭ + /// ``` Top(RangeTo), /// Left vertical labels for multi-line labels. /// @@ -263,7 +264,9 @@ impl<'writer, 'config> Renderer<'writer, 'config> { match multi_labels_iter.peek() { Some((label_index, label_style, label)) if *label_index == label_column => { match label { - MultiLabel::TopLeft => { + MultiLabel::Top(range) + if range.end <= source.len() - source.trim_start().len() => + { self.label_multi_top_left(severity, *label_style)?; } MultiLabel::Top(..) => self.inner_gutter_space()?, @@ -290,7 +293,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> { *ls == LabelStyle::Primary && match label { MultiLabel::Top(range) => column_range.start >= range.end, - MultiLabel::TopLeft | MultiLabel::Left => true, + MultiLabel::Left => true, MultiLabel::Bottom(range, _) => column_range.end <= range.end, } }); @@ -537,7 +540,13 @@ impl<'writer, 'config> Renderer<'writer, 'config> { // ``` for (multi_label_index, (_, label_style, label)) in multi_labels.iter().enumerate() { let (label_style, range, bottom_message) = match label { - MultiLabel::TopLeft | MultiLabel::Left => continue, // no label caret needed + MultiLabel::Left => continue, // no label caret needed + // no label caret needed if this can be started in front of the line + MultiLabel::Top(range_to) + if range_to.end <= source.len() - source.trim_start().len() => + { + continue + } MultiLabel::Top(range) => (*label_style, range, None), MultiLabel::Bottom(range, message) => (*label_style, range, Some(message)), }; @@ -556,7 +565,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> { match multi_labels_iter.peek() { Some((i, (label_index, ls, label))) if *label_index == label_column => { match label { - MultiLabel::TopLeft | MultiLabel::Left => { + MultiLabel::Left => { self.label_multi_left(severity, *ls, underline.map(|(s, _)| s))?; } MultiLabel::Top(..) if multi_label_index > *i => { @@ -944,7 +953,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> { for label_column in 0..num_multi_labels { match multi_labels_iter.peek() { Some((label_index, ls, label)) if *label_index == label_column => match label { - MultiLabel::TopLeft | MultiLabel::Left | MultiLabel::Bottom(..) => { + MultiLabel::Left | MultiLabel::Bottom(..) => { self.label_multi_left(severity, *ls, None)?; multi_labels_iter.next(); } diff --git a/codespan-reporting/src/term/views.rs b/codespan-reporting/src/term/views.rs index 59cdcc5..0722d9e 100644 --- a/codespan-reporting/src/term/views.rs +++ b/codespan-reporting/src/term/views.rs @@ -83,11 +83,6 @@ where // Group labels by file for label in &self.diagnostic.labels { - let source = files - .source(label.file_id) - .ok_or(RenderError::FileMissing)?; - let source = source.as_ref(); - let start_line_index = files .line_index(label.file_id, label.range.start) .ok_or(RenderError::InvalidIndex)?; @@ -213,7 +208,6 @@ where // First labeled line let label_start = label.range.start - start_line_range.start; - let prefix_source = &source[start_line_range.start..label.range.start]; let start_line = labeled_file.get_or_insert_line( start_line_index, @@ -221,26 +215,11 @@ where start_line_number, ); - start_line - .multi_labels - // TODO: Do this in the `Renderer`? - .push(match prefix_source.trim() { - // Section is prefixed by empty space, so we don't need to take - // up a new line. - // - // ```text - // 4 │ ╭ case (mod num 5) (mod num 3) of - // ``` - "" => (label_index, label.style, MultiLabel::TopLeft), - // There's source code in the prefix, so run a label - // underneath it to get to the start of the range. - // - // ```text - // 4 │ fizz₁ num = case (mod num 5) (mod num 3) of - // │ ╭─────────────^ - // ``` - _ => (label_index, label.style, MultiLabel::Top(..label_start)), - }); + start_line.multi_labels.push(( + label_index, + label.style, + MultiLabel::Top(..label_start), + )); // The first line has to be rendered so the start of the label is visible. start_line.must_render = true;