终端主题:浅色、深色外观各选一套,界面切深浅时终端跟着换

- 设置 › 外观新开「终端主题」组,左栏浅色、右栏深色各 10 套内置主题,
  卡片是主题名加一段 ls 示例,选中的整张加底色、右上角蓝底对勾。同一
  主题的浅、深两版在同一行,没有另一版的排最后。应用外观(含跟随系统、
  标题栏按钮)决定用哪一栏。
- 默认 ShellRS Light / Dark:背景、文字、光标、选区和原来一样,16 色
  按 Tailwind 色阶重调,浅色下黄字等不再看不清。第三方主题取自各项目
  自己的终端配色(MIT、Apache-2.0),出处写在源码里。
- 终端格子、边距、选区、链接都取自终端主题;程序查询颜色(OSC 4 / 10
  / 11 / 12)按当前主题回答,不再一律答深色背景。字体和关键字高亮的
  预览也用当前主题。
- 不做自定义主题、导入、按主机指定。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
XuzandClaude Opus 5.5 committed 2026-10-06 21:39:22 +08:00
1 parent 2aa5d5be49
commit d791dad8ae
13 files changed
+1076 -88

No files matched your search

+66
View File
@@ -318,6 +318,72 @@ fn the_appearance_setting_drives_the_theme_and_the_title_bar_switch(cx: &mut Tes
.unwrap();
}
#[gpui_kit::test]
fn terminal_themes_follow_the_appearance_and_a_card_chooses_one(cx: &mut TestAppContext) {
use gpui_kit::component::ThemeMode;
use shellrs::terminal::{TerminalColors, TerminalTheme};
let (handle, workspace) = open_workspace(cx);
let settings = cx.update(|cx| workspace.read(cx).settings().clone());
let in_effect = |cx: &mut TestAppContext| cx.update(|cx| TerminalColors::current(cx).key());
let set_appearance = |appearance, cx: &mut TestAppContext| {
cx.update(|cx| {
settings.update(cx, |settings, cx| {
settings.update(|settings| settings.appearance = appearance, cx)
})
});
cx.run_until_parked();
};
let card = |theme: &TerminalTheme| {
gpui_kit::SharedString::from(format!("terminal-theme-{}", theme.key()))
};
let light = TerminalTheme::for_mode(ThemeMode::Light).nth(1).unwrap();
let dark = TerminalTheme::for_mode(ThemeMode::Dark).nth(1).unwrap();
set_appearance(Appearance::Light, cx);
assert_eq!(in_effect(cx), "shellrs-light");
in_frame(cx, handle, |window, cx| window.click("open-settings", cx));
// 外观 is the first category; its second group holds both columns.
in_frame(cx, handle, |window, cx| {
window.within("settings").click("0-0", cx)
});
in_frame(cx, handle, |window, cx| {
assert_eq!(
window.find("terminal-theme-shellrs-light").checked(),
Some(true)
);
assert_eq!(
window.find("terminal-theme-shellrs-dark").checked(),
Some(true)
);
assert_eq!(window.find(card(light)).checked(), Some(false));
window.click(card(light), cx);
});
cx.update(|cx| {
assert_eq!(
settings.read(cx).settings().terminal_theme.light,
light.key()
)
});
// The light column is the one in effect, so the terminals change now.
assert_eq!(in_effect(cx), light.key());
in_frame(cx, handle, |window, cx| {
assert_eq!(window.find(card(light)).checked(), Some(true));
assert_eq!(
window.find("terminal-theme-shellrs-light").checked(),
Some(false)
);
window.click(card(dark), cx);
});
// The dark one waits for the dark appearance.
cx.update(|cx| assert_eq!(settings.read(cx).settings().terminal_theme.dark, dark.key()));
assert_eq!(in_effect(cx), light.key());
set_appearance(Appearance::Dark, cx);
assert_eq!(in_effect(cx), dark.key());
set_appearance(Appearance::Light, cx);
assert_eq!(in_effect(cx), light.key());
}
/// The 关键字高亮 rules, as the settings hold them.
fn highlight_rules(
workspace: &Entity<Workspace>,