From fc09bb0a92c290847767e97c43e6cc7e6a9ebb83 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Sat, 8 Aug 2026 19:54:21 +0700 Subject: [PATCH] fix(settings): keep the theme editor's color labels in the current language MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The editor stored each row's label as a String when it was built, so Background, Foreground, Accent, Cursor, Selection and the sixteen ANSI rows kept whatever language was set the moment you clicked "Duplicate to edit" — switching language a few rows further down the same page left them all behind. Look the label up from the ThemeEdit at render time instead of caching it. Verified by switching language with the editor open: the rows now follow. --- src/ui/app.rs | 50 +++++++++++++++++++--------------------------- src/ui/settings.rs | 22 ++++++++++---------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index ba26d584..89080831 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -69,6 +69,19 @@ const ANSI_COLOR_LABELS: [L10nKey; 16] = [ L10nKey::AppThemeAnsiBrightWhite, ]; +/// Looked up at render time, never stored: the editor outlives a language +/// change, and a label cached when it opened would stay in the old language. +pub(crate) fn theme_edit_label(edit: ThemeEdit) -> &'static str { + t(match edit { + ThemeEdit::Background => L10nKey::AppThemeColorBackground, + ThemeEdit::Foreground => L10nKey::AppThemeColorForeground, + ThemeEdit::Accent => L10nKey::AppThemeColorAccent, + ThemeEdit::Cursor => L10nKey::AppThemeColorCursor, + ThemeEdit::Selection => L10nKey::AppThemeColorSelection, + ThemeEdit::Ansi(i) => ANSI_COLOR_LABELS[i.min(15)], + }) +} + fn hsla_to_u32(color: gpui::Hsla) -> u32 { let rgba: gpui::Rgba = color.into(); let to = |f: f32| (f.clamp(0.0, 1.0) * 255.0).round() as u32; @@ -1712,32 +1725,12 @@ impl Tty7App { } let neutrals = theme.neutrals(); - let seed_specs: [(ThemeEdit, &str, u32); 5] = [ - ( - ThemeEdit::Background, - t(L10nKey::AppThemeColorBackground), - theme.background_color(), - ), - ( - ThemeEdit::Foreground, - t(L10nKey::AppThemeColorForeground), - theme.foreground, - ), - ( - ThemeEdit::Accent, - t(L10nKey::AppThemeColorAccent), - theme.accent, - ), - ( - ThemeEdit::Cursor, - t(L10nKey::AppThemeColorCursor), - theme.caret.unwrap_or(theme.accent), - ), - ( - ThemeEdit::Selection, - t(L10nKey::AppThemeColorSelection), - neutrals.selection, - ), + let seed_specs: [(ThemeEdit, u32); 5] = [ + (ThemeEdit::Background, theme.background_color()), + (ThemeEdit::Foreground, theme.foreground), + (ThemeEdit::Accent, theme.accent), + (ThemeEdit::Cursor, theme.caret.unwrap_or(theme.accent)), + (ThemeEdit::Selection, neutrals.selection), ]; let mut subs = Vec::new(); @@ -1760,9 +1753,7 @@ impl Tty7App { let seed = seed_specs .iter() - .map(|&(edit, label, value)| { - (edit, label.to_string(), make(edit, value, &mut subs, cx)) - }) + .map(|&(edit, value)| (edit, make(edit, value, &mut subs, cx))) .collect(); let ansi = (0..16) .map(|i| { @@ -1770,7 +1761,6 @@ impl Tty7App { let value = (r as u32) << 16 | (g as u32) << 8 | b as u32; ( ThemeEdit::Ansi(i), - t(ANSI_COLOR_LABELS[i]).to_string(), make(ThemeEdit::Ansi(i), value, &mut subs, cx), ) }) diff --git a/src/ui/settings.rs b/src/ui/settings.rs index d74a2271..978c5ec4 100644 --- a/src/ui/settings.rs +++ b/src/ui/settings.rs @@ -480,8 +480,8 @@ pub(crate) fn best_matching_section(query: &str) -> Option { pub(crate) struct ThemeEditor { #[allow(dead_code)] pub(crate) for_id: String, - pub(crate) seed: Vec<(ThemeEdit, String, Entity)>, - pub(crate) ansi: Vec<(ThemeEdit, String, Entity)>, + pub(crate) seed: Vec<(ThemeEdit, Entity)>, + pub(crate) ansi: Vec<(ThemeEdit, Entity)>, pub(crate) image_opacity_slider: Option>, pub(crate) _subs: Vec, } @@ -1596,16 +1596,14 @@ impl Tty7App { .on_click(cx.listener(|this, _, w, cx| this.open_themes_folder(w, cx))); if let Some(editor) = editor { - let seed: Vec<_> = editor - .seed - .iter() - .map(|(_, label, state)| (label.clone(), state.clone())) - .collect(); - let ansi: Vec<_> = editor - .ansi - .iter() - .map(|(_, label, state)| (label.clone(), state.clone())) - .collect(); + let label_of = |&(edit, ref state): &(ThemeEdit, Entity)| { + ( + crate::ui::app::theme_edit_label(edit).to_string(), + state.clone(), + ) + }; + let seed: Vec<_> = editor.seed.iter().map(label_of).collect(); + let ansi: Vec<_> = editor.ansi.iter().map(label_of).collect(); let image_opacity_slider = editor.image_opacity_slider.clone(); let theme = presets::by_id(cx, &crate::ui::theme::effective_preset_id(cx));