Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix margin #105

Merged
merged 4 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
863 changes: 504 additions & 359 deletions src/renderer/display_list.rs

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions src/renderer/margin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const ELLIPSIS_PASSING: usize = 6;
const LONG_WHITESPACE: usize = 20;
const LONG_WHITESPACE_PADDING: usize = 4;

#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Margin {
/// The available whitespace in the left that can be consumed when centering.
whitespace_left: usize,
Expand All @@ -17,7 +17,7 @@ pub struct Margin {
/// The end of the line to be displayed.
computed_right: usize,
/// The current width of the terminal. 140 by default and in tests.
column_width: usize,
term_width: usize,
/// The end column of a span label, including the span. Doesn't account for labels not in the
/// same line as the span.
label_right: usize,
Expand All @@ -29,7 +29,7 @@ impl Margin {
span_left: usize,
span_right: usize,
label_right: usize,
column_width: usize,
term_width: usize,
max_line_len: usize,
) -> Self {
// The 6 is padding to give a bit of room for `...` when displaying:
Expand All @@ -47,7 +47,7 @@ impl Margin {
span_right: span_right + ELLIPSIS_PASSING,
computed_left: 0,
computed_right: 0,
column_width,
term_width,
label_right: label_right + ELLIPSIS_PASSING,
};
m.compute(max_line_len);
Expand All @@ -67,7 +67,7 @@ impl Margin {
} else {
self.computed_right
};
right < line_len && self.computed_left + self.column_width < line_len
right < line_len && self.computed_left + self.term_width < line_len
}

fn compute(&mut self, max_line_len: usize) {
Expand All @@ -81,22 +81,22 @@ impl Margin {
// relevant code.
self.computed_right = max(max_line_len, self.computed_left);

if self.computed_right - self.computed_left > self.column_width {
if self.computed_right - self.computed_left > self.term_width {
// Trimming only whitespace isn't enough, let's get craftier.
if self.label_right - self.whitespace_left <= self.column_width {
if self.label_right - self.whitespace_left <= self.term_width {
// Attempt to fit the code window only trimming whitespace.
self.computed_left = self.whitespace_left;
self.computed_right = self.computed_left + self.column_width;
} else if self.label_right - self.span_left <= self.column_width {
self.computed_right = self.computed_left + self.term_width;
} else if self.label_right - self.span_left <= self.term_width {
// Attempt to fit the code window considering only the spans and labels.
let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2;
let padding_left = (self.term_width - (self.label_right - self.span_left)) / 2;
self.computed_left = self.span_left.saturating_sub(padding_left);
self.computed_right = self.computed_left + self.column_width;
} else if self.span_right - self.span_left <= self.column_width {
self.computed_right = self.computed_left + self.term_width;
} else if self.span_right - self.span_left <= self.term_width {
// Attempt to fit the code window considering the spans and labels plus padding.
let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2;
let padding_left = (self.term_width - (self.span_right - self.span_left)) / 5 * 2;
self.computed_left = self.span_left.saturating_sub(padding_left);
self.computed_right = self.computed_left + self.column_width;
self.computed_right = self.computed_left + self.term_width;
} else {
// Mostly give up but still don't show the full line.
self.computed_left = self.span_left;
Expand All @@ -110,7 +110,7 @@ impl Margin {
}

pub(crate) fn right(&self, line_len: usize) -> usize {
if line_len.saturating_sub(self.computed_left) <= self.column_width {
if line_len.saturating_sub(self.computed_left) <= self.term_width {
line_len
} else {
min(line_len, self.computed_right)
Expand Down
32 changes: 9 additions & 23 deletions src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ pub(crate) mod stylesheet;
use crate::snippet::Message;
pub use anstyle::*;
use display_list::DisplayList;
pub use margin::Margin;
use margin::Margin;
use std::fmt::Display;
use stylesheet::Stylesheet;

pub const DEFAULT_TERM_WIDTH: usize = 140;

/// A renderer for [`Message`]s
#[derive(Clone)]
pub struct Renderer {
anonymized_line_numbers: bool,
margin: Option<Margin>,
term_width: usize,
stylesheet: Stylesheet,
}

Expand All @@ -34,7 +36,7 @@ impl Renderer {
pub const fn plain() -> Self {
Self {
anonymized_line_numbers: false,
margin: None,
term_width: DEFAULT_TERM_WIDTH,
stylesheet: Stylesheet::plain(),
}
}
Expand Down Expand Up @@ -94,25 +96,9 @@ impl Renderer {
self
}

/// Set the margin for the output
///
/// This controls the various margins of the output.
///
/// # Example
///
/// ```text
/// error: expected type, found `22`
/// --> examples/footer.rs:29:25
/// |
/// 26 | ... annotations: vec![SourceAnnotation {
/// | ---------------- info: while parsing this struct
/// ...
/// 29 | ... range: <22, 25>,
/// | ^^
/// |
/// ```
pub const fn margin(mut self, margin: Option<Margin>) -> Self {
self.margin = margin;
// Set the terminal width
pub const fn term_width(mut self, term_width: usize) -> Self {
self.term_width = term_width;
self
}

Expand Down Expand Up @@ -170,7 +156,7 @@ impl Renderer {
msg,
&self.stylesheet,
self.anonymized_line_numbers,
self.margin,
self.term_width,
)
}
}
46 changes: 5 additions & 41 deletions tests/fixtures/deserialize.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use serde::{Deserialize, Deserializer, Serialize};
use std::ops::Range;

use annotate_snippets::{renderer::Margin, Annotation, Level, Message, Renderer, Snippet};
use annotate_snippets::renderer::DEFAULT_TERM_WIDTH;
use annotate_snippets::{Annotation, Level, Message, Renderer, Snippet};

#[derive(Deserialize)]
pub struct Fixture<'a> {
Expand Down Expand Up @@ -148,55 +149,18 @@ enum LevelDef {
pub struct RendererDef {
#[serde(default)]
anonymized_line_numbers: bool,
#[serde(deserialize_with = "deserialize_margin")]
#[serde(default)]
margin: Option<Margin>,
term_width: Option<usize>,
}

impl From<RendererDef> for Renderer {
fn from(val: RendererDef) -> Self {
let RendererDef {
anonymized_line_numbers,
margin,
term_width,
} = val;
Renderer::plain()
.anonymized_line_numbers(anonymized_line_numbers)
.margin(margin)
.term_width(term_width.unwrap_or(DEFAULT_TERM_WIDTH))
}
}

fn deserialize_margin<'de, D>(deserializer: D) -> Result<Option<Margin>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Wrapper {
whitespace_left: usize,
span_left: usize,
span_right: usize,
label_right: usize,
column_width: usize,
max_line_len: usize,
}

Option::<Wrapper>::deserialize(deserializer).map(|opt_wrapped: Option<Wrapper>| {
opt_wrapped.map(|wrapped: Wrapper| {
let Wrapper {
whitespace_left,
span_left,
span_right,
label_right,
column_width,
max_line_len,
} = wrapped;
Margin::new(
whitespace_left,
span_left,
span_right,
label_right,
column_width,
max_line_len,
)
})
})
}
7 changes: 0 additions & 7 deletions tests/fixtures/no-color/strip_line.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,3 @@ range = [192, 194]
[renderer]
color = false
anonymized_line_numbers = true
[renderer.margin]
whitespace_left = 180
span_left = 192
span_right = 194
label_right = 221
column_width = 140
max_line_len = 195
7 changes: 0 additions & 7 deletions tests/fixtures/no-color/strip_line_char.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,3 @@ range = [192, 194]
[renderer]
color = false
anonymized_line_numbers = true
[renderer.margin]
whitespace_left = 180
span_left = 192
span_right = 194
label_right = 221
column_width = 140
max_line_len = 195
12 changes: 7 additions & 5 deletions tests/fixtures/no-color/strip_line_non_ws.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 11 additions & 10 deletions tests/fixtures/no-color/strip_line_non_ws.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ id = "E0308"
title = "mismatched types"

[[message.snippets]]
source = " let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();"
source = """
let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
"""
line_start = 4
origin = "$DIR/non-whitespace-trimming.rs"

[[message.snippets.annotations]]
label = "expected (), found integer"
label = "expected `()`, found integer"
level = "Error"
range = [240, 242]
range = [241, 243]

[[message.snippets.annotations]]
label = "expected due to this"
level = "Error"
range = [236, 238]


[renderer]
anonymized_line_numbers = true
[renderer.margin]
whitespace_left = 4
span_left = 240
span_right = 242
label_right = 271
column_width = 140
max_line_len = 371
Loading