From a45f4de683427b7fe39b09483de35b2938d5488a Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Wed, 8 Jan 2025 12:54:31 -0500 Subject: [PATCH] ruff_annotate_snippets: fix false positive line trimming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fix was sent upstream and the PR description includes more details: https://github.com/rust-lang/annotate-snippets-rs/pull/170 Without this fix, there was an errant snapshot diff that looked like this: | 1 | version = "0.1.0" 2 | # Ensure that the spans from toml handle utf-8 correctly 3 | authors = [ | ___________^ 4 | | { name = "Z͑ͫ̓ͪ̂ͫ̽͏̴̙...A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘", email = 1 } 5 | | ] | |_^ RUF200 | That ellipsis should _not_ be inserted since the line is not actually truncated. The handling of line length (in bytes versus actual rendered length) wasn't quite being handled correctly in all cases. With this fix, there's (correctly) no snapshot diff. --- .../src/renderer/display_list.rs | 33 +++++++++---------- .../src/renderer/margin.rs | 12 ------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/crates/ruff_annotate_snippets/src/renderer/display_list.rs b/crates/ruff_annotate_snippets/src/renderer/display_list.rs index bd723e7dd1..f9c774c2fd 100644 --- a/crates/ruff_annotate_snippets/src/renderer/display_list.rs +++ b/crates/ruff_annotate_snippets/src/renderer/display_list.rs @@ -331,28 +331,27 @@ impl DisplaySet<'_> { // On long lines, we strip the source line, accounting for unicode. let mut taken = 0; - let code: String = text - .chars() - .skip(left) - .take_while(|ch| { - // 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. - let next = unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1); - if taken + next > right - left { - return false; - } - taken += next; - true - }) - .collect(); + let mut was_cut_right = false; + let mut code = String::new(); + for ch in text.chars().skip(left) { + // 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. + let next = unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1); + if taken + next > right - left { + was_cut_right = true; + break; + } + taken += next; + code.push(ch); + } buffer.puts(line_offset, code_offset, &code, Style::new()); if self.margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear. buffer.puts(line_offset, code_offset, "...", *lineno_color); } - if self.margin.was_cut_right(line_len) { + if was_cut_right { buffer.puts(line_offset, code_offset + taken - 3, "...", *lineno_color); } diff --git a/crates/ruff_annotate_snippets/src/renderer/margin.rs b/crates/ruff_annotate_snippets/src/renderer/margin.rs index c484416610..59bd550745 100644 --- a/crates/ruff_annotate_snippets/src/renderer/margin.rs +++ b/crates/ruff_annotate_snippets/src/renderer/margin.rs @@ -58,18 +58,6 @@ impl Margin { self.computed_left > 0 } - pub(crate) fn was_cut_right(&self, line_len: usize) -> bool { - let right = - if self.computed_right == self.span_right || self.computed_right == self.label_right { - // Account for the "..." padding given above. Otherwise we end up with code lines that - // do fit but end in "..." as if they were trimmed. - self.computed_right - ELLIPSIS_PASSING - } else { - self.computed_right - }; - right < line_len && self.computed_left + self.term_width < line_len - } - fn compute(&mut self, max_line_len: usize) { // When there's a lot of whitespace (>20), we want to trim it as it is useless. self.computed_left = if self.whitespace_left > LONG_WHITESPACE {