From 434dc956a40b9d7659830a88dcf1e2eb0e193a71 Mon Sep 17 00:00:00 2001 From: Aditya Pillai <29032680+pilleye@users.noreply.github.com> Date: Sat, 1 Jun 2024 19:49:11 -0700 Subject: [PATCH] fix displaying non-printable characters --- crates/ruff_linter/src/lib.rs | 1 + crates/ruff_linter/src/message/diff.rs | 12 ++++++++++-- crates/ruff_linter/src/message/text.rs | 5 ++++- crates/ruff_linter/src/source_kind.rs | 21 ++++++++++++++++----- crates/ruff_linter/src/text_helpers.rs | 23 +++++++++++++++++++++++ 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 crates/ruff_linter/src/text_helpers.rs diff --git a/crates/ruff_linter/src/lib.rs b/crates/ruff_linter/src/lib.rs index 7ce0bdd15a6117..e01601ed2581e4 100644 --- a/crates/ruff_linter/src/lib.rs +++ b/crates/ruff_linter/src/lib.rs @@ -39,6 +39,7 @@ pub mod rule_selector; pub mod rules; pub mod settings; pub mod source_kind; +mod text_helpers; pub mod upstream_categories; #[cfg(any(test, fuzzing))] diff --git a/crates/ruff_linter/src/message/diff.rs b/crates/ruff_linter/src/message/diff.rs index 2ba3f24ee24df4..4c47677c28da5c 100644 --- a/crates/ruff_linter/src/message/diff.rs +++ b/crates/ruff_linter/src/message/diff.rs @@ -10,6 +10,7 @@ use ruff_diagnostics::{Applicability, Fix}; use ruff_source_file::{OneIndexed, SourceFile}; use crate::message::Message; +use crate::text_helpers::ShowNonprinting; /// Renders a diff that shows the code fixes. /// @@ -102,9 +103,16 @@ impl Display for Diff<'_> { for (emphasized, value) in change.iter_strings_lossy() { if emphasized { - write!(f, "{}", line_style.apply_to(&value).underline().on_black())?; + write!( + f, + "{}", + line_style + .apply_to(&value.show_nonprinting()) + .underline() + .on_black() + )?; } else { - write!(f, "{}", line_style.apply_to(&value))?; + write!(f, "{}", line_style.apply_to(&value.show_nonprinting()))?; } } if change.missing_newline() { diff --git a/crates/ruff_linter/src/message/text.rs b/crates/ruff_linter/src/message/text.rs index 833deab46c8182..6e104e49af2a50 100644 --- a/crates/ruff_linter/src/message/text.rs +++ b/crates/ruff_linter/src/message/text.rs @@ -17,6 +17,7 @@ use crate::message::diff::Diff; use crate::message::{Emitter, EmitterContext, Message}; use crate::registry::AsRule; use crate::settings::types::UnsafeFixes; +use crate::text_helpers::ShowNonprinting; bitflags! { #[derive(Default)] @@ -251,6 +252,8 @@ impl Display for MessageCodeFrame<'_> { range - start_offset, ); + let source_text = source.text.show_nonprinting(); + let start_char = source.text[TextRange::up_to(source.annotation_range.start())] .chars() .count(); @@ -262,7 +265,7 @@ impl Display for MessageCodeFrame<'_> { let snippet = Snippet { title: None, slices: vec![Slice { - source: &source.text, + source: &source_text, line_start: self.notebook_index.map_or_else( || start_index.get(), |notebook_index| { diff --git a/crates/ruff_linter/src/source_kind.rs b/crates/ruff_linter/src/source_kind.rs index da27457348a1b1..f3392864ff1bec 100644 --- a/crates/ruff_linter/src/source_kind.rs +++ b/crates/ruff_linter/src/source_kind.rs @@ -14,6 +14,7 @@ use ruff_python_ast::PySourceType; use colored::Colorize; use crate::fs; +use crate::text_helpers::ShowNonprinting; #[derive(Clone, Debug, PartialEq, is_macro::Is)] pub enum SourceKind { @@ -220,8 +221,8 @@ impl<'a> CodeDiff<'a> { impl std::fmt::Display for CodeDiff<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some((original, modified)) = self.header { - writeln!(f, "--- {}", original.red())?; - writeln!(f, "+++ {}", modified.green())?; + writeln!(f, "--- {}", original.show_nonprinting().red())?; + writeln!(f, "+++ {}", modified.show_nonprinting().green())?; } let mut unified = self.diff.unified_diff(); @@ -234,9 +235,19 @@ impl std::fmt::Display for CodeDiff<'_> { // individual lines for change in hunk.iter_changes() { match change.tag() { - ChangeTag::Equal => write!(f, " {}", change.value())?, - ChangeTag::Delete => write!(f, "{}{}", "-".red(), change.value().red())?, - ChangeTag::Insert => write!(f, "{}{}", "+".green(), change.value().green())?, + ChangeTag::Equal => write!(f, " {}", change.value().show_nonprinting())?, + ChangeTag::Delete => write!( + f, + "{}{}", + "-".red(), + change.value().show_nonprinting().red() + )?, + ChangeTag::Insert => write!( + f, + "{}{}", + "+".green(), + change.value().show_nonprinting().green() + )?, } if !self.diff.newline_terminated() { diff --git a/crates/ruff_linter/src/text_helpers.rs b/crates/ruff_linter/src/text_helpers.rs new file mode 100644 index 00000000000000..422cf170b163c8 --- /dev/null +++ b/crates/ruff_linter/src/text_helpers.rs @@ -0,0 +1,23 @@ +use std::borrow::Cow; + +pub(crate) trait ShowNonprinting { + fn show_nonprinting(&self) -> Cow<'_, str>; +} + +macro_rules! impl_show_nonprinting { + ($(($from:expr, $to:expr)),+) => { + impl ShowNonprinting for str { + fn show_nonprinting(&self) -> Cow<'_, str> { + if self.find(&[$($from),*][..]).is_some() { + Cow::Owned( + self.$(replace($from, $to)).* + ) + } else { + Cow::Borrowed(self) + } + } + } + }; +} + +impl_show_nonprinting!(('\x07', "␇"), ('\x08', "␈"), ('\x1b', "␛"), ('\x7f', "␡"));