From 29c8e7f502ef48cf6985ef6e94aa28478efb520a Mon Sep 17 00:00:00 2001 From: Juan Aguilar Santillana Date: Mon, 24 Aug 2020 10:39:15 +0000 Subject: [PATCH 1/2] Fix character split when strip code --- src/formatter/mod.rs | 10 ++++++-- tests/fixtures/no-color/strip_line_char.toml | 25 ++++++++++++++++++++ tests/fixtures/no-color/strip_line_char.txt | 6 +++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/no-color/strip_line_char.toml create mode 100644 tests/fixtures/no-color/strip_line_char.txt diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index ed31b86b..d34c7bfe 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,16 +218,21 @@ impl<'a> DisplayList<'a> { } else { false }; + let mut ended = false; let range = text .char_indices() + .chain(once((text.len(), '\0'))) .skip(left) .take_while(|(_, ch)| { + 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 }) @@ -238,7 +244,7 @@ impl<'a> DisplayList<'a> { } }); - text[range.0.expect("One character at line")..=range.1].fmt(f)?; + 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 00000000..5b432beb --- /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 00000000..3d4b700c --- /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 + | From 65fced101d90837ef007e4515ef9aae59a86a532 Mon Sep 17 00:00:00 2001 From: Juan Aguilar Santillana Date: Mon, 24 Aug 2020 12:30:48 +0000 Subject: [PATCH 2/2] Add documentation --- src/formatter/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index d34c7bfe..c93048d9 100644 --- a/src/formatter/mod.rs +++ b/src/formatter/mod.rs @@ -218,12 +218,17 @@ 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() - .chain(once((text.len(), '\0'))) .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; } @@ -236,6 +241,7 @@ impl<'a> DisplayList<'a> { } true }) + // Reduce to start and end byte position .fold((None, 0), |acc, (i, _)| { if acc.0.is_some() { (acc.0, i) @@ -244,6 +250,7 @@ impl<'a> DisplayList<'a> { } }); + // Format text with margins text[range.0.expect("One character at line")..range.1].fmt(f)?; if cut_right {