Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new --style called header-filesize and display it by default #1988

Merged
merged 15 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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| {
mdibaiee marked this conversation as resolved.
Show resolved Hide resolved
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 \
mdibaiee marked this conversation as resolved.
Show resolved Hide resolved
* 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(),
Enselic marked this conversation as resolved.
Show resolved Hide resolved
..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!(
Enselic marked this conversation as resolved.
Show resolved Hide resolved
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
mdibaiee marked this conversation as resolved.
Show resolved Hide resolved
// 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!(
Enselic marked this conversation as resolved.
Show resolved Hide resolved
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,
mdibaiee marked this conversation as resolved.
Show resolved Hide resolved
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,
Enselic marked this conversation as resolved.
Show resolved Hide resolved
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