From 89436e978b0f483af65ae6ebdabe70ee5263f891 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Tue, 19 Dec 2023 13:09:31 -0600 Subject: [PATCH] add special emoji handling for debug --raw (#11368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR add special handling in `debug -r` for emoji's so that it prints the code points. ### Before ```nushell ❯ emoji --list | where name =~ farmer | reject utf8_bytes | get 0.emoji | debug -r String { val: "🧑\u{200d}🌾", internal_span: Span { start: 0, end: 0, }, } ``` ### After ```nushell ❯ emoji --list | where name =~ farmer | reject utf8_bytes | get 0.emoji | debug -r String { val: "\\u{1f9d1}\\u{200d}\\u{1f33e}", internal_span: Span { start: 0, end: 0, }, } ``` # User-Facing Changes # Tests + Formatting # After Submitting --- crates/nu-protocol/src/value/mod.rs | 20 +++++++++++++++++--- crates/nu-utils/src/emoji.rs | 16 ++++++++++++++++ crates/nu-utils/src/lib.rs | 2 ++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 crates/nu-utils/src/emoji.rs diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 21db50e028..3f4574735b 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -20,8 +20,9 @@ pub use custom_value::CustomValue; use fancy_regex::Regex; pub use from_value::FromValue; pub use lazy_record::LazyRecord; -use nu_utils::locale::get_system_locale_string; -use nu_utils::{get_system_locale, IgnoreCaseExt}; +use nu_utils::{ + contains_emoji, get_system_locale, locale::get_system_locale_string, IgnoreCaseExt, +}; use num_format::ToFormattedString; pub use range::*; pub use record::Record; @@ -789,7 +790,20 @@ impl Value { /// Convert Value into a debug string pub fn debug_value(&self) -> String { - format!("{self:#?}") + match self { + Value::String { val, .. } => { + if contains_emoji(val) { + // This has to be an emoji, so let's display the code points that make it up. + format!( + "{:#?}", + Value::string(val.escape_unicode().to_string(), self.span()) + ) + } else { + format!("{self:#?}") + } + } + _ => format!("{self:#?}"), + } } /// Convert Value into a parsable string (quote strings) diff --git a/crates/nu-utils/src/emoji.rs b/crates/nu-utils/src/emoji.rs new file mode 100644 index 0000000000..d3b2fe6f13 --- /dev/null +++ b/crates/nu-utils/src/emoji.rs @@ -0,0 +1,16 @@ +pub fn contains_emoji(val: &str) -> bool { + // Let's do some special handling for emojis + const ZERO_WIDTH_JOINER: &str = "\u{200d}"; + const VARIATION_SELECTOR_16: &str = "\u{fe0f}"; + const SKIN_TONES: [&str; 5] = [ + "\u{1f3fb}", // Light Skin Tone + "\u{1f3fc}", // Medium-Light Skin Tone + "\u{1f3fd}", // Medium Skin Tone + "\u{1f3fe}", // Medium-Dark Skin Tone + "\u{1f3ff}", // Dark Skin Tone + ]; + + val.contains(ZERO_WIDTH_JOINER) + || val.contains(VARIATION_SELECTOR_16) + || SKIN_TONES.iter().any(|skin_tone| val.contains(skin_tone)) +} diff --git a/crates/nu-utils/src/lib.rs b/crates/nu-utils/src/lib.rs index 6a0c23679f..575704dc81 100644 --- a/crates/nu-utils/src/lib.rs +++ b/crates/nu-utils/src/lib.rs @@ -1,6 +1,7 @@ mod casing; pub mod ctrl_c; mod deansi; +pub mod emoji; pub mod locale; pub mod utils; @@ -14,3 +15,4 @@ pub use casing::IgnoreCaseExt; pub use deansi::{ strip_ansi_likely, strip_ansi_string_likely, strip_ansi_string_unlikely, strip_ansi_unlikely, }; +pub use emoji::contains_emoji;