i18n: Hebrew on one line, its sign held left, CLDR's short years
gpui 0.2.2 wraps shaped glyphs in the order they are drawn, so a right-to-left line that wraps comes out garbled. The demo's Hebrew lines are Ellipses, which cut by characters, and an Ellipsis now sits by its text's alignment, so a short line under text_right lies at the right; the editor's completion details take the side they ask for. A right-to-left locale leads a minus with a left-to-right mark, as CLDR does, so the sign stays at the digits' left inside Hebrew. en-US and de-DE write CLDR's two-digit year. The repeated-key and second-catalog guards have tests.
This commit is contained in:
1 parent
ae5f2334f5
commit
83ecacde65
6 files changed
+68
-18
No files matched your search
+8
-4
@@ -61,7 +61,7 @@ pub const LOCALES: [Locale; 7] = [
|
||||
"en-US",
|
||||
"English (US)",
|
||||
(',', '.'),
|
||||
"%-m/%-d/%Y",
|
||||
"%-m/%-d/%y",
|
||||
Direction::Ltr,
|
||||
),
|
||||
locale(
|
||||
@@ -71,7 +71,7 @@ pub const LOCALES: [Locale; 7] = [
|
||||
"%d/%m/%Y",
|
||||
Direction::Ltr,
|
||||
),
|
||||
locale("de-DE", "Deutsch", ('.', ','), "%d.%m.%Y", Direction::Ltr),
|
||||
locale("de-DE", "Deutsch", ('.', ','), "%d.%m.%y", Direction::Ltr),
|
||||
locale(
|
||||
"fr-FR",
|
||||
"Français",
|
||||
@@ -93,9 +93,13 @@ impl Locale {
|
||||
.unwrap_or_else(|| panic!("no locale {tag:?}"))
|
||||
}
|
||||
|
||||
/// `value` with this locale's separators.
|
||||
/// `value` with this locale's separators; a right-to-left locale leads its sign with a left-to-right mark, as CLDR does.
|
||||
pub fn number(self, value: f64, decimals: usize) -> String {
|
||||
format::number(value, decimals, self.separators)
|
||||
let number = format::number(value, decimals, self.separators);
|
||||
match (self.direction, number.starts_with(format::MINUS)) {
|
||||
(Direction::Rtl, true) => format!("\u{200e}{number}"),
|
||||
_ => number,
|
||||
}
|
||||
}
|
||||
|
||||
/// The day `at` falls on in `zone`, written as this locale writes dates.
|
||||
|
||||
+22
-3
@@ -53,6 +53,20 @@ fn a_catalog_with_a_stray_key_fails() {
|
||||
.catalog("de-DE", &[("hi", "Hallo"), ("bye", "Tschüss")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "en-US repeats a key")]
|
||||
fn a_repeated_key_fails() {
|
||||
I18n::new("en-US").catalog("en-US", &[("hi", "Hello"), ("hi", "Hey")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "en-US has a catalog")]
|
||||
fn a_second_catalog_for_a_locale_fails() {
|
||||
I18n::new("en-US")
|
||||
.catalog("en-US", &[("hi", "Hello")])
|
||||
.catalog("en-US", &[("hi", "Hey")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "no locale \"xx-XX\"")]
|
||||
fn an_unlisted_locale_fails() {
|
||||
@@ -76,9 +90,9 @@ fn locales_write_their_own_numbers_and_dates() {
|
||||
assert_eq!(
|
||||
cases,
|
||||
[
|
||||
("en-US", "−1,234,567.89".into(), "9/1/2026".into()),
|
||||
("en-US", "−1,234,567.89".into(), "9/1/26".into()),
|
||||
("en-GB", "−1,234,567.89".into(), "01/09/2026".into()),
|
||||
("de-DE", "−1.234.567,89".into(), "01.09.2026".into()),
|
||||
("de-DE", "−1.234.567,89".into(), "01.09.26".into()),
|
||||
(
|
||||
"fr-FR",
|
||||
"−1\u{202f}234\u{202f}567,89".into(),
|
||||
@@ -86,7 +100,7 @@ fn locales_write_their_own_numbers_and_dates() {
|
||||
),
|
||||
("ja-JP", "−1,234,567.89".into(), "2026/09/01".into()),
|
||||
("zh-CN", "−1,234,567.89".into(), "2026/9/1".into()),
|
||||
("he-IL", "−1,234,567.89".into(), "1.9.2026".into()),
|
||||
("he-IL", "\u{200e}−1,234,567.89".into(), "1.9.2026".into()),
|
||||
]
|
||||
);
|
||||
let rtl: Vec<_> = LOCALES
|
||||
@@ -94,6 +108,11 @@ fn locales_write_their_own_numbers_and_dates() {
|
||||
.filter(|locale| locale.direction == Direction::Rtl)
|
||||
.collect();
|
||||
assert_eq!(rtl, [&Locale::of("he-IL")]);
|
||||
assert_eq!(
|
||||
Locale::of("he-IL").number(3.5, 1),
|
||||
"3.5",
|
||||
"a gain takes no mark"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "test-support")]
|
||||
|
||||
Reference in new issue
Block a user