Skip to content

feat(tui): add /theme slash command and fix Plan panel dark theme colors#992

Closed
MengZ-super wants to merge 3 commits intoHmbown:mainfrom
MengZ-super:main
Closed

feat(tui): add /theme slash command and fix Plan panel dark theme colors#992
MengZ-super wants to merge 3 commits intoHmbown:mainfrom
MengZ-super:main

Conversation

@MengZ-super
Copy link
Copy Markdown
Contributor

Summary

  • Add /theme command to toggle between light/dark themes at runtime
  • Add --theme CLI flag (--theme dark / --theme light) for startup theme selection
  • Fix Plan panel displaying white/light background in dark theme by setting explicit section_bg: DEEPSEEK_INK instead of Color::Reset
  • Fix plan_progress_color and plan_completed_color to use deeper DEEPSEEK_BLUE instead of bright DEEPSEEK_SKY blue in dark theme
  • Restore Ctrl+T → Live Transcript Overlay (revert accidental toggle_theme binding)
  • Add theme field to TuiOptions and update all test initializers
  • Add KbLiveTranscript localization for Ctrl+T keybinding description

Test plan

  • Run cargo build successfully
  • Test /theme command toggles theme correctly
  • Verify Plan panel has dark background in dark theme (previously showed white)
  • Verify Ctrl+T opens live transcript overlay
  • Run cargo test -p deepseek-tui and confirm all tests pass

🤖 Generated with Claude Code

MengZ-super and others added 3 commits May 7, 2026 16:04
- Add /theme command to toggle between light/dark themes at runtime
- Add --theme CLI flag for startup theme selection
- Fix Plan panel displaying white background in dark theme by setting
  explicit section_bg instead of Color::Reset
- Fix plan_progress_color and plan_completed_color to use deeper
  DEEPSEEK_BLUE instead of bright SKY blue in dark theme
- Restore Ctrl+T → Live Transcript Overlay (revert accidental
  toggle_theme binding)
- Add theme field to TuiOptions and update all test initializers
- Add KbLiveTranscript localization for Ctrl+T keybinding

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Accept origin/main palette.rs restructuring (PaletteMode, LIGHT_UI_THEME)
and fix theme-related references to use new UITheme names.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nd-plan-panel-fix

feat(tui): add /theme slash command and fix Plan panel dark theme colors
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a theme system to the TUI, enabling users to switch between light and dark modes via a new /theme command or a --theme CLI flag. The implementation includes a light theme definition, global theme state management with persistence to user preferences, and updated localizations. Review feedback identifies critical issues including a naming inconsistency that will cause compilation errors, logic duplication between the command handler and the App struct, and an incomplete UI state update when initializing via the CLI flag. Additionally, concerns were raised regarding the efficiency and safety of the thread-based persistence mechanism and the presence of unused localization keys.

Comment on lines +509 to +527
pub fn theme(app: &mut App) -> CommandResult {
let current = crate::deepseek_theme::active_theme().variant;
let (new_variant, label) = match current {
crate::deepseek_theme::Variant::Dark => (crate::deepseek_theme::Variant::Light, "light"),
crate::deepseek_theme::Variant::Light => (crate::deepseek_theme::Variant::Dark, "dark"),
};
let new_theme = if new_variant == crate::deepseek_theme::Variant::Light {
crate::deepseek_theme::Theme::light()
} else {
crate::deepseek_theme::Theme::dark()
};
crate::deepseek_theme::set_active_theme(new_theme);
app.ui_theme = if new_variant == crate::deepseek_theme::Variant::Light {
crate::palette::UI_THEME_LIGHT
} else {
crate::palette::UI_THEME
};
CommandResult::message(format!("Theme switched to {label}."))
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic for toggling the theme is duplicated here and in App::toggle_theme. Additionally, there is a naming discrepancy for the palette constant: this file uses UI_THEME_LIGHT (line 522), while crates/tui/src/tui/app.rs uses LIGHT_UI_THEME (line 3706). This inconsistency will likely cause a compilation error. It is better to delegate the toggle logic to the App method to ensure consistency and maintainability.

pub fn theme(app: &mut App) -> CommandResult {
    app.toggle_theme();
    let label = if crate::deepseek_theme::active_theme().variant == crate::deepseek_theme::Variant::Light {
        "light"
    } else {
        "dark"
    };
    CommandResult::message(format!("Theme switched to {label}."))
}

Comment thread crates/tui/src/tui/ui.rs
Comment on lines +255 to +261
if let Some(theme_arg) = options.theme.as_ref() {
let theme = match theme_arg {
crate::deepseek_theme::ThemeArg::Dark => crate::deepseek_theme::Theme::dark(),
crate::deepseek_theme::ThemeArg::Light => crate::deepseek_theme::Theme::light(),
};
crate::deepseek_theme::set_active_theme(theme);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

When the --theme CLI flag is provided, app.ui_theme is not updated to match the requested theme. This will result in an inconsistent UI state where some components use the new theme (via the global active_theme()) while others remain in the default theme (via app.ui_theme). Ensure app.ui_theme is updated here as well.

    if let Some(theme_arg) = options.theme.as_ref() {
        let theme = match theme_arg {
            crate::deepseek_theme::ThemeArg::Dark => crate::deepseek_theme::Theme::dark(),
            crate::deepseek_theme::ThemeArg::Light => crate::deepseek_theme::Theme::light(),
        };
        crate::deepseek_theme::set_active_theme(theme);
        app.ui_theme = if theme.variant == crate::deepseek_theme::Variant::Light {
            crate::palette::LIGHT_UI_THEME
        } else {
            crate::palette::UI_THEME
        };
    }

Comment on lines +179 to +184
std::thread::spawn(move || {
if let Ok(mut prefs) = crate::settings::TuiPrefs::load() {
prefs.theme = variant_str.to_string();
let _ = prefs.save();
}
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Spawning a new thread for every theme change to persist preferences is inefficient and potentially prone to race conditions if TuiPrefs::load() and save() are called concurrently (e.g., if a user toggles the theme rapidly). Since this is a TUI application, consider using a more robust persistence mechanism, such as a background worker or an async task if the runtime is available.

KbToolDetailsPager,
KbThinkingPager,
KbLiveTranscript,
KbToggleTheme,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The KbToggleTheme message ID is added and translated across multiple languages, but it is not used in crates/tui/src/tui/keybindings.rs or elsewhere in the current changes. If a keybinding for toggling the theme was intended, it should be added to the keybindings list; otherwise, this appears to be dead code.

MengZ-super added a commit to MengZ-super/DeepSeek-TUI that referenced this pull request May 7, 2026
Fixes two review comments from PR Hmbown#992:
1. config::theme() now delegates to App::toggle_theme() instead
   of duplicating the toggle logic
2. --theme CLI flag now updates app.ui_theme to maintain consistent
   UI state between the active theme and the UI_THEME palette

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@MengZ-super MengZ-super closed this May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant