Skip to content

Commit b9348ff

Browse files
sharifhsnsharkdp
authored andcommitted
Adds --columns for Print using custom width #13
1 parent 55cf7b0 commit b9348ff

File tree

4 files changed

+114
-93
lines changed

4 files changed

+114
-93
lines changed

examples/simple.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn main() {
1616
let show_position_panel = true;
1717
let use_squeezing = false;
1818
let border_style = BorderStyle::Unicode;
19+
let columns = 2;
1920

2021
let mut printer = Printer::new(
2122
&mut handle,
@@ -24,6 +25,7 @@ fn main() {
2425
show_position_panel,
2526
border_style,
2627
use_squeezing,
28+
columns,
2729
);
2830
printer.print_all(&input[..]).unwrap();
2931
}

src/bin/hexyl.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ extern crate clap;
44
use std::convert::TryFrom;
55
use std::fs::File;
66
use std::io::{self, prelude::*, SeekFrom};
7-
use std::num::NonZeroI64;
7+
use std::num::{NonZeroI64, NonZeroU8};
88

99
use clap::{crate_name, crate_version, AppSettings, Arg, ColorChoice, Command};
1010

@@ -149,6 +149,17 @@ fn run() -> Result<(), AnyhowError> {
149149
A negative value is valid and calculates an offset relative to the \
150150
end of the file.",
151151
),
152+
)
153+
.arg(
154+
Arg::new("columns")
155+
.short('w')
156+
.long("columns")
157+
.takes_value(true)
158+
.value_name("N")
159+
.help(
160+
"Sets the number of hex data columns to be displayed. \
161+
Cannot be used with other width-setting options.",
162+
),
152163
);
153164

154165
let matches = command.get_matches();
@@ -267,6 +278,17 @@ fn run() -> Result<(), AnyhowError> {
267278
.transpose()?
268279
.unwrap_or(0);
269280

281+
let columns = matches
282+
.value_of("columns")
283+
.map(|s| {
284+
s.parse::<NonZeroU8>().map(u8::from).context(anyhow!(
285+
"failed to parse `--columns` arg {:?} as unsigned nonzero integer",
286+
s
287+
))
288+
})
289+
.transpose()?
290+
.unwrap_or(2);
291+
270292
let stdout = io::stdout();
271293
let mut stdout_lock = stdout.lock();
272294

@@ -277,6 +299,7 @@ fn run() -> Result<(), AnyhowError> {
277299
show_position_panel,
278300
border_style,
279301
squeeze,
302+
columns,
280303
);
281304
printer.display_offset(skip_offset + display_offset);
282305
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;

src/lib.rs

+71-75
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ pub struct Printer<'a, Writer: Write> {
154154
byte_char_panel: Vec<String>,
155155
squeezer: Squeezer,
156156
display_offset: u64,
157+
/// The number of panels to draw.
158+
columns: u8,
157159
}
158160

159161
impl<'a, Writer: Write> Printer<'a, Writer> {
@@ -164,6 +166,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
164166
show_position_panel: bool,
165167
border_style: BorderStyle,
166168
use_squeeze: bool,
169+
columns: u8,
167170
) -> Printer<'a, Writer> {
168171
Printer {
169172
idx: 1,
@@ -175,7 +178,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
175178
show_position_panel,
176179
border_style,
177180
header_was_printed: false,
178-
byte_hex_panel: (0u8..=u8::max_value())
181+
byte_hex_panel: (0u8..=u8::MAX)
179182
.map(|i| {
180183
let byte_hex = format!("{:02x} ", i);
181184
if show_color {
@@ -187,7 +190,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
187190
.collect(),
188191
byte_char_panel: show_char_panel
189192
.then(|| {
190-
(0u8..=u8::max_value())
193+
(0u8..=u8::MAX)
191194
.map(|i| {
192195
let byte_char = format!("{}", Byte(i).as_char());
193196
if show_color {
@@ -199,8 +202,9 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
199202
.collect()
200203
})
201204
.unwrap_or_default(),
202-
squeezer: Squeezer::new(use_squeeze),
205+
squeezer: Squeezer::new(use_squeeze, 8 * columns as u64),
203206
display_offset: 0,
207+
columns,
204208
}
205209
}
206210

@@ -223,10 +227,20 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
223227
write!(self.writer, "{}", l).ok();
224228
}
225229

226-
write!(self.writer, "{h25}{c}{h25}", c = c, h25 = h25).ok();
230+
for _ in 0..self.columns - 1 {
231+
write!(self.writer, "{h25}{c}", h25 = h25, c = c).ok();
232+
}
233+
if self.show_char_panel {
234+
write!(self.writer, "{h25}{c}", h25 = h25, c = c).ok();
235+
} else {
236+
write!(self.writer, "{h25}", h25 = h25).ok();
237+
}
227238

228239
if self.show_char_panel {
229-
writeln!(self.writer, "{c}{h8}{c}{h8}{r}", c = c, h8 = h8, r = r).ok();
240+
for _ in 0..self.columns - 1 {
241+
write!(self.writer, "{h8}{c}", h8 = h8, c = c).ok();
242+
}
243+
writeln!(self.writer, "{h8}{r}", h8 = h8, r = r).ok();
230244
} else {
231245
writeln!(self.writer, "{r}", r = r).ok();
232246
}
@@ -287,36 +301,25 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
287301
self.byte_char_panel[b as usize]
288302
);
289303

290-
if idx == 8 {
304+
if idx % 8 == 0 && idx % (u64::from(self.columns * 8)) != 0 {
291305
let _ = write!(&mut self.buffer_line, "{}", self.border_style.inner_sep());
292306
}
293307

294308
idx += 1;
295309
}
296310

297-
if len < 8 {
298-
let _ = writeln!(
299-
&mut self.buffer_line,
300-
"{0:1$}{3}{0:2$}{4}",
301-
"",
302-
8 - len,
303-
8,
304-
self.border_style.inner_sep(),
305-
self.border_style.outer_sep(),
306-
);
307-
} else {
308-
let _ = writeln!(
309-
&mut self.buffer_line,
310-
"{0:1$}{2}",
311-
"",
312-
16 - len,
313-
self.border_style.outer_sep()
314-
);
311+
if len < usize::from(8 * self.columns) {
312+
let _ = write!(&mut self.buffer_line, "{0:1$}", "", 8 - len % 8);
313+
for _ in 0..(usize::from(8 * self.columns) - (len + (8 - len % 8))) / 8 {
314+
let _ = write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.inner_sep());
315+
}
315316
}
317+
let _ = writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep());
318+
316319
}
317320

318321
pub fn print_byte(&mut self, b: u8) -> io::Result<()> {
319-
if self.idx % 16 == 1 {
322+
if self.idx % u64::from(self.columns * 8) == 1 {
320323
self.print_header();
321324
self.print_position_panel();
322325
}
@@ -326,14 +329,10 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
326329

327330
self.squeezer.process(b, self.idx);
328331

329-
match self.idx % 16 {
330-
8 => {
331-
let _ = write!(&mut self.buffer_line, "{} ", self.border_style.inner_sep());
332-
}
333-
0 => {
334-
self.print_textline()?;
335-
}
336-
_ => {}
332+
if self.idx % u64::from(self.columns * 8) == 0 {
333+
self.print_textline()?;
334+
} else if self.idx % 8 == 0 {
335+
let _ = write!(&mut self.buffer_line, "{} ", self.border_style.inner_sep());
337336
}
338337

339338
self.idx += 1;
@@ -347,45 +346,33 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
347346
if len == 0 {
348347
if self.squeezer.active() {
349348
self.print_position_panel();
350-
let _ = writeln!(
351-
&mut self.buffer_line,
352-
"{0:1$}{4}{0:2$}{5}{0:3$}{4}{0:3$}{5}",
353-
"",
354-
24,
355-
25,
356-
8,
357-
self.border_style.inner_sep(),
358-
self.border_style.outer_sep(),
359-
);
349+
write!(&mut self.buffer_line, "{0:1$}", "", 24)?;
350+
for _ in 0..self.columns - 1 {
351+
write!(&mut self.buffer_line, "{2}{0:1$}", "", 25, self.border_style.inner_sep())?;
352+
}
353+
write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.outer_sep())?;
354+
for _ in 0..self.columns - 1 {
355+
write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.inner_sep())?;
356+
}
357+
writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
360358
self.writer.write_all(&self.buffer_line)?;
361359
}
362360
return Ok(());
363361
}
364362

365363
let squeeze_action = self.squeezer.action();
366364

365+
// print empty space on last line
367366
if squeeze_action != SqueezeAction::Delete {
368-
if len < 8 {
369-
let _ = write!(
370-
&mut self.buffer_line,
371-
"{0:1$}{3}{0:2$}{4}",
372-
"",
373-
3 * (8 - len),
374-
1 + 3 * 8,
375-
self.border_style.inner_sep(),
376-
self.border_style.outer_sep(),
377-
);
378-
} else {
379-
let _ = write!(
380-
&mut self.buffer_line,
381-
"{0:1$}{2}",
382-
"",
383-
3 * (16 - len),
384-
self.border_style.outer_sep()
385-
);
367+
if len < usize::from(8 * self.columns) {
368+
write!(&mut self.buffer_line, "{0:1$}", "", 3 * (8 - len % 8))?;
369+
// dbg!(usize::from(8 * self.columns) - (len + (8 - len % 8)));
370+
for _ in 0..(usize::from(8 * self.columns) - (len + (8 - len % 8))) / 8 {
371+
write!(&mut self.buffer_line, "{2}{0:1$}", "", 1 + 3 * 8, self.border_style.inner_sep())?;
372+
}
386373
}
374+
write!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
387375
}
388-
389376
self.print_char_panel();
390377

391378
match squeeze_action {
@@ -397,17 +384,26 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
397384
} else {
398385
String::from("*")
399386
};
400-
let _ = writeln!(
401-
&mut self.buffer_line,
402-
"{5}{0}{1:2$}{5}{1:3$}{6}{1:3$}{5}{1:4$}{6}{1:4$}{5}",
403-
asterisk,
404-
"",
405-
7,
406-
25,
407-
8,
408-
self.border_style.outer_sep(),
409-
self.border_style.inner_sep(),
410-
);
387+
388+
write!(&mut self.buffer_line, "{3}{0}{1:2$}{3}", asterisk, "", 7, self.border_style.outer_sep())?;
389+
390+
for i in 0..self.columns {
391+
write!(&mut self.buffer_line, "{0:1$}", "", 25)?;
392+
if i != self.columns - 1 {
393+
write!(&mut self.buffer_line, "{}", self.border_style.inner_sep())?;
394+
} else {
395+
write!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
396+
}
397+
}
398+
399+
for i in 0..self.columns {
400+
write!(&mut self.buffer_line, "{0:1$}", "", 8)?;
401+
if i != self.columns - 1 {
402+
write!(&mut self.buffer_line, "{}", self.border_style.inner_sep())?;
403+
} else {
404+
writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
405+
}
406+
}
411407
}
412408
SqueezeAction::Delete => self.buffer_line.clear(),
413409
SqueezeAction::Ignore => (),
@@ -484,7 +480,7 @@ mod tests {
484480

485481
fn assert_print_all_output<Reader: Read>(input: Reader, expected_string: String) {
486482
let mut output = vec![];
487-
let mut printer = Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true);
483+
let mut printer = Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true, 2);
488484

489485
printer.print_all(input).unwrap();
490486

@@ -529,7 +525,7 @@ mod tests {
529525

530526
let mut output = vec![];
531527
let mut printer: Printer<Vec<u8>> =
532-
Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true);
528+
Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true, 2);
533529
printer.display_offset(0xdeadbeef);
534530

535531
printer.print_all(input).unwrap();

0 commit comments

Comments
 (0)