From 462fa9077ad95de86de21830968ae4902233c23b Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 22 Nov 2025 08:23:06 +0100 Subject: [PATCH] Fix wcwidth() on systems without C.UTF-8 locale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS has en_US.UTF-8 but not C.UTF-8, which leads to a glitch when typing "🐟". Fix that by trying the user's locale first, restoring historical behavior. Fixes 71a962653de (Be explicit about setlocale() scope, 2025-10-24). Reported-by: Ilya Grigoriev --- CHANGELOG.rst | 1 + src/locale.rs | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bec1fa9c2..49022524f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,7 @@ For distributors and developers Regression fixes: ----------------- - (from 4.1.0) Crash on invalid colors variables (:issue:`12078`). +- (from 4.2.0) Incorrect emoji width computation on macOS. fish 4.2.1 (released November 13, 2025) ======================================= diff --git a/src/locale.rs b/src/locale.rs index 72b8870ea..b3c438fd5 100644 --- a/src/locale.rs +++ b/src/locale.rs @@ -10,25 +10,33 @@ /// above mutex. pub unsafe fn set_libc_locales(log_ok: bool) -> bool { let mut ok = true; + let from_environment = c""; let mut set = |category_name, category, value| { let locale_string = setlocale(category, Some(value)); if log_ok { - crate::flog::FLOG!( - env_locale, + crate::flog::FLOG!(env_locale, { + let source = if value == from_environment { + "from environment".to_string() + } else { + format!("to '{}'", value.to_str().unwrap()) + }; match locale_string { Some(locale_string) => { - format!("Set {category_name} to {}", locale_string.to_string_lossy()) + format!( + "Set {category_name} {source}: {}", + locale_string.to_string_lossy() + ) } None => { - format!("Failed to set {category_name}",) + format!("Failed to set {category_name} {source}") } - }, - ); + } + }); } ok &= locale_string.is_some(); }; - let from_environment = c""; // For wcwidth(3p) + set("LC_CTYPE", libc::LC_CTYPE, from_environment); set("LC_CTYPE", libc::LC_CTYPE, c"C.UTF-8"); // For strerror(3p) and strsignal(3p) set("LC_MESSAGES", libc::LC_MESSAGES, from_environment);