Skip to content

Commit

Permalink
Add new --style called header-filesize and display it by default (#…
Browse files Browse the repository at this point in the history
…1988)

Also rename `header` to `header-filename`.

Related to #1701
  • Loading branch information
mdibaiee authored Feb 7, 2022
1 parent f3f8194 commit 312c8ef
Show file tree
Hide file tree
Showing 111 changed files with 302 additions and 42 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Features

- New style component `header-filesize` to show size of the displayed file in the header. See #1988 (@mdibaiee)

## Bugfixes

## Other
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ dirs-next = { version = "2.0.0", optional = true }
grep-cli = { version = "0.1.6", optional = true }
regex = { version = "1.0", optional = true }
walkdir = { version = "2.0", optional = true }
bytesize = { version = "1.1.0" }

[dependencies.git2]
version = "0.13"
Expand Down
20 changes: 15 additions & 5 deletions src/bin/bat/clap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,19 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.validator(|val| {
let mut invalid_vals = val.split(',').filter(|style| {
!&[
"auto", "full", "plain", "header", "grid", "rule", "numbers", "snip",
"auto",
"full",
"plain",
"header",
"header-filename",
"header-filesize",
"grid",
"rule",
"numbers",
"snip",
#[cfg(feature = "git")]
"changes",
]
.contains(style)
"changes",
].contains(style)
});

if let Some(invalid) = invalid_vals.next() {
Expand All @@ -426,7 +434,9 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
* auto: same as 'full', unless the output is piped.\n \
* plain: disables all available components.\n \
* changes: show Git modification markers.\n \
* header: show filenames before the content.\n \
* header: alias for 'header-filename'.\n \
* header-filename: show filenames before the content.\n \
* header-filesize: show file sizes before the content.\n \
* grid: vertical/horizontal lines to separate side bar\n \
and the header from the content.\n \
* rule: horizontal lines to delimit files.\n \
Expand Down
9 changes: 8 additions & 1 deletion src/input.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::convert::TryFrom;
use std::fs;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Read};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -87,6 +88,7 @@ impl<'a> InputKind<'a> {
#[derive(Clone, Default)]
pub(crate) struct InputMetadata {
pub(crate) user_provided_name: Option<PathBuf>,
pub(crate) size: Option<u64>,
}

pub struct Input<'a> {
Expand Down Expand Up @@ -130,9 +132,14 @@ impl<'a> Input<'a> {

fn _ordinary_file(path: &Path) -> Self {
let kind = InputKind::OrdinaryFile(path.to_path_buf());
let metadata = InputMetadata {
size: fs::metadata(path).map(|m| m.len()).ok(),
..InputMetadata::default()
};

Input {
description: kind.description(),
metadata: InputMetadata::default(),
metadata,
kind,
}
}
Expand Down
104 changes: 73 additions & 31 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::vec::Vec;
use ansi_term::Colour::{Fixed, Green, Red, Yellow};
use ansi_term::Style;

use bytesize::ByteSize;

use console::AnsiCodeIterator;

use syntect::easy::HighlightLines;
Expand All @@ -29,6 +31,7 @@ use crate::error::*;
use crate::input::OpenedInput;
use crate::line_range::RangeCheckResult;
use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::style::StyleComponent;
use crate::terminal::{as_terminal_escaped, to_ansi_color};
use crate::vscreen::AnsiStyle;
use crate::wrapping::WrappingMode;
Expand Down Expand Up @@ -250,6 +253,21 @@ impl<'a> InteractivePrinter<'a> {
}
}

fn print_header_component_indent(&mut self, handle: &mut dyn Write) -> std::io::Result<()> {
if self.config.style_components.grid() {
write!(
handle,
"{}{}",
" ".repeat(self.panel_width),
self.colors
.grid
.paint(if self.panel_width > 0 { "│ " } else { "" }),
)
} else {
write!(handle, "{}", " ".repeat(self.panel_width))
}
}

fn preprocess(&self, text: &str, cursor: &mut usize) -> String {
if self.config.tab_width > 0 {
return expand_tabs(text, self.config.tab_width, cursor);
Expand Down Expand Up @@ -287,25 +305,6 @@ impl<'a> Printer for InteractivePrinter<'a> {
return Ok(());
}

if self.config.style_components.grid() {
self.print_horizontal_line(handle, '┬')?;

write!(
handle,
"{}{}",
" ".repeat(self.panel_width),
self.colors
.grid
.paint(if self.panel_width > 0 { "│ " } else { "" }),
)?;
} else {
// Only pad space between files, if we haven't already drawn a horizontal rule
if add_header_padding && !self.config.style_components.rule() {
writeln!(handle)?;
}
write!(handle, "{}", " ".repeat(self.panel_width))?;
}

let mode = match self.content_type {
Some(ContentType::BINARY) => " <BINARY>",
Some(ContentType::UTF_16LE) => " <UTF-16LE>",
Expand All @@ -315,17 +314,60 @@ impl<'a> Printer for InteractivePrinter<'a> {
};

let description = &input.description;
let metadata = &input.metadata;

// We use this iterator to have a deterministic order for
// header components. HashSet has arbitrary order, but Vec is ordered.
let header_components: Vec<StyleComponent> = [
(
StyleComponent::HeaderFilename,
self.config.style_components.header_filename(),
),
(
StyleComponent::HeaderFilesize,
self.config.style_components.header_filesize(),
),
]
.iter()
.filter(|(_, is_enabled)| *is_enabled)
.map(|(component, _)| *component)
.collect();

// Print the cornering grid before the first header component
if self.config.style_components.grid() {
self.print_horizontal_line(handle, '┬')?;
} else {
// Only pad space between files, if we haven't already drawn a horizontal rule
if add_header_padding && !self.config.style_components.rule() {
writeln!(handle)?;
}
}

writeln!(
handle,
"{}{}{}",
description
.kind()
.map(|kind| format!("{}: ", kind))
.unwrap_or_else(|| "".into()),
self.colors.filename.paint(description.title()),
mode
)?;
header_components.iter().try_for_each(|component| {
self.print_header_component_indent(handle)?;

match component {
StyleComponent::HeaderFilename => writeln!(
handle,
"{}{}{}",
description
.kind()
.map(|kind| format!("{}: ", kind))
.unwrap_or_else(|| "".into()),
self.colors.header_value.paint(description.title()),
mode
),

StyleComponent::HeaderFilesize => {
let bsize = metadata
.size
.map(|s| format!("{}", ByteSize(s)))
.unwrap_or_else(|| "-".into());
writeln!(handle, "Size: {}", self.colors.header_value.paint(bsize))
}
_ => Ok(()),
}
})?;

if self.config.style_components.grid() {
if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
Expand Down Expand Up @@ -617,7 +659,7 @@ const DEFAULT_GUTTER_COLOR: u8 = 238;
pub struct Colors {
pub grid: Style,
pub rule: Style,
pub filename: Style,
pub header_value: Style,
pub git_added: Style,
pub git_removed: Style,
pub git_modified: Style,
Expand Down Expand Up @@ -646,7 +688,7 @@ impl Colors {
Colors {
grid: gutter_style,
rule: gutter_style,
filename: Style::new().bold(),
header_value: Style::new().bold(),
git_added: Green.normal(),
git_removed: Red.normal(),
git_modified: Yellow.normal(),
Expand Down
22 changes: 19 additions & 3 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::str::FromStr;

use crate::error::*;

#[non_exhaustive]
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub enum StyleComponent {
Auto,
Expand All @@ -11,6 +12,8 @@ pub enum StyleComponent {
Grid,
Rule,
Header,
HeaderFilename,
HeaderFilesize,
LineNumbers,
Snip,
Full,
Expand All @@ -31,14 +34,17 @@ impl StyleComponent {
StyleComponent::Changes => &[StyleComponent::Changes],
StyleComponent::Grid => &[StyleComponent::Grid],
StyleComponent::Rule => &[StyleComponent::Rule],
StyleComponent::Header => &[StyleComponent::Header],
StyleComponent::Header => &[StyleComponent::HeaderFilename],
StyleComponent::HeaderFilename => &[StyleComponent::HeaderFilename],
StyleComponent::HeaderFilesize => &[StyleComponent::HeaderFilesize],
StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
StyleComponent::Snip => &[StyleComponent::Snip],
StyleComponent::Full => &[
#[cfg(feature = "git")]
StyleComponent::Changes,
StyleComponent::Grid,
StyleComponent::Header,
StyleComponent::HeaderFilename,
StyleComponent::HeaderFilesize,
StyleComponent::LineNumbers,
StyleComponent::Snip,
],
Expand All @@ -58,6 +64,8 @@ impl FromStr for StyleComponent {
"grid" => Ok(StyleComponent::Grid),
"rule" => Ok(StyleComponent::Rule),
"header" => Ok(StyleComponent::Header),
"header-filename" => Ok(StyleComponent::HeaderFilename),
"header-filesize" => Ok(StyleComponent::HeaderFilesize),
"numbers" => Ok(StyleComponent::LineNumbers),
"snip" => Ok(StyleComponent::Snip),
"full" => Ok(StyleComponent::Full),
Expand Down Expand Up @@ -89,7 +97,15 @@ impl StyleComponents {
}

pub fn header(&self) -> bool {
self.0.contains(&StyleComponent::Header)
self.header_filename() || self.header_filesize()
}

pub fn header_filename(&self) -> bool {
self.0.contains(&StyleComponent::HeaderFilename)
}

pub fn header_filesize(&self) -> bool {
self.0.contains(&StyleComponent::HeaderFilesize)
}

pub fn numbers(&self) -> bool {
Expand Down
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 0
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 1
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 10
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-100.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 100
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-11.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 11
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-12.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 12
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-13.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 13
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-14.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 14
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-15.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 15
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-16.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 16
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-17.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 17
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-18.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 18
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-19.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 19
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 2
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-20.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 20
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-21.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 21
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-22.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 22
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-23.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 23
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-24.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 24
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-25.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 25
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-26.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 26
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-27.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 27
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-28.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 28
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-29.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 29
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 3
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-30.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 30
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-31.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 31
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-32.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 32
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-33.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 33
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-34.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 34
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-35.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 35
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-36.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 36
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-37.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 37
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-38.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 38
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-39.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 39
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 4
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-40.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 40
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-41.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 41
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-42.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 42
1 change: 1 addition & 0 deletions tests/benchmarks/many-small-files/small-file-43.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am small file 43
Loading

0 comments on commit 312c8ef

Please sign in to comment.