Skip to content

Commit

Permalink
Merge pull request #2665 from einfachIrgendwer0815/feature_squeeze
Browse files Browse the repository at this point in the history
Add `-s`/`--squeeze` and `--squeeze-limit` (based on #1441).
  • Loading branch information
sharkdp authored Feb 24, 2024
2 parents e1a3fc5 + bc5beae commit 6f69682
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
## Features

- Set terminal title to file names when Paging is not Paging::Never #2807 (@Oliver-Looney)
- `bat --squeeze-blank`/`bat -s` will now squeeze consecutive empty lines, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)
- `bat --squeeze-limit` to set the maximum number of empty consecutive when using `--squeeze-blank`, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)
- `PrettyPrinter::squeeze_empty_lines` to support line squeezing for bat as a library, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)

## Bugfixes

Expand Down
6 changes: 6 additions & 0 deletions doc/long-help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ Options:
--list-themes
Display a list of supported themes for syntax highlighting.

-s, --squeeze-blank
Squeeze consecutive empty lines into a single empty line.

--squeeze-limit <squeeze-limit>
Set the maximum number of consecutive empty lines to be printed.

--style <components>
Configure which elements (line numbers, file headers, grid borders, Git modifications, ..)
to display in addition to the file contents. The argument is a comma-separated list of
Expand Down
2 changes: 2 additions & 0 deletions doc/short-help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Options:
Set the color theme for syntax highlighting.
--list-themes
Display all supported highlighting themes.
-s, --squeeze-blank
Squeeze consecutive empty lines.
--style <components>
Comma-separated list of style elements to display (*default*, auto, full, plain, changes,
header, header-filename, header-filesize, grid, rule, numbers, snip).
Expand Down
10 changes: 10 additions & 0 deletions src/bin/bat/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ impl App {
#[cfg(feature = "lessopen")]
use_lessopen: self.matches.get_flag("lessopen"),
set_terminal_title: self.matches.get_flag("set-terminal-title"),
squeeze_lines: if self.matches.get_flag("squeeze-blank") {
Some(
self.matches
.get_one::<usize>("squeeze-limit")
.map(|limit| limit.to_owned())
.unwrap_or(1),
)
} else {
None
},
})
}

Expand Down
15 changes: 15 additions & 0 deletions src/bin/bat/clap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,21 @@ pub fn build_app(interactive_output: bool) -> Command {
.help("Display all supported highlighting themes.")
.long_help("Display a list of supported themes for syntax highlighting."),
)
.arg(
Arg::new("squeeze-blank")
.long("squeeze-blank")
.short('s')
.action(ArgAction::SetTrue)
.help("Squeeze consecutive empty lines.")
.long_help("Squeeze consecutive empty lines into a single empty line.")
)
.arg(
Arg::new("squeeze-limit")
.long("squeeze-limit")
.value_parser(|s: &str| s.parse::<usize>().map_err(|_| "Requires a non-negative number".to_owned()))
.long_help("Set the maximum number of consecutive empty lines to be printed.")
.hide_short_help(true)
)
.arg(
Arg::new("style")
.long("style")
Expand Down
3 changes: 3 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ pub struct Config<'a> {

// Weather or not to set terminal title when using a pager
pub set_terminal_title: bool,

/// The maximum number of consecutive empty lines to display
pub squeeze_lines: Option<usize>,
}

#[cfg(all(feature = "minimal-application", feature = "paging"))]
Expand Down
6 changes: 6 additions & 0 deletions src/pretty_printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ impl<'a> PrettyPrinter<'a> {
self
}

/// Specify the maximum number of consecutive empty lines to print.
pub fn squeeze_empty_lines(&mut self, maximum: Option<usize>) -> &mut Self {
self.config.squeeze_lines = maximum;
self
}

/// Specify the highlighting theme
pub fn theme(&mut self, theme: impl AsRef<str>) -> &mut Self {
self.config.theme = theme.as_ref().to_owned();
Expand Down
35 changes: 34 additions & 1 deletion src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,15 @@ pub(crate) trait Printer {

pub struct SimplePrinter<'a> {
config: &'a Config<'a>,
consecutive_empty_lines: usize,
}

impl<'a> SimplePrinter<'a> {
pub fn new(config: &'a Config) -> Self {
SimplePrinter { config }
SimplePrinter {
config,
consecutive_empty_lines: 0,
}
}
}

Expand Down Expand Up @@ -134,6 +138,21 @@ impl<'a> Printer for SimplePrinter<'a> {
_line_number: usize,
line_buffer: &[u8],
) -> Result<()> {
// Skip squeezed lines.
if let Some(squeeze_limit) = self.config.squeeze_lines {
if String::from_utf8_lossy(line_buffer)
.trim_end_matches(|c| c == '\r' || c == '\n')
.is_empty()
{
self.consecutive_empty_lines += 1;
if self.consecutive_empty_lines > squeeze_limit {
return Ok(());
}
} else {
self.consecutive_empty_lines = 0;
}
}

if !out_of_range {
if self.config.show_nonprintable {
let line = replace_nonprintable(
Expand Down Expand Up @@ -187,6 +206,7 @@ pub(crate) struct InteractivePrinter<'a> {
pub line_changes: &'a Option<LineChanges>,
highlighter_from_set: Option<HighlighterFromSet<'a>>,
background_color_highlight: Option<Color>,
consecutive_empty_lines: usize,
}

impl<'a> InteractivePrinter<'a> {
Expand Down Expand Up @@ -272,6 +292,7 @@ impl<'a> InteractivePrinter<'a> {
line_changes,
highlighter_from_set,
background_color_highlight,
consecutive_empty_lines: 0,
})
}

Expand Down Expand Up @@ -577,6 +598,18 @@ impl<'a> Printer for InteractivePrinter<'a> {
return Ok(());
}

// Skip squeezed lines.
if let Some(squeeze_limit) = self.config.squeeze_lines {
if line.trim_end_matches(|c| c == '\r' || c == '\n').is_empty() {
self.consecutive_empty_lines += 1;
if self.consecutive_empty_lines > squeeze_limit {
return Ok(());
}
} else {
self.consecutive_empty_lines = 0;
}
}

let mut cursor: usize = 0;
let mut cursor_max: usize = self.config.term_width;
let mut cursor_total: usize = 0;
Expand Down
30 changes: 30 additions & 0 deletions tests/examples/empty_lines.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
line 1



line 5














line 20
line 21


line 24

line 26



line 30
64 changes: 64 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,70 @@ fn line_range_multiple() {
.stdout("line 1\nline 2\nline 4\n");
}

#[test]
fn squeeze_blank() {
bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.assert()
.success()
.stdout("line 1\n\nline 5\n\nline 20\nline 21\n\nline 24\n\nline 26\n\nline 30\n");
}

#[test]
fn squeeze_blank_line_numbers() {
bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.arg("--decorations=always")
.arg("--number")
.assert()
.success()
.stdout(" 1 line 1\n 2 \n 5 line 5\n 6 \n 20 line 20\n 21 line 21\n 22 \n 24 line 24\n 25 \n 26 line 26\n 27 \n 30 line 30\n");
}

#[test]
fn squeeze_limit() {
bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.arg("--squeeze-limit=2")
.assert()
.success()
.stdout("line 1\n\n\nline 5\n\n\nline 20\nline 21\n\n\nline 24\n\nline 26\n\n\nline 30\n");

bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.arg("--squeeze-limit=5")
.assert()
.success()
.stdout("line 1\n\n\n\nline 5\n\n\n\n\n\nline 20\nline 21\n\n\nline 24\n\nline 26\n\n\n\nline 30\n");
}

#[test]
fn squeeze_limit_line_numbers() {
bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.arg("--squeeze-limit=2")
.arg("--decorations=always")
.arg("--number")
.assert()
.success()
.stdout(" 1 line 1\n 2 \n 3 \n 5 line 5\n 6 \n 7 \n 20 line 20\n 21 line 21\n 22 \n 23 \n 24 line 24\n 25 \n 26 line 26\n 27 \n 28 \n 30 line 30\n");

bat()
.arg("empty_lines.txt")
.arg("--squeeze-blank")
.arg("--squeeze-limit=5")
.arg("--decorations=always")
.arg("--number")
.assert()
.success()
.stdout(" 1 line 1\n 2 \n 3 \n 4 \n 5 line 5\n 6 \n 7 \n 8 \n 9 \n 10 \n 20 line 20\n 21 line 21\n 22 \n 23 \n 24 line 24\n 25 \n 26 line 26\n 27 \n 28 \n 29 \n 30 line 30\n");
}

#[test]
#[cfg_attr(any(not(feature = "git"), target_os = "windows"), ignore)]
fn short_help() {
Expand Down

0 comments on commit 6f69682

Please sign in to comment.