use gpui::{App, SharedString};
use gpui_base::TypographyTokens;
use std::sync::OnceLock;
const MONO_FONT_ALTERNATES: &[&str] = if cfg!(target_os = "macos") {
&["Monaco", "Courier New"]
} else if cfg!(target_os = "windows") {
&["Cascadia Mono", "Courier New"]
} else {
&["Noto Sans Mono", "Liberation Mono", "Ubuntu Mono"]
};
const SYSTEM_UI_FONT: &str = ".SystemUIFont";
pub(super) fn default_mono_font_family() -> SharedString {
TypographyTokens::default().mono
}
pub(super) fn resolve_default_mono_font(cx: &mut App) {
if cx.global::<super::Theme>().mono_font_family != default_mono_font_family() {
return;
}
let family = installed_default_mono_font_family(cx);
cx.global_mut::<super::Theme>().mono_font_family = family;
}
fn installed_default_mono_font_family(cx: &App) -> SharedString {
static RESOLVED: OnceLock<SharedString> = OnceLock::new();
RESOLVED
.get_or_init(|| {
let default = default_mono_font_family();
let family = first_installed(
&default,
MONO_FONT_ALTERNATES,
&cx.text_system().all_font_names(),
);
if family != default {
tracing::warn!(
"Monospace font {default:?} is not installed, using {family:?} instead."
);
}
family
})
.clone()
}
fn first_installed(default: &str, alternates: &[&str], installed: &[String]) -> SharedString {
std::iter::once(default)
.chain(alternates.iter().copied())
.find(|candidate| installed.iter().any(|name| name == candidate))
.unwrap_or(SYSTEM_UI_FONT)
.to_string()
.into()
}
#[cfg(test)]
mod tests {
use super::*;
fn names(names: &[&str]) -> Vec<String> {
names.iter().map(|name| name.to_string()).collect()
}
#[test]
fn keeps_the_default_when_it_is_installed() {
let installed = names(&["Monaco", "Menlo", ".SystemUIFont"]);
assert_eq!(
first_installed("Menlo", &["Monaco"], &installed),
SharedString::from("Menlo")
);
}
#[test]
fn falls_through_the_alternates_in_order() {
let installed = names(&["Courier New", "Monaco", ".SystemUIFont"]);
assert_eq!(
first_installed("Menlo", &["Monaco", "Courier New"], &installed),
SharedString::from("Monaco")
);
}
#[test]
fn falls_back_to_the_system_font_when_nothing_is_installed() {
let installed = names(&["Helvetica", ".SystemUIFont"]);
assert_eq!(
first_installed("Menlo", &["Monaco"], &installed),
SharedString::from(".SystemUIFont")
);
}
}