diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index ed31b86..c93048d 100644 --- a/src/formatter/mod.rs +++ b/src/formatter/mod.rs @@ -1,6 +1,7 @@ use std::{ cmp, fmt::{self, Display, Write}, + iter::once, }; pub mod style; @@ -217,19 +218,30 @@ impl<'a> DisplayList<'a> { } else { false }; + // Specifies that it will end on the next character, so it will return + // until the next one to the final condition. + let mut ended = false; let range = text .char_indices() .skip(left) + // Complete char iterator with final character + .chain(once((text.len(), '\0'))) + // Take until the next one to the final condition .take_while(|(_, ch)| { + // Fast return to iterate over final byte position + if ended { + return false; + } // Make sure that the trimming on the right will fall within the terminal width. // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is. // For now, just accept that sometimes the code line will be longer than desired. taken += unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1); if taken > right - left { - return false; + ended = true; } true }) + // Reduce to start and end byte position .fold((None, 0), |acc, (i, _)| { if acc.0.is_some() { (acc.0, i) @@ -238,7 +250,8 @@ impl<'a> DisplayList<'a> { } }); - text[range.0.expect("One character at line")..=range.1].fmt(f)?; + // Format text with margins + text[range.0.expect("One character at line")..range.1].fmt(f)?; if cut_right { // We have stripped some code after the right-most span end, make it clear we did so. diff --git a/tests/fixtures/no-color/strip_line_char.toml b/tests/fixtures/no-color/strip_line_char.toml new file mode 100644 index 0000000..5b432be --- /dev/null +++ b/tests/fixtures/no-color/strip_line_char.toml @@ -0,0 +1,25 @@ +[title] +id = "E0308" +label = "mismatched types" +annotation_type = "Error" + +[[slices]] +source = " let _: () = 42ñ" +line_start = 4 +origin = "$DIR/whitespace-trimming.rs" + +[[slices.annotations]] +label = "expected (), found integer" +annotation_type = "Error" +range = [192, 194] + +[opt] +color = false +anonymized_line_numbers = true +[opt.margin] +whitespace_left = 180 +span_left = 192 +span_right = 194 +label_right = 221 +column_width = 140 +max_line_len = 195 diff --git a/tests/fixtures/no-color/strip_line_char.txt b/tests/fixtures/no-color/strip_line_char.txt new file mode 100644 index 0000000..3d4b700 --- /dev/null +++ b/tests/fixtures/no-color/strip_line_char.txt @@ -0,0 +1,6 @@ +error[E0308]: mismatched types + --> $DIR/whitespace-trimming.rs:4:193 + | +LL | ... let _: () = 42ñ + | ^^ expected (), found integer + |