diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 21db50e02..3f4574735 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 000000000..d3b2fe6f1 --- /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 6a0c23679..575704dc8 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;