mirror of
https://github.com/sharkdp/hexyl.git
synced 2026-10-26 20:16:34 +00:00
Enable custom colors with environment variables (#248)
* Enable custom colors with environment variables * Rename HEXYL_XYZ env vars to HEXYL_COLOR_XYZ
This commit is contained in:
1 parent
6220cae644
commit
9ef7c346dd
7 files changed
+268
-32
No files matched your search
+1
-1
@@ -9,7 +9,7 @@ readme = "README.md"
|
|||||||
repository = "https://github.com/sharkdp/hexyl"
|
repository = "https://github.com/sharkdp/hexyl"
|
||||||
version = "0.16.0"
|
version = "0.16.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.74"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
|||||||
@@ -193,6 +193,22 @@ scoop install hexyl
|
|||||||
x env use hexyl
|
x env use hexyl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
`hexyl` colors can be configured via environment variables. The variables used are as follows:
|
||||||
|
|
||||||
|
* `HEXYL_COLOR_ASCII_PRINTABLE`: Any non-whitespace printable ASCII character
|
||||||
|
* `HEXYL_COLOR_ASCII_WHITESPACE`: Whitespace such as space or newline (only visible in middle panel with byte values)
|
||||||
|
* `HEXYL_COLOR_ASCII_OTHER`: Any other ASCII character (< `0x80`) besides null
|
||||||
|
* `HEXYL_COLOR_NULL`: The null byte (`0x00`)
|
||||||
|
* `HEXYL_COLOR_NONASCII`: Any non-ASCII byte (> `0x7F`)
|
||||||
|
* `HEXYL_COLOR_OFFSET`: The lefthand file offset
|
||||||
|
|
||||||
|
The colors can be any of the 8 standard terminal colors: `black`, `blue`, `cyan`, `green`, `magenta`, `red`,
|
||||||
|
`yellow` and `white`. The "bright" variants are also supported (e.g., `bright blue`). Additionally, you can use
|
||||||
|
the RGB hex format, `#abcdef`. For example, `HEXYL_COLOR_ASCII_PRINTABLE=blue HEXYL_COLOR_ASCII_WHITESPACE="bright green"
|
||||||
|
HEXYL_COLOR_ASCII_OTHER="#ff7f99"`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under either of
|
Licensed under either of
|
||||||
|
|||||||
@@ -106,6 +106,22 @@ _FILE_
|
|||||||
**-V**, **\--version**
|
**-V**, **\--version**
|
||||||
: Prints version information.
|
: Prints version information.
|
||||||
|
|
||||||
|
# ENVIRONMENT VARIABLES
|
||||||
|
|
||||||
|
**hexyl** colors can be configured via environment variables. The variables used are as follows:
|
||||||
|
|
||||||
|
: - **HEXYL_COLOR_ASCII_PRINTABLE**: Any non-whitespace printable ASCII character
|
||||||
|
- **HEXYL_COLOR_ASCII_WHITESPACE**: Whitespace such as space or newline (only visible in middle panel with byte values)
|
||||||
|
- **HEXYL_COLOR_ASCII_OTHER**: Any other ASCII character (< **0x80**) besides null
|
||||||
|
- **HEXYL_COLOR_NULL**: The null byte (**0x00**)
|
||||||
|
- **HEXYL_COLOR_NONASCII**: Any non-ASCII byte (> **0x7F**)
|
||||||
|
- **HEXYL_COLOR_OFFSET**: The lefthand file offset
|
||||||
|
|
||||||
|
The colors can be any of the 8 standard terminal colors: **black**, **blue**, **cyan**, **green**, **magenta**, **red**,
|
||||||
|
**yellow** and **white**. The "bright" variants are also supported (e.g., **bright blue**). Additionally, you can use
|
||||||
|
the RGB hex format, **#abcdef**. For example, **HEXYL_COLOR_ASCII_PRINTABLE=blue HEXYL_COLOR_ASCII_WHITESPACE="bright green"
|
||||||
|
HEXYL_COLOR_ASCII_OTHER="#ff7f99"**.
|
||||||
|
|
||||||
# NOTES
|
# NOTES
|
||||||
|
|
||||||
Source repository:
|
Source repository:
|
||||||
|
|||||||
+35
-8
@@ -1,12 +1,39 @@
|
|||||||
use owo_colors::{colors, Color};
|
use owo_colors::{colors, AnsiColors, Color, DynColors, OwoColorize};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
pub const COLOR_NULL: &[u8] = colors::BrightBlack::ANSI_FG.as_bytes();
|
pub static COLOR_NULL: LazyLock<String> =
|
||||||
pub const COLOR_OFFSET: &[u8] = colors::BrightBlack::ANSI_FG.as_bytes();
|
LazyLock::new(|| init_color("NULL", AnsiColors::BrightBlack));
|
||||||
pub const COLOR_ASCII_PRINTABLE: &[u8] = colors::Cyan::ANSI_FG.as_bytes();
|
pub static COLOR_OFFSET: LazyLock<String> =
|
||||||
pub const COLOR_ASCII_WHITESPACE: &[u8] = colors::Green::ANSI_FG.as_bytes();
|
LazyLock::new(|| init_color("OFFSET", AnsiColors::BrightBlack));
|
||||||
pub const COLOR_ASCII_OTHER: &[u8] = colors::Green::ANSI_FG.as_bytes();
|
pub static COLOR_ASCII_PRINTABLE: LazyLock<String> =
|
||||||
pub const COLOR_NONASCII: &[u8] = colors::Yellow::ANSI_FG.as_bytes();
|
LazyLock::new(|| init_color("ASCII_PRINTABLE", AnsiColors::Cyan));
|
||||||
pub const COLOR_RESET: &[u8] = colors::Default::ANSI_FG.as_bytes();
|
pub static COLOR_ASCII_WHITESPACE: LazyLock<String> =
|
||||||
|
LazyLock::new(|| init_color("ASCII_WHITESPACE", AnsiColors::Green));
|
||||||
|
pub static COLOR_ASCII_OTHER: LazyLock<String> =
|
||||||
|
LazyLock::new(|| init_color("ASCII_OTHER", AnsiColors::Green));
|
||||||
|
pub static COLOR_NONASCII: LazyLock<String> =
|
||||||
|
LazyLock::new(|| init_color("NONASCII", AnsiColors::Yellow));
|
||||||
|
pub const COLOR_RESET: &str = colors::Default::ANSI_FG;
|
||||||
|
|
||||||
|
fn init_color(name: &str, default_ansi: AnsiColors) -> String {
|
||||||
|
let default = DynColors::Ansi(default_ansi);
|
||||||
|
let env_var = format!("HEXYL_COLOR_{}", name);
|
||||||
|
let color = match std::env::var(env_var).as_deref() {
|
||||||
|
Ok(color) => match DynColors::from_str(color) {
|
||||||
|
Ok(color) => color,
|
||||||
|
_ => default,
|
||||||
|
},
|
||||||
|
_ => default,
|
||||||
|
};
|
||||||
|
// owo_colors' API isn't designed to get the terminal codes directly for
|
||||||
|
// dynamic colors, so we use this hack to get them from the LHS of some text.
|
||||||
|
format!("{}", "|".color(color))
|
||||||
|
.split_once("|")
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const CP437: [char; 256] = [
|
pub const CP437: [char; 256] = [
|
||||||
|
|||||||
+13
-13
@@ -84,11 +84,11 @@ impl Byte {
|
|||||||
fn color(self) -> &'static [u8] {
|
fn color(self) -> &'static [u8] {
|
||||||
use crate::ByteCategory::*;
|
use crate::ByteCategory::*;
|
||||||
match self.category() {
|
match self.category() {
|
||||||
Null => COLOR_NULL,
|
Null => COLOR_NULL.as_bytes(),
|
||||||
AsciiPrintable => COLOR_ASCII_PRINTABLE,
|
AsciiPrintable => COLOR_ASCII_PRINTABLE.as_bytes(),
|
||||||
AsciiWhitespace => COLOR_ASCII_WHITESPACE,
|
AsciiWhitespace => COLOR_ASCII_WHITESPACE.as_bytes(),
|
||||||
AsciiOther => COLOR_ASCII_OTHER,
|
AsciiOther => COLOR_ASCII_OTHER.as_bytes(),
|
||||||
NonAscii => COLOR_NONASCII,
|
NonAscii => COLOR_NONASCII.as_bytes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,14 +440,14 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)?;
|
)?;
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_OFFSET)?;
|
self.writer.write_all(COLOR_OFFSET.as_bytes())?;
|
||||||
}
|
}
|
||||||
if self.show_position_panel {
|
if self.show_position_panel {
|
||||||
match self.squeezer {
|
match self.squeezer {
|
||||||
Squeezer::Print => {
|
Squeezer::Print => {
|
||||||
self.writer.write_all(b"*")?;
|
self.writer.write_all(b"*")?;
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
}
|
}
|
||||||
self.writer.write_all(b" ")?;
|
self.writer.write_all(b" ")?;
|
||||||
}
|
}
|
||||||
@@ -462,7 +462,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
.write_all(self.byte_hex_panel_g[byte as usize].as_bytes())?;
|
.write_all(self.byte_hex_panel_g[byte as usize].as_bytes())?;
|
||||||
}
|
}
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
}
|
}
|
||||||
if i == 8 * self.panels - 1 {
|
if i == 8 * self.panels - 1 {
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
self.curr_color = None;
|
self.curr_color = None;
|
||||||
}
|
}
|
||||||
self.writer.write_all(
|
self.writer.write_all(
|
||||||
@@ -505,7 +505,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
)?;
|
)?;
|
||||||
} else if i % 8 == 7 {
|
} else if i % 8 == 7 {
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
self.curr_color = None;
|
self.curr_color = None;
|
||||||
}
|
}
|
||||||
self.writer.write_all(
|
self.writer.write_all(
|
||||||
@@ -531,12 +531,12 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
Squeezer::Print => {
|
Squeezer::Print => {
|
||||||
if !self.show_position_panel && i == 0 {
|
if !self.show_position_panel && i == 0 {
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_OFFSET)?;
|
self.writer.write_all(COLOR_OFFSET.as_bytes())?;
|
||||||
}
|
}
|
||||||
self.writer
|
self.writer
|
||||||
.write_all(self.byte_char_panel[b'*' as usize].as_bytes())?;
|
.write_all(self.byte_char_panel[b'*' as usize].as_bytes())?;
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
}
|
}
|
||||||
} else if i % (self.group_size as usize) == 0 {
|
} else if i % (self.group_size as usize) == 0 {
|
||||||
self.writer.write_all(b" ")?;
|
self.writer.write_all(b" ")?;
|
||||||
@@ -562,7 +562,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
|||||||
if i % 8 == 7 {
|
if i % 8 == 7 {
|
||||||
if self.show_color {
|
if self.show_color {
|
||||||
self.curr_color = None;
|
self.curr_color = None;
|
||||||
self.writer.write_all(COLOR_RESET)?;
|
self.writer.write_all(COLOR_RESET.as_bytes())?;
|
||||||
}
|
}
|
||||||
self.writer.write_all(b" ")?;
|
self.writer.write_all(b" ")?;
|
||||||
// byte is last in last panel
|
// byte is last in last panel
|
||||||
|
|||||||
+10
-10
@@ -493,32 +493,32 @@ fn print_color_table() -> io::Result<()> {
|
|||||||
writeln!(stdout, "hexyl color reference:\n")?;
|
writeln!(stdout, "hexyl color reference:\n")?;
|
||||||
|
|
||||||
// NULL bytes
|
// NULL bytes
|
||||||
stdout.write_all(COLOR_NULL)?;
|
stdout.write_all(COLOR_NULL.as_bytes())?;
|
||||||
writeln!(stdout, "⋄ NULL bytes (0x00)")?;
|
writeln!(stdout, "⋄ NULL bytes (0x00)")?;
|
||||||
stdout.write_all(COLOR_RESET)?;
|
stdout.write_all(COLOR_RESET.as_bytes())?;
|
||||||
|
|
||||||
// ASCII printable
|
// ASCII printable
|
||||||
stdout.write_all(COLOR_ASCII_PRINTABLE)?;
|
stdout.write_all(COLOR_ASCII_PRINTABLE.as_bytes())?;
|
||||||
writeln!(stdout, "a ASCII printable characters (0x20 - 0x7E)")?;
|
writeln!(stdout, "a ASCII printable characters (0x20 - 0x7E)")?;
|
||||||
stdout.write_all(COLOR_RESET)?;
|
stdout.write_all(COLOR_RESET.as_bytes())?;
|
||||||
|
|
||||||
// ASCII whitespace
|
// ASCII whitespace
|
||||||
stdout.write_all(COLOR_ASCII_WHITESPACE)?;
|
stdout.write_all(COLOR_ASCII_WHITESPACE.as_bytes())?;
|
||||||
writeln!(stdout, "_ ASCII whitespace (0x09 - 0x0D, 0x20)")?;
|
writeln!(stdout, "_ ASCII whitespace (0x09 - 0x0D, 0x20)")?;
|
||||||
stdout.write_all(COLOR_RESET)?;
|
stdout.write_all(COLOR_RESET.as_bytes())?;
|
||||||
|
|
||||||
// ASCII other
|
// ASCII other
|
||||||
stdout.write_all(COLOR_ASCII_OTHER)?;
|
stdout.write_all(COLOR_ASCII_OTHER.as_bytes())?;
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout,
|
stdout,
|
||||||
"• ASCII control characters (except NULL and whitespace)"
|
"• ASCII control characters (except NULL and whitespace)"
|
||||||
)?;
|
)?;
|
||||||
stdout.write_all(COLOR_RESET)?;
|
stdout.write_all(COLOR_RESET.as_bytes())?;
|
||||||
|
|
||||||
// Non-ASCII
|
// Non-ASCII
|
||||||
stdout.write_all(COLOR_NONASCII)?;
|
stdout.write_all(COLOR_NONASCII.as_bytes())?;
|
||||||
writeln!(stdout, "× Non-ASCII bytes (0x80 - 0xFF)")?;
|
writeln!(stdout, "× Non-ASCII bytes (0x80 - 0xFF)")?;
|
||||||
stdout.write_all(COLOR_RESET)?;
|
stdout.write_all(COLOR_RESET.as_bytes())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -785,3 +785,180 @@ mod character_table {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod colors {
|
||||||
|
use super::hexyl;
|
||||||
|
use owo_colors::{colors, Color};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
// This is a helper for testing color in output. Writing tests to expect
|
||||||
|
// raw color codes is ugly and hard to look at. Loading expected output
|
||||||
|
// from files works fine, but you end up with a lot of files for all the
|
||||||
|
// tests, and you have to cross-reference the file with the test that uses
|
||||||
|
// it. The files also suffer from the same problem of being hard to
|
||||||
|
// visually inspect. Just catting the file to see the colorized output
|
||||||
|
// loses the nuance of where exactly the color codes appear (before or
|
||||||
|
// after spaces, for example), or whether there are redundant codes.
|
||||||
|
//
|
||||||
|
// So this ColorMap solves the problem neatly by having two inputs:
|
||||||
|
// - the easy to read expected output in plain format without any colors
|
||||||
|
// - a mapping with identical structure except some characters replaced
|
||||||
|
// with single character color codes.
|
||||||
|
// This makes it easy to reference the output and expected colors side by
|
||||||
|
// side, and provides fairly precise control over exactly where color codes
|
||||||
|
// are expected (the only caveat being you can't have two color codes back
|
||||||
|
// to back). ColorMap combines these into the actual expected output.
|
||||||
|
//
|
||||||
|
// The color mapping needs to be identical to the expected output, except
|
||||||
|
// it has some chars replaced by color code stand ins. These are replaced
|
||||||
|
// with the actual color codes by the colorize method. The '.' character
|
||||||
|
// is also ignored (it doesn't need to match the input). This makes the
|
||||||
|
// color map more readable and avoids input characters from conflicting
|
||||||
|
// with color chars.
|
||||||
|
struct ColorMap {
|
||||||
|
text_map: &'static str,
|
||||||
|
char_to_color: HashMap<char, &'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorMap {
|
||||||
|
fn from(text_map: &'static str) -> Self {
|
||||||
|
ColorMap {
|
||||||
|
text_map,
|
||||||
|
char_to_color: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with<C: Color>(&mut self, c: char) -> &mut Self {
|
||||||
|
self.char_to_color.insert(c, C::ANSI_FG);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn colorize(&self, input: &str) -> String {
|
||||||
|
let mut output = String::new();
|
||||||
|
let mut input_chars = input.chars();
|
||||||
|
for c in self.text_map.chars() {
|
||||||
|
let next_input = input_chars.next().expect("input and color map don't match");
|
||||||
|
if let Some(color) = self.char_to_color.get(&c) {
|
||||||
|
output.push_str(color);
|
||||||
|
} else if c != '.' {
|
||||||
|
// ignore '.' in the mapping for readability
|
||||||
|
assert_eq!(c, next_input, "input and color map don't match");
|
||||||
|
}
|
||||||
|
output.push(next_input);
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hex_colors() {
|
||||||
|
let input = b"He\x11\0 \xff\0\xdd";
|
||||||
|
let expected_text = "\
|
||||||
|
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\
|
||||||
|
│00000000│ 48 65 11 00 20 ff 00 dd ┊ │He•⋄ ×⋄×┊ │\n\
|
||||||
|
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n";
|
||||||
|
let expected = ColorMap::from(
|
||||||
|
"\
|
||||||
|
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\
|
||||||
|
│r.......d y. .. b. c. g. m. c. m.d┊ d│y.bcgmcmd d\n\
|
||||||
|
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n",
|
||||||
|
)
|
||||||
|
.with::<colors::Red>('r')
|
||||||
|
.with::<colors::Default>('d')
|
||||||
|
.with::<colors::Yellow>('y')
|
||||||
|
.with::<colors::Blue>('b')
|
||||||
|
.with::<colors::Green>('g')
|
||||||
|
.with::<colors::BrightMagenta>('m')
|
||||||
|
.with::<colors::CustomColor<0xab, 0xcd, 0xef>>('c')
|
||||||
|
.colorize(expected_text);
|
||||||
|
|
||||||
|
hexyl()
|
||||||
|
.write_stdin(input)
|
||||||
|
.arg("--color=always")
|
||||||
|
.env("HEXYL_COLOR_OFFSET", "red")
|
||||||
|
.env("HEXYL_COLOR_ASCII_PRINTABLE", "yellow")
|
||||||
|
.env("HEXYL_COLOR_ASCII_WHITESPACE", "green")
|
||||||
|
.env("HEXYL_COLOR_ASCII_OTHER", "blue")
|
||||||
|
.env("HEXYL_COLOR_NONASCII", "bright magenta")
|
||||||
|
.env("HEXYL_COLOR_NULL", "#abcdef")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binary_colors() {
|
||||||
|
let input = b"He\x11\0 \xff\0\xdd";
|
||||||
|
let expected_text = "\
|
||||||
|
┌────────┬─────────────────────────────────────────────────────────────────────────┬────────┐\n\
|
||||||
|
│00000000│ 01001000 01100101 00010001 00000000 00100000 11111111 00000000 11011101 │He•⋄ ×⋄×│\n\
|
||||||
|
└────────┴─────────────────────────────────────────────────────────────────────────┴────────┘\n";
|
||||||
|
let expected = ColorMap::from(
|
||||||
|
"\
|
||||||
|
┌────────┬─────────────────────────────────────────────────────────────────────────┬────────┐\n\
|
||||||
|
│r.......d y....... ........ b....... c....... g....... m....... c....... m.......d│y.bcgmcmd\n\
|
||||||
|
└────────┴─────────────────────────────────────────────────────────────────────────┴────────┘\n"
|
||||||
|
)
|
||||||
|
.with::<colors::Red>('r')
|
||||||
|
.with::<colors::Default>('d')
|
||||||
|
.with::<colors::Yellow>('y')
|
||||||
|
.with::<colors::Blue>('b')
|
||||||
|
.with::<colors::Green>('g')
|
||||||
|
.with::<colors::BrightMagenta>('m')
|
||||||
|
.with::<colors::CustomColor<0xab, 0xcd, 0xef>>('c')
|
||||||
|
.colorize(expected_text);
|
||||||
|
|
||||||
|
hexyl()
|
||||||
|
.write_stdin(input)
|
||||||
|
.arg("--color=always")
|
||||||
|
.arg("--panels=1")
|
||||||
|
.arg("--base=binary")
|
||||||
|
.env("HEXYL_COLOR_OFFSET", "red")
|
||||||
|
.env("HEXYL_COLOR_ASCII_PRINTABLE", "yellow")
|
||||||
|
.env("HEXYL_COLOR_ASCII_WHITESPACE", "green")
|
||||||
|
.env("HEXYL_COLOR_ASCII_OTHER", "blue")
|
||||||
|
.env("HEXYL_COLOR_NONASCII", "bright magenta")
|
||||||
|
.env("HEXYL_COLOR_NULL", "#abcdef")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn groupsize_colors() {
|
||||||
|
let input = b"He\x11\0 \xff\0\xdd";
|
||||||
|
let expected_text = "\
|
||||||
|
┌────────┬─────────────────────┬────────┐\n\
|
||||||
|
│00000000│ 4865 1100 20ff 00dd │He•⋄ ×⋄×│\n\
|
||||||
|
└────────┴─────────────────────┴────────┘\n";
|
||||||
|
let expected = ColorMap::from(
|
||||||
|
"\
|
||||||
|
┌────────┬─────────────────────┬────────┐\n\
|
||||||
|
│r.......d y... b.c. g.m. c.m.d│y.bcgmcmd\n\
|
||||||
|
└────────┴─────────────────────┴────────┘\n",
|
||||||
|
)
|
||||||
|
.with::<colors::Red>('r')
|
||||||
|
.with::<colors::Default>('d')
|
||||||
|
.with::<colors::Yellow>('y')
|
||||||
|
.with::<colors::Blue>('b')
|
||||||
|
.with::<colors::Green>('g')
|
||||||
|
.with::<colors::BrightMagenta>('m')
|
||||||
|
.with::<colors::CustomColor<0xab, 0xcd, 0xef>>('c')
|
||||||
|
.colorize(expected_text);
|
||||||
|
|
||||||
|
hexyl()
|
||||||
|
.write_stdin(input)
|
||||||
|
.arg("--color=always")
|
||||||
|
.arg("--panels=1")
|
||||||
|
.arg("--groupsize=2")
|
||||||
|
.env("HEXYL_COLOR_OFFSET", "red")
|
||||||
|
.env("HEXYL_COLOR_ASCII_PRINTABLE", "yellow")
|
||||||
|
.env("HEXYL_COLOR_ASCII_WHITESPACE", "green")
|
||||||
|
.env("HEXYL_COLOR_ASCII_OTHER", "blue")
|
||||||
|
.env("HEXYL_COLOR_NONASCII", "bright magenta")
|
||||||
|
.env("HEXYL_COLOR_NULL", "#abcdef")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user