v0.2.14 : 9 nouveaux themes - nord, solarized, gruvbox, catppuccin, tokyo-night, monokai, matrix, rose-pine, amber (15 au total), liste des themes sur deux lignes dans la banniere

This commit is contained in:
2026-08-16 21:01:15 -04:00
parent b3437b0601
commit f968d7d0b0
5 changed files with 172 additions and 15 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ pub struct Cli {
#[arg(long, global = true, action = ArgAction::SetTrue)]
pub no_color: bool,
/// Color theme for the output: default, ocean, sunset, forest, dracula, mono
/// Color theme for the output (see 'am help theme' for the list)
#[arg(long, global = true, value_name = "THEME")]
pub theme: Option<String>,
+2 -2
View File
@@ -66,8 +66,8 @@ pub struct Settings {
/// GitHub repository (owner/repo) used by the self-update command.
#[serde(default)]
pub self_update_repo: Option<String>,
/// Color theme for the output: default, ocean, sunset, forest, dracula,
/// mono (the --theme flag overrides it).
/// Color theme for the output (see 'am help theme' for the list; the
/// --theme flag overrides it).
#[serde(default)]
pub theme: Option<String>,
}
+2 -2
View File
@@ -103,7 +103,7 @@ const GLOBAL_FLAGS: &[HelpFlag] = &[
short: "",
long: "--theme",
value: "THEME",
desc: "Color theme for the output: default, ocean, sunset, forest, dracula, mono",
desc: "Color theme for the output (see 'am help theme' for the list)",
},
];
@@ -517,7 +517,7 @@ pub static HELP_SPECS: &[HelpSpec] = &[
flags: &[],
subcommands: &[],
parameters: &[
HelpParam { name: "name", typ: "string", desc: "Theme to switch to (default, ocean, sunset, forest, dracula, mono); omit to list them" },
HelpParam { name: "name", typ: "string", desc: "Theme to switch to; omit to list every available theme" },
],
io: None,
examples: &[
+15 -10
View File
@@ -572,11 +572,16 @@ pub fn banner_box(
.map(|t| t.name)
.filter(|n| *n != theme.name)
.collect();
rows.push(inner(dim(
&format!(" ⇄ {}", theme_others.join(" · ")),
theme,
color,
)));
// The full list may not fit one line: wrap it into two ⇄ lines.
let half = theme_others.len().div_ceil(2);
for (i, chunk) in theme_others.chunks(half).enumerate() {
let line = format!(
"{}⇄ {}",
if i == 0 { " " } else { " " },
chunk.join(" · ")
);
rows.push(inner(dim(&line, theme, color)));
}
rows.push(inner(dim(
" 'am --theme <name>' to switch · settings.theme in the config",
theme,
@@ -1623,13 +1628,13 @@ mod tests {
// The splash screen shows the active theme and every other theme.
assert!(text.contains("Theme"));
assert!(text.contains("◉ default"));
assert!(text.contains("ocean"));
assert!(text.contains("sunset"));
assert!(text.contains("forest"));
assert!(text.contains("dracula"));
assert!(text.contains("mono"));
assert!(text.contains("theme default"));
assert!(text.contains("--theme <name>"));
for t in crate::theme::THEMES {
if t.name != "default" {
assert!(text.contains(t.name), "banner misses theme {}", t.name);
}
}
}
#[test]
+152
View File
@@ -106,6 +106,132 @@ pub static THEMES: &[Theme] = &[
key: "38;5;141",
value: "1",
},
Theme {
name: "nord",
title: "Nord (arctic frost)",
header: "1;38;5;109",
accent: "1;38;5;108",
info: "38;5;110",
dim: "2",
border: "38;5;109",
warn: "38;5;222",
error: "38;5;167",
ok: "1;38;5;108",
key: "38;5;110",
value: "1",
},
Theme {
name: "solarized",
title: "Solarized (dark)",
header: "1;38;5;32",
accent: "1;38;5;100",
info: "38;5;37",
dim: "2",
border: "38;5;102",
warn: "38;5;136",
error: "38;5;160",
ok: "1;38;5;100",
key: "38;5;37",
value: "1",
},
Theme {
name: "gruvbox",
title: "Gruvbox (retro warm)",
header: "1;38;5;109",
accent: "1;38;5;142",
info: "38;5;66",
dim: "2",
border: "38;5;59",
warn: "38;5;214",
error: "38;5;167",
ok: "1;38;5;142",
key: "38;5;108",
value: "1",
},
Theme {
name: "catppuccin",
title: "Catppuccin (pastel)",
header: "1;38;5;111",
accent: "1;38;5;114",
info: "38;5;117",
dim: "2",
border: "38;5;111",
warn: "38;5;229",
error: "38;5;210",
ok: "1;38;5;114",
key: "38;5;140",
value: "1",
},
Theme {
name: "tokyo-night",
title: "Tokyo Night (neon)",
header: "1;38;5;111",
accent: "1;38;5;114",
info: "38;5;117",
dim: "2",
border: "38;5;111",
warn: "38;5;215",
error: "38;5;204",
ok: "1;38;5;114",
key: "38;5;141",
value: "1",
},
Theme {
name: "monokai",
title: "Monokai (classic IDE)",
header: "1;38;5;81",
accent: "1;38;5;148",
info: "38;5;81",
dim: "2",
border: "38;5;81",
warn: "38;5;185",
error: "38;5;197",
ok: "1;38;5;148",
key: "38;5;141",
value: "1",
},
Theme {
name: "matrix",
title: "Matrix (green phosphor)",
header: "1;38;5;46",
accent: "1;38;5;40",
info: "38;5;34",
dim: "2",
border: "38;5;34",
warn: "38;5;190",
error: "38;5;196",
ok: "1;38;5;40",
key: "38;5;40",
value: "1",
},
Theme {
name: "rose-pine",
title: "Rose Pine (elegant pink)",
header: "1;38;5;183",
accent: "1;38;5;216",
info: "38;5;117",
dim: "2",
border: "38;5;183",
warn: "38;5;180",
error: "38;5;204",
ok: "1;38;5;216",
key: "38;5;183",
value: "1",
},
Theme {
name: "amber",
title: "Amber (retro CRT)",
header: "1;38;5;214",
accent: "1;38;5;215",
info: "38;5;178",
dim: "2",
border: "38;5;172",
warn: "38;5;220",
error: "38;5;196",
ok: "1;38;5;215",
key: "38;5;214",
value: "1",
},
Theme {
name: "mono",
title: "Mono (no colors)",
@@ -241,6 +367,32 @@ mod tests {
}
}
#[test]
fn theme_names_are_unique() {
let mut names: Vec<&str> = THEMES.iter().map(|t| t.name).collect();
names.sort();
names.dedup();
assert_eq!(names.len(), THEMES.len(), "duplicate theme names");
}
#[test]
fn extended_catalog_is_findable() {
for name in [
"nord",
"solarized",
"gruvbox",
"catppuccin",
"tokyo-night",
"monokai",
"matrix",
"rose-pine",
"amber",
] {
assert!(find(name).is_some(), "missing theme {name}");
}
assert_eq!(THEMES.len(), 15);
}
#[test]
fn frame_paints_with_the_theme_border_color() {
let t = find("ocean").unwrap();