From 732942ec62059a70b21abf3b812e688060bfa886 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 25 Oct 2025 08:30:13 +0200 Subject: [PATCH] Force libc wcwidth to use UTF-8 locale again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 046db09f902 (Try to set LC_CTYPE to something UTF-8 capable (#8031), 2021-06-06) forced UTF-8 encoding if available. Since c8001b5023a (encoding: use UTF-8 everywhere, 2025-10-18) we no longer override LC_CTYPE, since we no longer use it for anything like mbrtowc or iswalpha. However there is one remaining use: our fallbacks to system wcwidth(). If we are started as LC_ALL=C fish then wcwidth('😃') will fail to return the correct value, even if the UTF-8 locale would have been available. Restore the previous behavior, so locale variables don't affect emoji width. This is consistent with the direction in c8001b5023a which stops us from falling back to ASCII characters if our desired multibyte locale is missing (that was not the ideal criteria). In future we should maybe stop using wcwidth(). --- src/locale.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/locale.rs b/src/locale.rs index 2fd1fa555..169c2e29c 100644 --- a/src/locale.rs +++ b/src/locale.rs @@ -9,7 +9,9 @@ /// Call this either before starting any locale-using thread, or while holding a lock on the /// above mutex. pub unsafe fn set_libc_locales() -> Option<&'static CStr> { - setlocale(libc::LC_ALL, Some(c"")) + let opaque_locale_str = setlocale(libc::LC_ALL, Some(c"")); + setlocale(libc::LC_CTYPE, Some(c"C.UTF-8")); + opaque_locale_str } fn setlocale(category: libc::c_int, locale: Option<&CStr>) -> Option<&'static CStr> {