diff --git a/Cargo.lock b/Cargo.lock index 61e8bad..942a689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1197,9 +1197,10 @@ dependencies = [ "hex_color", "i18n-embed", "i18n-embed-fl", + "icu_collator", + "icu_provider", "indexmap", "lazy_static", - "lexical-sort", "libcosmic", "log", "open", @@ -2769,6 +2770,149 @@ dependencies = [ "objc2 0.5.2", ] +[[package]] +name = "icu_collator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d370371887d31d56f361c3eaa15743e54f13bc677059c9191c77e099ed6966b2" +dependencies = [ + "displaydoc", + "icu_collator_data", + "icu_collections", + "icu_locid_transform", + "icu_normalizer", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "zerovec", +] + +[[package]] +name = "icu_collator_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee3f88741364b7d6269cce6827a3e6a8a2cf408a78f766c9224ab479d5e4ae5" + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -3201,6 +3345,12 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0b5399f6804fbab912acbd8878ed3532d506b7c951b8f9f164ef90fef39e3f4" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "locale_config" version = "0.3.0" @@ -4890,6 +5040,12 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -4966,6 +5122,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "sys-locale" version = "0.3.1" @@ -5126,6 +5293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", + "zerovec", ] [[package]] @@ -5506,6 +5674,18 @@ dependencies = [ "tiny-skia-path", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -6346,6 +6526,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "x11-dl" version = "2.21.0" @@ -6470,6 +6662,30 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zbus" version = "3.15.2" @@ -6625,6 +6841,49 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "zune-inflate" version = "0.2.54" diff --git a/Cargo.toml b/Cargo.toml index 67ad045..33824cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ env_logger = "0.10" hex_color = { version = "3", features = ["serde"] } indexmap = "2" lazy_static = "1" -lexical-sort = "0.3.1" log = "0.4" open = "5.0.2" palette = { version = "0.7", features = ["serde"] } @@ -30,6 +29,8 @@ i18n-embed = { version = "0.14", features = [ "desktop-requester", ] } i18n-embed-fl = "0.7" +icu_collator = "1.5" +icu_provider = { version = "1.5", features = ["sync"] } rust-embed = "8" [dependencies.cosmic-files] diff --git a/src/config.rs b/src/config.rs index 61a2f11..99aee50 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::sync::OnceLock; -use crate::fl; +use crate::{fl, localize::LANGUAGE_SORTER}; pub const CONFIG_VERSION: u64 = 1; pub const COSMIC_THEME_DARK: &str = "COSMIC Dark"; @@ -311,7 +311,7 @@ impl Config { color_scheme_names.push((name, *color_scheme_id)); } - color_scheme_names.sort_by(|a, b| lexical_sort::natural_lexical_cmp(&a.0, &b.0)); + color_scheme_names.sort_by(|a, b| LANGUAGE_SORTER.compare(&a.0, &b.0)); color_scheme_names } @@ -347,7 +347,7 @@ impl Config { profile_names.push((name, *profile_id)); } - profile_names.sort_by(|a, b| lexical_sort::natural_lexical_cmp(&a.0, &b.0)); + profile_names.sort_by(|a, b| LANGUAGE_SORTER.compare(&a.0, &b.0)); profile_names } diff --git a/src/key_bind.rs b/src/key_bind.rs index 2d3fec1..30f02e0 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -64,7 +64,7 @@ pub fn key_binds() -> HashMap { bind!([Ctrl], Key::Character("-".into()), ZoomOut); bind!([Ctrl], Key::Character("=".into()), ZoomIn); bind!([Ctrl], Key::Character("+".into()), ZoomIn); - + // Ctrl+Arrows and Ctrl+HJKL move between splits bind!([Ctrl, Shift], Key::Named(Named::ArrowLeft), PaneFocusLeft); bind!([Ctrl, Shift], Key::Character("H".into()), PaneFocusLeft); diff --git a/src/localize.rs b/src/localize.rs index 012d25f..cabd298 100644 --- a/src/localize.rs +++ b/src/localize.rs @@ -1,9 +1,13 @@ // SPDX-License-Identifier: GPL-3.0-only +use std::str::FromStr; + use i18n_embed::{ fluent::{fluent_language_loader, FluentLanguageLoader}, DefaultLocalizer, LanguageLoader, Localizer, }; +use icu_collator::{Collator, CollatorOptions, Numeric}; +use icu_provider::DataLocale; use rust_embed::RustEmbed; #[derive(RustEmbed)] @@ -22,6 +26,23 @@ lazy_static::lazy_static! { }; } +lazy_static::lazy_static! { + pub static ref LANGUAGE_SORTER: Collator = { + let mut options = CollatorOptions::new(); + options.numeric = Some(Numeric::On); + + DataLocale::from_str(&LANGUAGE_LOADER.current_language().to_string()) + .or_else(|_| DataLocale::from_str(&LANGUAGE_LOADER.fallback_language().to_string())) + .ok() + .and_then(|locale| Collator::try_new(&locale, options).ok()) + .or_else(|| { + let locale = DataLocale::from_str("en-US").expect("en-US is a valid BCP-47 tag"); + Collator::try_new(&locale, options).ok() + }) + .expect("Creating a collator from the system's current language, the fallback language, or American English should succeed") + }; +} + #[macro_export] macro_rules! fl { ($message_id:literal) => {{ diff --git a/src/main.rs b/src/main.rs index 815c121..1ffbf3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ use cosmic::{ }; use cosmic_files::dialog::{Dialog, DialogKind, DialogMessage, DialogResult}; use cosmic_text::{fontdb::FaceInfo, Family, Stretch, Weight}; +use localize::LANGUAGE_SORTER; use std::{ any::TypeId, cmp, @@ -460,9 +461,9 @@ impl App { } } self.theme_names_dark - .sort_by(|a, b| lexical_sort::natural_lexical_cmp(a, b)); + .sort_by(|a, b| LANGUAGE_SORTER.compare(a, b)); self.theme_names_light - .sort_by(|a, b| lexical_sort::natural_lexical_cmp(a, b)); + .sort_by(|a, b| LANGUAGE_SORTER.compare(a, b)); } fn update_config(&mut self) -> Command {