Skip to content

Commit

Permalink
Change --no-color argument into --color always|ansi|never (#491)
Browse files Browse the repository at this point in the history
* Change `--no-color` argument into `--color always|ansi|never`

When `ansi` is chosen, this calculates the closes distance between the
RGB color and one of the 8 basic ANSI colors, with the assumption that

* black = `#000000`
* red = `#FF0000`
* etc.
  • Loading branch information
spenserblack authored Jan 8, 2025
1 parent 461f2fb commit bf5ca9f
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 26 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ serde_json = "1"

[workspace.package]
description = "Get the language distribution stats of your repository"
version = "0.11.5"
version = "0.12.0"
edition = "2021"
repository = "https://github.com/spenserblack/gengo"
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion gengo-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ color = ["gengo/owo-colors", "owo-colors"]

[dependencies]
clap = { version = "4", features = ["derive", "wrap_help"] }
gengo = { path = "../gengo", version = "0.11", default-features = false }
gengo = { path = "../gengo", version = "0.12", default-features = false }
indexmap.workspace = true
owo-colors = { workspace = true, optional = true }
serde_json.workspace = true
Expand Down
80 changes: 63 additions & 17 deletions gengo-bin/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ pub struct CLI {
/// formats always include detailed statistics.
#[arg(short = 'b', long)]
breakdown: bool,
/// Force the output to not have colors.
/// Control when colors are displayed.
#[cfg(feature = "color")]
#[arg(long)]
no_color: bool,
#[arg(long, default_value = "always")]
color: ColorControl,
/// The format to use for output.
#[arg(short = 'F', long, default_value = "pretty")]
format: Format,
Expand All @@ -67,6 +67,17 @@ enum Commands {
},
}

#[cfg(feature = "color")]
#[derive(ValueEnum, Debug, Clone)]
enum ColorControl {
/// Always use colors.
Always,
/// Use only the 8 ANSI colors.
Ansi,
/// Disable colors.
Never,
}

#[derive(ValueEnum, Debug, Clone)]
enum Format {
/// Output for humans.
Expand Down Expand Up @@ -194,28 +205,63 @@ impl CLI {

#[cfg(feature = "color")]
fn colorize(&self, s: &str, color: owo_colors::Rgb) -> String {
use owo_colors::{OwoColorize, Rgb};
use owo_colors::{AnsiColors::*, OwoColorize, Rgb};
use ColorControl::*;

if self.no_color {
return String::from(s);
match self.color {
Never => String::from(s),
Always => {
let fg = if Self::is_bright(color.0, color.1, color.2) {
Rgb(0, 0, 0)
} else {
Rgb(0xFF, 0xFF, 0xFF)
};
s.on_color(color).color(fg).to_string()
}
Ansi => {
let (bg, (r, g, b)) = Self::closest_color(color);
let fg = if Self::is_bright(r, g, b) {
Black
} else {
White
};
s.on_color(bg).color(fg).to_string()
}
}
}

#[cfg(feature = "color")]
fn is_bright(r: u8, g: u8, b: u8) -> bool {
// NOTE Adapted from https://css-tricks.com/converting-color-spaces-in-javascript/#aa-rgb-to-hsl
let r = color.0;
let g = color.1;
let b = color.2;
let min: u16 = [r, g, b].into_iter().min().unwrap().into();
let max: u16 = [r, g, b].into_iter().max().unwrap().into();
let lightness = (max + min) / 2;
let bright = lightness > 0x7F;
lightness > 0x7F
}

let line = s.on_color(color);
let fg = if bright {
Rgb(0, 0, 0)
} else {
Rgb(0xFF, 0xFF, 0xFF)
};
line.color(fg).to_string()
#[cfg(feature = "color")]
fn closest_color(rgb: owo_colors::Rgb) -> (owo_colors::AnsiColors, (u8, u8, u8)) {
use owo_colors::AnsiColors::*;
// NOTE Gets the closest color by Euclidean distance
[
(Black, (0u8, 0u8, 0u8)),
(Red, (0xFF, 0, 0)),
(Yellow, (0xFF, 0xFF, 0)),
(Blue, (0, 0, 0xFF)),
(Magenta, (0xFF, 0, 0xFF)),
(Cyan, (0, 0xFF, 0xFF)),
(White, (0xFF, 0xFF, 0xFF)),
]
.into_iter()
.min_by_key(|(_, (r, g, b))| {
// NOTE As a shortcut we'll just skip the square root step
[(r, rgb.0), (g, rgb.1), (b, rgb.2)]
.into_iter()
.map(|(p1, p2)| u32::from(p1.abs_diff(p2)))
.map(|diff| diff * diff)
.sum::<u32>()
})
.unwrap()
}

#[cfg(not(feature = "color"))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,3 @@ expression: stdout

TypeScript
src/bin.ts


Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ expression: stdout
 40.79% 62 Plain Text
 40.79% 62 TypeScript
 18.42% 28 JavaScript

2 changes: 1 addition & 1 deletion samples-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ license.workspace = true
keywords.workspace = true

[dependencies]
gengo = { path = "../gengo", version = "0.11", default-features = false }
gengo = { path = "../gengo", version = "0.12", default-features = false }

0 comments on commit bf5ca9f

Please sign in to comment.