currently, you can only use ansi colors: 0-255. I would love to be able to specify an arbitrary rgb color instead. ideally, with this syntax: #aabbcc, but according to my looking at the source code, it will be easier to make syntax like { r = …, g = …, b = … }
I started writing the patch myself, but stopped when I realized this project prints escape codes manually, rather than using a library. so maybe, my work so far might be useful:
diff --git i/src/conf/skin.rs w/src/conf/skin.rs
index a338c0a..6e931e3 100644
--- i/src/conf/skin.rs
+++ w/src/conf/skin.rs
@@ -1,139 +1,135 @@
-use {
- paste::paste,
- schemars::JsonSchema,
- serde::Deserialize,
- termimad::crossterm::style::Color,
-};
+use {paste::paste, schemars::JsonSchema, serde::Deserialize, termimad::crossterm::style::Color};
-/// Define a `BaconSkin` struct with fields being u8 with default values.
-macro_rules! BaconSkin {
- (
- $( $(#[$meta:meta])* $name:ident: $default:literal, )*
- ) => {
- paste! {
- $(
- $(#[$meta])*
- #[doc=concat!(" - default value: ", stringify!($default))]
- #[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, JsonSchema)]
- #[serde(untagged)]
- pub enum [<Defaulting$name:camel>] {
- Set(u8),
- #[default]
- Unset,
- }
- impl [<Defaulting$name:camel>] {
- pub fn value(self) -> u8 {
- match self {
- Self::Set(value) => value,
- Self::Unset => $default,
- }
- }
- pub fn apply(&mut self, other: Self) {
- if let Self::Set(value) = other {
- *self = Self::Set(value);
- }
- }
- pub fn color(self) -> Color {
- Color::AnsiValue(self.value())
- }
- }
- )*
- /// Collection of optional color overrides for the Bacon UI.
- #[derive(Debug, Clone, Copy, Default, Deserialize, PartialEq, JsonSchema)]
- pub struct BaconSkin {
- $(
- $(#[$meta])*
- #[serde(default)]
- pub $name: [<Defaulting$name:camel>],
- )*
- }
- impl BaconSkin {
- pub fn apply(&mut self, other: Self) {
- $(
- self.$name.apply(other.$name);
- )*
- }
- $(
- #[inline]
- pub fn [<$name>](&self) -> u8 {
- self.$name.value()
- }
- )*
- }
+#[derive(Debug, Clone, Deserialize, PartialEq, JsonSchema)]
+pub enum ConfigColor {
+ Ansi(u8),
+ Rgb(u8, u8, u8),
+}
+
+impl From<ConfigColor> for Color {
+ fn from(value: ConfigColor) -> Self {
+ match value {
+ ConfigColor::Ansi(color) => Self::AnsiValue(color),
+ ConfigColor::Rgb(red, green, blue) => Self::Rgb {
+ r: red,
+ g: green,
+ b: blue,
+ },
}
}
}
-// The colors of Bacon, with default values (ANSI color codes, in 0-255)
-BaconSkin! {
+#[derive(Debug, Clone, Deserialize, PartialEq, JsonSchema)]
+pub struct BaconSkin {
/// Foreground color of the status line
- status_fg: 252,
+ pub status_fg: ConfigColor,
/// Background color of the status line
- status_bg: 239,
+ pub status_bg: ConfigColor,
/// Foreground color used for key shortcuts in the UI
- key_fg: 204,
+ pub key_fg: ConfigColor,
/// Foreground color for key shortcuts displayed in the status line
- status_key_fg: 204,
+ pub status_key_fg: ConfigColor,
/// Foreground color of the project name badge
- project_name_badge_fg: 255,
+ pub project_name_badge_fg: ConfigColor,
/// Background color of the project name badge
- project_name_badge_bg: 240,
+ pub project_name_badge_bg: ConfigColor,
/// Foreground color of the job label badge
- job_label_badge_fg: 235,
+ pub job_label_badge_fg: ConfigColor,
/// Background color of the job label badge
- job_label_badge_bg: 204,
+ pub job_label_badge_bg: ConfigColor,
/// Foreground color of the errors badge
- errors_badge_fg: 235,
+ pub errors_badge_fg: ConfigColor,
/// Background color of the errors badge
- errors_badge_bg: 9,
+ pub errors_badge_bg: ConfigColor,
/// Foreground color of the failing-tests badge
- test_fails_badge_fg: 235,
+ pub test_fails_badge_fg: ConfigColor,
/// Background color of the failing-tests badge
- test_fails_badge_bg: 208,
+ pub test_fails_badge_bg: ConfigColor,
/// Foreground color of the passing-tests badge
- test_pass_badge_fg: 254,
+ pub test_pass_badge_fg: ConfigColor,
/// Background color of the passing-tests badge
- test_pass_badge_bg: 2,
+ pub test_pass_badge_bg: ConfigColor,
/// Foreground color of the warnings badge
- warnings_badge_fg: 235,
+ pub warnings_badge_fg: ConfigColor,
/// Background color of the warnings badge
- warnings_badge_bg: 11,
+ pub warnings_badge_bg: ConfigColor,
/// Foreground color of the command-error badge
- command_error_badge_fg: 235,
+ pub command_error_badge_fg: ConfigColor,
/// Background color of the command-error badge
- command_error_badge_bg: 9,
+ pub command_error_badge_bg: ConfigColor,
/// Foreground color of the dismissed badge
- dismissed_badge_fg: 235,
+ pub dismissed_badge_fg: ConfigColor,
/// Background color of the dismissed badge
- dismissed_badge_bg: 6,
+ pub dismissed_badge_bg: ConfigColor,
/// Foreground color of the change badge
- change_badge_fg: 235,
+ pub change_badge_fg: ConfigColor,
/// Background color of the change badge
- change_badge_bg: 6,
+ pub change_badge_bg: ConfigColor,
/// Foreground color of the "computing..." indicator
- computing_fg: 235,
+ pub computing_fg: ConfigColor,
/// Background color of the "computing..." indicator
- computing_bg: 204,
+ pub computing_bg: ConfigColor,
/// Foreground color of search matches
- found_fg: 208,
+ pub found_fg: ConfigColor,
/// Background color of the selected search match
- found_selected_bg: 208,
+ pub found_selected_bg: ConfigColor,
/// Foreground color of the '/' search prefix
- search_input_prefix_fg: 208,
+ pub search_input_prefix_fg: ConfigColor,
/// Foreground color of the search summary
- search_summary_fg: 208,
+ pub search_summary_fg: ConfigColor,
/// Border color used for menus
- menu_border: 234,
+ pub menu_border: ConfigColor,
/// Background color used for menus
- menu_bg: 235,
+ pub menu_bg: ConfigColor,
/// Background color of individual menu items
- menu_item_bg: 235,
+ pub menu_item_bg: ConfigColor,
/// Background color of the selected menu item
- menu_item_selected_bg: 239,
+ pub menu_item_selected_bg: ConfigColor,
/// Foreground color of menu items
- menu_item_fg: 250,
+ pub menu_item_fg: ConfigColor,
/// Foreground color of the selected menu item
- menu_item_selected_fg: 255,
+ pub menu_item_selected_fg: ConfigColor,
+}
+
+impl Default for BaconSkin {
+ fn default() -> Self {
+ Self {
+ status_fg: ConfigColor::Ansi(252),
+ status_bg: ConfigColor::Ansi(239),
+ key_fg: ConfigColor::Ansi(204),
+ status_key_fg: ConfigColor::Ansi(204),
+ project_name_badge_fg: ConfigColor::Ansi(255),
+ project_name_badge_bg: ConfigColor::Ansi(240),
+ job_label_badge_fg: ConfigColor::Ansi(235),
+ job_label_badge_bg: ConfigColor::Ansi(204),
+ errors_badge_fg: ConfigColor::Ansi(235),
+ errors_badge_bg: ConfigColor::Ansi(9),
+ test_fails_badge_fg: ConfigColor::Ansi(235),
+ test_fails_badge_bg: ConfigColor::Ansi(208),
+ test_pass_badge_fg: ConfigColor::Ansi(254),
+ test_pass_badge_bg: ConfigColor::Ansi(2),
+ warnings_badge_fg: ConfigColor::Ansi(235),
+ warnings_badge_bg: ConfigColor::Ansi(11),
+ command_error_badge_fg: ConfigColor::Ansi(235),
+ command_error_badge_bg: ConfigColor::Ansi(9),
+ dismissed_badge_fg: ConfigColor::Ansi(235),
+ dismissed_badge_bg: ConfigColor::Ansi(6),
+ change_badge_fg: ConfigColor::Ansi(235),
+ change_badge_bg: ConfigColor::Ansi(6),
+ computing_fg: ConfigColor::Ansi(235),
+ computing_bg: ConfigColor::Ansi(204),
+ found_fg: ConfigColor::Ansi(208),
+ found_selected_bg: ConfigColor::Ansi(208),
+ search_input_prefix_fg: ConfigColor::Ansi(208),
+ search_summary_fg: ConfigColor::Ansi(208),
+ menu_border: ConfigColor::Ansi(234),
+ menu_bg: ConfigColor::Ansi(235),
+ menu_item_bg: ConfigColor::Ansi(235),
+ menu_item_selected_bg: ConfigColor::Ansi(239),
+ menu_item_fg: ConfigColor::Ansi(250),
+ menu_item_selected_fg: ConfigColor::Ansi(255),
+ }
+ }
}
#[test]
diff --git i/src/help/help_page.rs w/src/help/help_page.rs
index 3ec79b3..2b3eaf2 100644
--- i/src/help/help_page.rs
+++ w/src/help/help_page.rs
@@ -2,17 +2,9 @@ use {
crate::*,
anyhow::Result,
termimad::{
- Area,
- CompoundStyle,
- FmtText,
- MadSkin,
- TextView,
+ Area, CompoundStyle, FmtText, MadSkin, TextView,
crossterm::style::Attribute,
- minimad::{
- Alignment,
- OwningTemplateExpander,
- TextTemplate,
- },
+ minimad::{Alignment, OwningTemplateExpander, TextTemplate},
},
};
@@ -53,10 +45,10 @@ impl HelpPage {
pub fn new(settings: &Settings) -> Self {
let mut skin = MadSkin::default();
skin.paragraph.align = Alignment::Center;
- let key_color = settings.all_jobs.skin.key_fg.color();
- skin.italic = CompoundStyle::new(Some(key_color), None, Attribute::Bold.into());
+ let key_color = settings.all_jobs.skin.key_fg;
+ skin.italic = CompoundStyle::new(Some(key_color.into()), None, Attribute::Bold.into());
skin.table.align = Alignment::Center;
- skin.bullet.set_fg(key_color);
+ skin.bullet.set_fg(key_color.into());
let mut expander = OwningTemplateExpander::new();
expander.set("version", env!("CARGO_PKG_VERSION"));
let mut bindings: Vec<(String, String)> = settings
diff --git i/src/tui/menu/menu_view.rs w/src/tui/menu/menu_view.rs
index 40c7b56..88afbb6 100644
--- i/src/tui/menu/menu_view.rs
+++ w/src/tui/menu/menu_view.rs
@@ -3,15 +3,9 @@ use {
anyhow::Result,
crokey::{
KeyCombinationFormat,
- crossterm::{
- queue,
- style::Print,
- },
- },
- termimad::{
- minimad::*,
- *,
+ crossterm::{queue, style::Print},
},
+ termimad::{minimad::*, *},
};
/// The drawer of the menu
@@ -76,14 +70,14 @@ impl MenuView {
let mut md_skin = MadSkin::default();
md_skin
.paragraph
- .set_fgbg(skin.menu_item_fg.color(), skin.menu_item_bg.color());
- md_skin.italic.set_fg(skin.key_fg.color());
+ .set_fgbg(skin.menu_item_fg.into(), skin.menu_item_bg.into());
+ md_skin.italic.set_fg(skin.key_fg.into());
let mut sel_md_skin = MadSkin::default();
sel_md_skin.paragraph.set_fgbg(
- skin.menu_item_selected_fg.color(),
- skin.menu_item_selected_bg.color(),
+ skin.menu_item_selected_fg.into(),
+ skin.menu_item_selected_bg.into(),
);
- sel_md_skin.italic.set_fg(skin.key_fg.color());
+ sel_md_skin.italic.set_fg(skin.key_fg.into());
let area_width = self.compute_area_width(Self::estimate_content_optimal_width(state));
let mut intro_lines = Vec::new();
let text_width = area_width - 2;
@@ -100,7 +94,7 @@ impl MenuView {
state.fix_scroll(h);
let mut rect = Rect::new(
area.clone(),
- CompoundStyle::with_fgbg(skin.menu_border.color(), skin.menu_bg.color()),
+ CompoundStyle::with_fgbg(skin.menu_border.into(), skin.menu_bg.into()),
);
rect.set_border_style(BORDER_STYLE_HALF_WIDTH_OUTSIDE);
rect.set_fill(true);
diff --git i/src/tui/mission_state.rs w/src/tui/mission_state.rs
index 29cbc37..1bf7499 100644
--- i/src/tui/mission_state.rs
+++ w/src/tui/mission_state.rs
@@ -2,27 +2,14 @@ use {
crate::*,
anyhow::Result,
crokey::KeyCombination,
- std::{
- io::Write,
- process::ExitStatus,
- time::Instant,
- },
+ std::{io::Write, process::ExitStatus, time::Instant},
termimad::{
- Area,
- CompoundStyle,
- MadSkin,
+ Area, CompoundStyle, MadSkin,
crossterm::{
- cursor,
- execute,
- style::{
- Attribute,
- Print,
- },
- },
- minimad::{
- Alignment,
- Composite,
+ cursor, execute,
+ style::{Attribute, Print},
},
+ minimad::{Alignment, Composite},
},
};
@@ -98,9 +85,9 @@ impl<'a, 'm> MissionState<'a, 'm> {
let skin = mission.job.skin;
status_skin
.paragraph
- .set_fgbg(skin.status_fg.color(), skin.status_bg.color());
+ .set_fgbg(skin.status_fg.into(), skin.status_bg.into());
status_skin.italic = CompoundStyle::new(
- Some(skin.status_key_fg.color()),
+ Some(skin.status_key_fg.into()),
None,
Attribute::Bold.into(),
);
currently, you can only use ansi colors: 0-255. I would love to be able to specify an arbitrary rgb color instead. ideally, with this syntax:
#aabbcc, but according to my looking at the source code, it will be easier to make syntax like{ r = …, g = …, b = … }I started writing the patch myself, but stopped when I realized this project prints escape codes manually, rather than using a library. so maybe, my work so far might be useful: