Skip to content

Commit 7121b4d

Browse files
committed
resolve merge conflict
2 parents e9cb16b + f16e2c9 commit 7121b4d

File tree

12 files changed

+604
-214
lines changed

12 files changed

+604
-214
lines changed

.github/workflows/CICD.yml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636

3737
ensure_cargo_fmt:
3838
name: Ensure 'cargo fmt' has been run
39-
runs-on: ubuntu-20.04
39+
runs-on: ubuntu-24.04
4040
steps:
4141
- uses: dtolnay/rust-toolchain@stable
4242
with:
@@ -46,7 +46,7 @@ jobs:
4646

4747
min_version:
4848
name: Minimum supported rust version
49-
runs-on: ubuntu-20.04
49+
runs-on: ubuntu-24.04
5050
needs: crate_metadata
5151
steps:
5252
- name: Checkout source code
@@ -70,18 +70,19 @@ jobs:
7070
fail-fast: false
7171
matrix:
7272
job:
73-
- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
74-
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true }
75-
- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true }
76-
- { target: i686-pc-windows-msvc , os: windows-2019 }
77-
- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
78-
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
73+
- { target: aarch64-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
74+
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-24.04, use-cross: true }
75+
- { target: arm-unknown-linux-musleabihf, os: ubuntu-24.04, use-cross: true }
76+
- { target: i686-pc-windows-msvc , os: windows-2025 }
77+
- { target: i686-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
78+
- { target: i686-unknown-linux-musl , os: ubuntu-24.04, use-cross: true }
7979
- { target: x86_64-apple-darwin , os: macos-13 }
8080
- { target: aarch64-apple-darwin , os: macos-15 }
81-
- { target: x86_64-pc-windows-gnu , os: windows-2019 }
82-
- { target: x86_64-pc-windows-msvc , os: windows-2019 }
83-
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
84-
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
81+
# Was causing CI failures unrelated to app logic
82+
# - { target: x86_64-pc-windows-gnu , os: windows-2019 }
83+
- { target: x86_64-pc-windows-msvc , os: windows-2025 }
84+
- { target: x86_64-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
85+
- { target: x86_64-unknown-linux-musl , os: ubuntu-24.04, use-cross: true }
8586
env:
8687
BUILD_CMD: cargo
8788
steps:
@@ -155,7 +156,7 @@ jobs:
155156
run: |
156157
# test only library unit tests and binary for arm-type targets
157158
unset CARGO_TEST_OPTIONS
158-
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
159+
case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
159160
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
160161
161162
- name: Run tests

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
## Features
44

55
- Add option to output result in C include file style, see #242 (@wpcwzy)
6+
- Add `--color-scheme` option, see #247 (@aticu)
7+
- Add `braille` character table, see #247 (@aticu)
8+
- Add command line argument to generate shell completion, see #155 (@friedz)
69

710
## Bugfixes
811

12+
- Fix memory allocation bug when terminal width is less than 10, see #244 (@selfup)
13+
914

1015
# v0.16.0
1116

Cargo.lock

Lines changed: 10 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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ readme = "README.md"
99
repository = "https://github.com/sharkdp/hexyl"
1010
version = "0.16.0"
1111
edition = "2021"
12-
rust-version = "1.74"
12+
rust-version = "1.88"
1313

1414
[dependencies]
1515
anyhow = "1.0"
@@ -19,6 +19,7 @@ owo-colors = "4"
1919
supports-color = "3"
2020
thiserror = "1.0"
2121
terminal_size = "0.4"
22+
clap_complete = "4"
2223

2324
[dependencies.clap]
2425
version = "4"

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,22 @@ scoop install hexyl
193193
x env use hexyl
194194
```
195195

196+
## Configuration
197+
198+
`hexyl` colors can be configured via environment variables. The variables used are as follows:
199+
200+
* `HEXYL_COLOR_ASCII_PRINTABLE`: Any non-whitespace printable ASCII character
201+
* `HEXYL_COLOR_ASCII_WHITESPACE`: Whitespace such as space or newline (only visible in middle panel with byte values)
202+
* `HEXYL_COLOR_ASCII_OTHER`: Any other ASCII character (< `0x80`) besides null
203+
* `HEXYL_COLOR_NULL`: The null byte (`0x00`)
204+
* `HEXYL_COLOR_NONASCII`: Any non-ASCII byte (> `0x7F`)
205+
* `HEXYL_COLOR_OFFSET`: The lefthand file offset
206+
207+
The colors can be any of the 8 standard terminal colors: `black`, `blue`, `cyan`, `green`, `magenta`, `red`,
208+
`yellow` and `white`. The "bright" variants are also supported (e.g., `bright blue`). Additionally, you can use
209+
the RGB hex format, `#abcdef`. For example, `HEXYL_COLOR_ASCII_PRINTABLE=blue HEXYL_COLOR_ASCII_WHITESPACE="bright green"
210+
HEXYL_COLOR_ASCII_OTHER="#ff7f99"`.
211+
196212
## License
197213

198214
Licensed under either of

doc/hexyl.1.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@ _FILE_
106106
**-V**, **\--version**
107107
: Prints version information.
108108

109+
# ENVIRONMENT VARIABLES
110+
111+
**hexyl** colors can be configured via environment variables. The variables used are as follows:
112+
113+
: - **HEXYL_COLOR_ASCII_PRINTABLE**: Any non-whitespace printable ASCII character
114+
- **HEXYL_COLOR_ASCII_WHITESPACE**: Whitespace such as space or newline (only visible in middle panel with byte values)
115+
- **HEXYL_COLOR_ASCII_OTHER**: Any other ASCII character (< **0x80**) besides null
116+
- **HEXYL_COLOR_NULL**: The null byte (**0x00**)
117+
- **HEXYL_COLOR_NONASCII**: Any non-ASCII byte (> **0x7F**)
118+
- **HEXYL_COLOR_OFFSET**: The lefthand file offset
119+
120+
The colors can be any of the 8 standard terminal colors: **black**, **blue**, **cyan**, **green**, **magenta**, **red**,
121+
**yellow** and **white**. The "bright" variants are also supported (e.g., **bright blue**). Additionally, you can use
122+
the RGB hex format, **#abcdef**. For example, **HEXYL_COLOR_ASCII_PRINTABLE=blue HEXYL_COLOR_ASCII_WHITESPACE="bright green"
123+
HEXYL_COLOR_ASCII_OTHER="#ff7f99"**.
124+
109125
# NOTES
110126

111127
Source repository:

examples/simple.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::io;
33
use hexyl::{BorderStyle, PrinterBuilder};
44

55
fn main() {
6-
let input = vec![
6+
let input = [
77
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44,
88
0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x44, 0x08, 0x02, 0x00, 0x00, 0x00,
99
];

src/colors.rs

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,114 @@
1-
use owo_colors::{colors, Color};
2-
3-
pub const COLOR_NULL: &[u8] = colors::BrightBlack::ANSI_FG.as_bytes();
4-
pub const COLOR_OFFSET: &[u8] = colors::BrightBlack::ANSI_FG.as_bytes();
5-
pub const COLOR_ASCII_PRINTABLE: &[u8] = colors::Cyan::ANSI_FG.as_bytes();
6-
pub const COLOR_ASCII_WHITESPACE: &[u8] = colors::Green::ANSI_FG.as_bytes();
7-
pub const COLOR_ASCII_OTHER: &[u8] = colors::Green::ANSI_FG.as_bytes();
8-
pub const COLOR_NONASCII: &[u8] = colors::Yellow::ANSI_FG.as_bytes();
9-
pub const COLOR_RESET: &[u8] = colors::Default::ANSI_FG.as_bytes();
1+
use owo_colors::{colors, AnsiColors, Color, DynColors, OwoColorize};
2+
use std::str::FromStr;
3+
use std::sync::LazyLock;
4+
5+
pub static COLOR_NULL: LazyLock<String> =
6+
LazyLock::new(|| init_color("NULL", AnsiColors::BrightBlack));
7+
pub static COLOR_OFFSET: LazyLock<String> =
8+
LazyLock::new(|| init_color("OFFSET", AnsiColors::BrightBlack));
9+
pub static COLOR_ASCII_PRINTABLE: LazyLock<String> =
10+
LazyLock::new(|| init_color("ASCII_PRINTABLE", AnsiColors::Cyan));
11+
pub static COLOR_ASCII_WHITESPACE: LazyLock<String> =
12+
LazyLock::new(|| init_color("ASCII_WHITESPACE", AnsiColors::Green));
13+
pub static COLOR_ASCII_OTHER: LazyLock<String> =
14+
LazyLock::new(|| init_color("ASCII_OTHER", AnsiColors::Green));
15+
pub static COLOR_NONASCII: LazyLock<String> =
16+
LazyLock::new(|| init_color("NONASCII", AnsiColors::Yellow));
17+
pub const COLOR_RESET: &str = colors::Default::ANSI_FG;
18+
19+
fn init_color(name: &str, default_ansi: AnsiColors) -> String {
20+
let default = DynColors::Ansi(default_ansi);
21+
let env_var = format!("HEXYL_COLOR_{name}");
22+
let color = match std::env::var(env_var).as_deref() {
23+
Ok(color) => match DynColors::from_str(color) {
24+
Ok(color) => color,
25+
_ => default,
26+
},
27+
_ => default,
28+
};
29+
// owo_colors' API isn't designed to get the terminal codes directly for
30+
// dynamic colors, so we use this hack to get them from the LHS of some text.
31+
format!("{}", "|".color(color))
32+
.split_once("|")
33+
.unwrap()
34+
.0
35+
.to_owned()
36+
}
37+
38+
pub const COLOR_NULL_RGB: &[u8] = &rgb_bytes(100, 100, 100);
39+
40+
pub const COLOR_DEL: &[u8] = &rgb_bytes(64, 128, 0);
41+
42+
pub const COLOR_GRADIENT_NONASCII: [[u8; 19]; 128] =
43+
generate_color_gradient(&[(255, 0, 0, 0.0), (255, 255, 0, 0.66), (255, 255, 255, 1.0)]);
44+
45+
pub const COLOR_GRADIENT_ASCII_NONPRINTABLE: [[u8; 19]; 31] =
46+
generate_color_gradient(&[(255, 0, 255, 0.0), (128, 0, 255, 1.0)]);
47+
48+
pub const COLOR_GRADIENT_ASCII_PRINTABLE: [[u8; 19]; 95] =
49+
generate_color_gradient(&[(0, 128, 255, 0.0), (0, 255, 128, 1.0)]);
50+
51+
const fn as_dec(byte: u8) -> [u8; 3] {
52+
[
53+
b'0' + (byte / 100),
54+
b'0' + ((byte % 100) / 10),
55+
b'0' + (byte % 10),
56+
]
57+
}
58+
59+
const fn rgb_bytes(r: u8, g: u8, b: u8) -> [u8; 19] {
60+
let mut buf = *b"\x1b[38;2;rrr;ggg;bbbm";
61+
62+
// r 7
63+
buf[7] = as_dec(r)[0];
64+
buf[8] = as_dec(r)[1];
65+
buf[9] = as_dec(r)[2];
66+
67+
// g 11
68+
buf[11] = as_dec(g)[0];
69+
buf[12] = as_dec(g)[1];
70+
buf[13] = as_dec(g)[2];
71+
72+
// b 15
73+
buf[15] = as_dec(b)[0];
74+
buf[16] = as_dec(b)[1];
75+
buf[17] = as_dec(b)[2];
76+
77+
buf
78+
}
79+
80+
const fn generate_color_gradient<const N: usize>(stops: &[(u8, u8, u8, f64)]) -> [[u8; 19]; N] {
81+
let mut out = [rgb_bytes(0, 0, 0); N];
82+
83+
assert!(stops.len() >= 2, "need at least two stops for the gradient");
84+
85+
let mut byte = 0;
86+
while byte < N {
87+
let relative_byte = byte as f64 / N as f64;
88+
89+
let mut i = 1;
90+
while i < stops.len() && stops[i].3 < relative_byte {
91+
i += 1;
92+
}
93+
if i >= stops.len() {
94+
i = stops.len() - 1;
95+
}
96+
let prev_stop = stops[i - 1];
97+
let stop = stops[i];
98+
let diff = stop.3 - prev_stop.3;
99+
let t = (relative_byte - prev_stop.3) / diff;
100+
101+
let r = (prev_stop.0 as f64 + (t * (stop.0 as f64 - prev_stop.0 as f64))) as u8;
102+
let g = (prev_stop.1 as f64 + (t * (stop.1 as f64 - prev_stop.1 as f64))) as u8;
103+
let b = (prev_stop.2 as f64 + (t * (stop.2 as f64 - prev_stop.2 as f64))) as u8;
104+
105+
out[byte] = rgb_bytes(r, g, b);
106+
107+
byte += 1;
108+
}
109+
110+
out
111+
}
10112

11113
#[rustfmt::skip]
12114
pub const CP437: [char; 256] = [

src/input.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl Seek for Input<'_> {
2121
where
2222
R: Read,
2323
{
24-
let cant_seek_abs_err = || Err(io::Error::new(io::ErrorKind::Other, err_desc));
24+
let cant_seek_abs_err = || Err(io::Error::other(err_desc));
2525

2626
let offset = match pos {
2727
SeekFrom::Current(o) => u64::try_from(o).or_else(|_e| cant_seek_abs_err())?,

0 commit comments

Comments
 (0)