Skip to content

Commit e93b7c7

Browse files
authored
Support color theme config (#93)
* Enable serde feature in ratatui * Add ColorTheme support to configuration * Fix to use SmartDefault * Update README
1 parent 592fe28 commit e93b7c7

File tree

6 files changed

+121
-56
lines changed

6 files changed

+121
-56
lines changed

Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ image = { version = "0.25.6", default-features = false, features = [
2929
] }
3030
laurier = "0.1.0"
3131
once_cell = "1.21.3"
32-
ratatui = "0.29.0"
32+
ratatui = { version = "0.29.0", features = ["serde"] }
3333
rayon = "1.11.0"
3434
semver = "1.0.26"
3535
serde = { version = "1.0.219", features = ["derive"] }

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,55 @@ edge = "#00000000"
340340
# type: string
341341
background = "#00000000"
342342

343+
[color]
344+
# The colors of each element of the application.
345+
# Note: Graph colors are specified with [graph.color].
346+
#
347+
# Colors should be specified in one of the following formats:
348+
# - ANSI color name
349+
# - "red", "bright-blue", "light-red", "reset", ...
350+
# - 8-bit color (256-color) index values
351+
# - "34", "128", "255", ...
352+
# - 24-bit true color hex codes
353+
# - "#abcdef", ...
354+
# type: string
355+
fg = "reset"
356+
bg = "reset"
357+
list_selected_fg = "white"
358+
list_selected_bg = "dark-gray"
359+
list_ref_paren_fg = "yellow"
360+
list_ref_branch_fg = "green"
361+
list_ref_remote_branch_fg = "red"
362+
list_ref_tag_fg = "yellow"
363+
list_ref_stash_fg = "magenta"
364+
list_head_fg = "cyan"
365+
list_subject_fg = "reset"
366+
list_name_fg = "cyan"
367+
list_hash_fg = "yellow"
368+
list_date_fg = "magenta"
369+
list_match_fg = "black"
370+
list_match_bg = "yellow"
371+
detail_email_fg = "blue"
372+
detail_ref_branch_fg = "green"
373+
detail_ref_remote_branch_fg = "red"
374+
detail_ref_tag_fg = "yellow"
375+
detail_file_change_add_fg = "green"
376+
detail_file_change_modify_fg = "yellow"
377+
detail_file_change_delete_fg = "red"
378+
detail_file_change_move_fg = "magenta"
379+
ref_selected_fg = "white"
380+
ref_selected_bg = "dark-gray"
381+
help_block_title_fg = "green"
382+
help_key_fg = "yellow"
383+
virtual_cursor_fg = "reset"
384+
status_input_fg = "reset"
385+
status_input_transient_fg = "dark-gray"
386+
status_info_fg = "cyan"
387+
status_success_fg = "green"
388+
status_warn_fg = "yellow"
389+
status_error_fg = "red"
390+
divider_fg = "dark-gray"
391+
343392
[keybind]
344393
# See ./assets/default-keybind.toml for a specific example configuration.
345394
# ...

src/color.rs

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,93 @@
11
use ratatui::style::Color as RatatuiColor;
2+
use serde::Deserialize;
3+
use smart_default::SmartDefault;
4+
use umbra::optional;
25

36
use crate::config::GraphColorConfig;
47

5-
#[derive(Debug)]
8+
#[optional(derives = [Deserialize], visibility = pub)]
9+
#[derive(Debug, Clone, PartialEq, Eq, SmartDefault)]
610
pub struct ColorTheme {
11+
#[default(RatatuiColor::Reset)]
712
pub fg: RatatuiColor,
13+
#[default(RatatuiColor::Reset)]
814
pub bg: RatatuiColor,
915

16+
#[default(RatatuiColor::White)]
1017
pub list_selected_fg: RatatuiColor,
18+
#[default(RatatuiColor::DarkGray)]
1119
pub list_selected_bg: RatatuiColor,
20+
#[default(RatatuiColor::Yellow)]
1221
pub list_ref_paren_fg: RatatuiColor,
22+
#[default(RatatuiColor::Green)]
1323
pub list_ref_branch_fg: RatatuiColor,
24+
#[default(RatatuiColor::Red)]
1425
pub list_ref_remote_branch_fg: RatatuiColor,
26+
#[default(RatatuiColor::Yellow)]
1527
pub list_ref_tag_fg: RatatuiColor,
28+
#[default(RatatuiColor::Magenta)]
1629
pub list_ref_stash_fg: RatatuiColor,
30+
#[default(RatatuiColor::Cyan)]
1731
pub list_head_fg: RatatuiColor,
32+
#[default(RatatuiColor::Reset)]
1833
pub list_subject_fg: RatatuiColor,
34+
#[default(RatatuiColor::Cyan)]
1935
pub list_name_fg: RatatuiColor,
36+
#[default(RatatuiColor::Yellow)]
2037
pub list_hash_fg: RatatuiColor,
38+
#[default(RatatuiColor::Magenta)]
2139
pub list_date_fg: RatatuiColor,
40+
#[default(RatatuiColor::Black)]
2241
pub list_match_fg: RatatuiColor,
42+
#[default(RatatuiColor::Yellow)]
2343
pub list_match_bg: RatatuiColor,
2444

45+
#[default(RatatuiColor::Blue)]
2546
pub detail_email_fg: RatatuiColor,
47+
#[default(RatatuiColor::Green)]
2648
pub detail_ref_branch_fg: RatatuiColor,
49+
#[default(RatatuiColor::Red)]
2750
pub detail_ref_remote_branch_fg: RatatuiColor,
51+
#[default(RatatuiColor::Yellow)]
2852
pub detail_ref_tag_fg: RatatuiColor,
53+
#[default(RatatuiColor::Green)]
2954
pub detail_file_change_add_fg: RatatuiColor,
55+
#[default(RatatuiColor::Yellow)]
3056
pub detail_file_change_modify_fg: RatatuiColor,
57+
#[default(RatatuiColor::Red)]
3158
pub detail_file_change_delete_fg: RatatuiColor,
59+
#[default(RatatuiColor::Magenta)]
3260
pub detail_file_change_move_fg: RatatuiColor,
3361

62+
#[default(RatatuiColor::White)]
3463
pub ref_selected_fg: RatatuiColor,
64+
#[default(RatatuiColor::DarkGray)]
3565
pub ref_selected_bg: RatatuiColor,
3666

67+
#[default(RatatuiColor::Green)]
3768
pub help_block_title_fg: RatatuiColor,
69+
#[default(RatatuiColor::Yellow)]
3870
pub help_key_fg: RatatuiColor,
3971

72+
#[default(RatatuiColor::Reset)]
4073
pub virtual_cursor_fg: RatatuiColor,
74+
#[default(RatatuiColor::Reset)]
4175
pub status_input_fg: RatatuiColor,
76+
#[default(RatatuiColor::DarkGray)]
4277
pub status_input_transient_fg: RatatuiColor,
78+
#[default(RatatuiColor::Cyan)]
4379
pub status_info_fg: RatatuiColor,
80+
#[default(RatatuiColor::Green)]
4481
pub status_success_fg: RatatuiColor,
82+
#[default(RatatuiColor::Yellow)]
4583
pub status_warn_fg: RatatuiColor,
84+
#[default(RatatuiColor::Red)]
4685
pub status_error_fg: RatatuiColor,
4786

87+
#[default(RatatuiColor::DarkGray)]
4888
pub divider_fg: RatatuiColor,
4989
}
5090

51-
impl Default for ColorTheme {
52-
fn default() -> Self {
53-
Self {
54-
fg: RatatuiColor::Reset,
55-
bg: RatatuiColor::Reset,
56-
57-
list_selected_fg: RatatuiColor::White,
58-
list_selected_bg: RatatuiColor::DarkGray,
59-
list_ref_paren_fg: RatatuiColor::Yellow,
60-
list_ref_branch_fg: RatatuiColor::Green,
61-
list_ref_remote_branch_fg: RatatuiColor::Red,
62-
list_ref_tag_fg: RatatuiColor::Yellow,
63-
list_ref_stash_fg: RatatuiColor::Magenta,
64-
list_head_fg: RatatuiColor::Cyan,
65-
list_subject_fg: RatatuiColor::Reset,
66-
list_name_fg: RatatuiColor::Cyan,
67-
list_hash_fg: RatatuiColor::Yellow,
68-
list_date_fg: RatatuiColor::Magenta,
69-
list_match_fg: RatatuiColor::Black,
70-
list_match_bg: RatatuiColor::Yellow,
71-
72-
detail_email_fg: RatatuiColor::Blue,
73-
detail_ref_branch_fg: RatatuiColor::Green,
74-
detail_ref_remote_branch_fg: RatatuiColor::Red,
75-
detail_ref_tag_fg: RatatuiColor::Yellow,
76-
detail_file_change_add_fg: RatatuiColor::Green,
77-
detail_file_change_modify_fg: RatatuiColor::Yellow,
78-
detail_file_change_delete_fg: RatatuiColor::Red,
79-
detail_file_change_move_fg: RatatuiColor::Magenta,
80-
81-
ref_selected_fg: RatatuiColor::White,
82-
ref_selected_bg: RatatuiColor::DarkGray,
83-
84-
help_block_title_fg: RatatuiColor::Green,
85-
help_key_fg: RatatuiColor::Yellow,
86-
87-
virtual_cursor_fg: RatatuiColor::Reset,
88-
status_input_fg: RatatuiColor::Reset,
89-
status_input_transient_fg: RatatuiColor::DarkGray,
90-
status_info_fg: RatatuiColor::Cyan,
91-
status_success_fg: RatatuiColor::Green,
92-
status_warn_fg: RatatuiColor::Yellow,
93-
status_error_fg: RatatuiColor::Red,
94-
95-
divider_fg: RatatuiColor::DarkGray,
96-
}
97-
}
98-
}
99-
10091
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10192
pub struct GraphColor {
10293
r: u8,

src/config.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,25 @@ use serde::Deserialize;
88
use smart_default::SmartDefault;
99
use umbra::optional;
1010

11-
use crate::{keybind::KeyBind, Result};
11+
use crate::{
12+
color::{ColorTheme, OptionalColorTheme},
13+
keybind::KeyBind,
14+
Result,
15+
};
1216

1317
const XDG_CONFIG_HOME_ENV_NAME: &str = "XDG_CONFIG_HOME";
1418
const DEFAULT_CONFIG_DIR: &str = ".config";
1519
const APP_DIR_NAME: &str = "serie";
1620
const CONFIG_FILE_NAME: &str = "config.toml";
1721
const CONFIG_FILE_ENV_NAME: &str = "SERIE_CONFIG_FILE";
1822

19-
pub fn load() -> Result<(CoreConfig, UiConfig, GraphConfig, Option<KeyBind>)> {
23+
pub fn load() -> Result<(
24+
CoreConfig,
25+
UiConfig,
26+
GraphConfig,
27+
ColorTheme,
28+
Option<KeyBind>,
29+
)> {
2030
let config = match config_file_path_from_env() {
2131
Some(user_path) => {
2232
if !user_path.exists() {
@@ -37,7 +47,13 @@ pub fn load() -> Result<(CoreConfig, UiConfig, GraphConfig, Option<KeyBind>)> {
3747
}
3848
}
3949
}?;
40-
Ok((config.core, config.ui, config.graph, config.keybind))
50+
Ok((
51+
config.core,
52+
config.ui,
53+
config.graph,
54+
config.color,
55+
config.keybind,
56+
))
4157
}
4258

4359
fn config_file_path_from_env() -> Option<PathBuf> {
@@ -67,6 +83,8 @@ struct Config {
6783
ui: UiConfig,
6884
#[nested]
6985
graph: GraphConfig,
86+
#[nested]
87+
color: ColorTheme,
7088
// The user customed keybinds, please ref `assets/default-keybind.toml`
7189
keybind: Option<KeyBind>,
7290
}
@@ -323,6 +341,7 @@ mod tests {
323341
background: "#00000000".into(),
324342
},
325343
},
344+
color: ColorTheme::default(),
326345
keybind: None,
327346
};
328347
assert_eq!(actual, expected);
@@ -423,6 +442,7 @@ mod tests {
423442
background: "#ffffff".into(),
424443
},
425444
},
445+
color: ColorTheme::default(),
426446
keybind: None,
427447
};
428448
assert_eq!(actual, expected);
@@ -491,6 +511,7 @@ mod tests {
491511
background: "#00000000".into(),
492512
},
493513
},
514+
color: ColorTheme::default(),
494515
keybind: None,
495516
};
496517
assert_eq!(actual, expected);

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,9 @@ pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
9090

9191
pub fn run() -> Result<()> {
9292
let args = Args::parse();
93-
let (core_config, ui_config, graph_config, key_bind_patch) = config::load()?;
93+
let (core_config, ui_config, graph_config, color_theme, key_bind_patch) = config::load()?;
9494
let key_bind = keybind::KeyBind::new(key_bind_patch);
9595

96-
let color_theme = color::ColorTheme::default();
9796
let graph_color_set = color::GraphColorSet::new(&graph_config.color);
9897
let image_protocol = args.protocol.into();
9998

0 commit comments

Comments
 (0)