Fix wcwidth() on systems without C.UTF-8 locale

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 71a962653d (Be explicit about setlocale() scope, 2025-10-24).

Reported-by: Ilya Grigoriev <ilyagr@users.noreply.github.com>
This commit is contained in:
Johannes Altmanninger
2025-11-22 08:23:06 +01:00
parent 0f9749c140
commit 462fa9077a
2 changed files with 16 additions and 7 deletions

View File

@@ -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)
=======================================

View File

@@ -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);