feat: phase 2 — i18n messages EN/FR (--lang, AM_LANG/LANG, catalogue tr/tr_fmt, REPL lang) (closes #74)

This commit is contained in:
2026-08-18 15:46:51 -04:00
parent 4c7866a25a
commit 7f4d74f811
19 changed files with 852 additions and 47 deletions
+18
View File
@@ -21,6 +21,9 @@ pub struct App {
pub catalog: Catalog,
pub state: StateStore,
pub log: Logger,
/// Active output language (issue #74); mirrored in i18n::active() so the
/// REPL 'lang' command can switch it at runtime.
lang: Cell<crate::i18n::Lang>,
/// Active output color theme (switchable at runtime with the REPL
/// 'theme <name>' command).
theme: Cell<&'static Theme>,
@@ -84,6 +87,8 @@ impl App {
loaded.config.groups.clone(),
);
let theme = resolve_theme(cli.theme.as_deref(), loaded.config.settings.theme.as_deref())?;
let lang = crate::i18n::resolve(cli.lang);
crate::i18n::set_lang(lang);
Ok(Self {
cli,
config: loaded.config,
@@ -92,6 +97,7 @@ impl App {
catalog,
state,
log,
lang: Cell::new(lang),
theme: Cell::new(theme),
})
}
@@ -116,6 +122,18 @@ impl App {
self.theme.get()
}
/// Active output language (issue #74).
pub fn lang(&self) -> crate::i18n::Lang {
self.lang.get()
}
/// Switch the active language (REPL 'lang' command); the i18n global is
/// kept in sync so tr()/tr_fmt! follow immediately.
pub fn set_lang(&self, lang: crate::i18n::Lang) {
self.lang.set(lang);
crate::i18n::set_lang(lang);
}
/// Switch the active theme (used by the REPL 'theme <name>' command).
pub fn set_theme(&self, theme: &'static Theme) {
self.theme.set(theme);