tmux-copyrat/src/ui/colors.rs

148 lines
4.6 KiB
Rust
Raw Normal View History

2022-11-07 00:02:27 +01:00
use std::fmt;
use std::str::FromStr;
use clap::Args;
use termion::color as tcolor;
2020-06-02 20:03:16 +02:00
2022-05-31 08:47:53 +02:00
use crate::{Error, Result};
2021-10-24 11:57:25 +02:00
2022-11-07 00:02:27 +01:00
#[derive(Debug, Clone, Copy)]
pub struct Color(Option<u8>);
impl tcolor::Color for Color {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
Some(value) => write!(f, "\x1B[38;5;{value}m"),
2022-11-07 00:02:27 +01:00
None => write!(f, "\x1B[39m"),
}
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
Some(value) => write!(f, "\x1B[48;5;{value}m"),
2022-11-07 00:02:27 +01:00
None => write!(f, "\x1B[49m"),
}
}
}
pub(crate) static BLACK: Color = Color(Some(0));
pub(crate) static RED: Color = Color(Some(1));
pub(crate) static GREEN: Color = Color(Some(2));
pub(crate) static YELLOW: Color = Color(Some(3));
pub(crate) static BLUE: Color = Color(Some(4));
pub(crate) static MAGENTA: Color = Color(Some(5));
pub(crate) static CYAN: Color = Color(Some(6));
pub(crate) static WHITE: Color = Color(Some(7));
pub(crate) static BRIGHTBLACK: Color = Color(Some(8));
pub(crate) static BRIGHTRED: Color = Color(Some(9));
pub(crate) static BRIGHTGREEN: Color = Color(Some(10));
pub(crate) static BRIGHTYELLOW: Color = Color(Some(11));
pub(crate) static BRIGHTBLUE: Color = Color(Some(12));
pub(crate) static BRIGHTMAGENTA: Color = Color(Some(13));
pub(crate) static BRIGHTCYAN: Color = Color(Some(14));
pub(crate) static BRIGHTWHITE: Color = Color(Some(15));
pub(crate) static RESET: Color = Color(None);
impl FromStr for Color {
type Err = Error;
fn from_str(src: &str) -> std::result::Result<Self, Self::Err> {
match src {
"black" => Ok(BLACK),
"red" => Ok(RED),
"green" => Ok(GREEN),
"yellow" => Ok(YELLOW),
"blue" => Ok(BLUE),
"magenta" => Ok(MAGENTA),
"cyan" => Ok(CYAN),
"white" => Ok(WHITE),
"bright-black" | "brightblack" => Ok(BRIGHTBLACK),
"bright-red" | "brightred" => Ok(BRIGHTRED),
"bright-green" | "brightgreen" => Ok(BRIGHTGREEN),
"bright-yellow" | "brightyellow" => Ok(BRIGHTYELLOW),
"bright-blue" | "brightblue" => Ok(BRIGHTBLUE),
"bright-magenta" | "brightmagenta" => Ok(BRIGHTMAGENTA),
"bright-cyan" | "brightcyan" => Ok(BRIGHTCYAN),
"bright-white" | "brightwhite" => Ok(BRIGHTWHITE),
"none" => Ok(RESET),
_ => Err(Error::UnknownColor),
}
2020-05-24 21:02:11 +02:00
}
2020-06-02 20:03:16 +02:00
}
2022-11-07 00:02:27 +01:00
pub fn parse_color(src: &str) -> Result<Color> {
Color::from_str(src)
}
2020-06-02 20:03:16 +02:00
#[cfg(test)]
mod tests {
2020-05-24 21:02:11 +02:00
use super::*;
2020-06-02 20:03:16 +02:00
2020-05-24 21:02:11 +02:00
#[test]
2022-11-07 00:02:27 +01:00
fn span_color_fg() {
let actual = format!("{}{}", tcolor::Fg(Color::from_str("green").unwrap()), "foo");
let expected = format!("{}{}", tcolor::Fg(tcolor::Green), "foo");
assert_eq!(actual, expected);
}
#[test]
fn span_color_bg() {
let actual = format!("{}{}", tcolor::Bg(Color::from_str("green").unwrap()), "foo");
let expected = format!("{}{}", tcolor::Bg(tcolor::Green), "foo");
2020-06-02 20:03:16 +02:00
2022-11-07 00:02:27 +01:00
assert_eq!(actual, expected);
2020-05-24 21:02:11 +02:00
}
2020-06-02 20:03:16 +02:00
2020-05-24 21:02:11 +02:00
#[test]
2021-03-22 23:56:35 +01:00
fn no_span_color() {
2022-11-07 00:02:27 +01:00
assert!(
Color::from_str("wat").is_err(),
"this color should not exist"
);
2020-05-24 21:02:11 +02:00
}
2020-06-02 20:03:16 +02:00
}
2021-03-19 09:39:30 +01:00
2021-03-21 11:32:57 +01:00
/// Holds color-related data.
2021-03-19 09:39:30 +01:00
///
2021-03-22 23:56:35 +01:00
/// - `focus_*` colors are used to render the currently focused text span.
/// - `normal_*` colors are used to render other text spans.
2021-03-19 09:39:30 +01:00
/// - `hint_*` colors are used to render the hints.
2022-11-07 00:02:27 +01:00
#[derive(Args, Debug)]
// #[clap(about)] // Needed to avoid this doc comment to be used as overall `about`.
2021-03-19 09:39:30 +01:00
pub struct UiColors {
/// Foreground color for base text.
2022-11-07 00:02:27 +01:00
#[arg(long, default_value = "bright-cyan", value_parser(parse_color))]
pub text_fg: Color,
2021-03-19 09:39:30 +01:00
/// Background color for base text.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "none", value_parser(parse_color))]
pub text_bg: Color,
2021-03-19 09:39:30 +01:00
2021-03-22 23:56:35 +01:00
/// Foreground color for spans.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "blue", value_parser(parse_color))]
pub span_fg: Color,
2021-03-19 09:39:30 +01:00
2021-03-22 23:56:35 +01:00
/// Background color for spans.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "none", value_parser(parse_color))]
pub span_bg: Color,
2021-03-19 09:39:30 +01:00
2021-03-22 23:56:35 +01:00
/// Foreground color for the focused span.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "magenta", value_parser(parse_color))]
pub focused_fg: Color,
2021-03-19 09:39:30 +01:00
2021-03-22 23:56:35 +01:00
/// Background color for the focused span.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "none", value_parser(parse_color))]
pub focused_bg: Color,
2021-03-19 09:39:30 +01:00
/// Foreground color for hints.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "yellow", value_parser(parse_color))]
pub hint_fg: Color,
2021-03-19 09:39:30 +01:00
/// Background color for hints.
2022-11-07 00:02:27 +01:00
#[clap(long, default_value = "none", value_parser(parse_color))]
pub hint_bg: Color,
2021-03-19 09:39:30 +01:00
}