diff --git a/CHANGELOG.md b/CHANGELOG.md index c6e1ae81..9934329f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ## Features +- Add `--quiet-empty` (`-E`) flag to suppress output when input is empty. Closes #1936, see #3563 (@NORMAL-EX) - Improve native man pages and command help syntax highlighting by stripping overstriking, see #3517 (@akirk) ## Bugfixes diff --git a/assets/completions/_bat.ps1.in b/assets/completions/_bat.ps1.in index a9b3bcd5..db10302a 100644 --- a/assets/completions/_bat.ps1.in +++ b/assets/completions/_bat.ps1.in @@ -186,6 +186,7 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script [CompletionResult]::new('--acknowledgements' , 'acknowledgements' , [CompletionResultType]::ParameterName, 'Show acknowledgements.') [CompletionResult]::new('--set-terminal-title' , 'set-terminal-title' , [CompletionResultType]::ParameterName, 'Sets terminal title to filenames when using a pager.') [CompletionResult]::new('--diagnostic' , 'diagnostic' , [CompletionResultType]::ParameterName, 'Show diagnostic information for bug reports.') + [CompletionResult]::new('--quiet-empty' , 'quiet-empty' , [CompletionResultType]::ParameterName, 'Do not produce any output when the input is empty.') # [CompletionResult]::new('-h' , 'h' , [CompletionResultType]::ParameterName, 'Print this help message.') [CompletionResult]::new('--help' , 'help' , [CompletionResultType]::ParameterName, 'Print this help message.') # [CompletionResult]::new('-V' , 'V' , [CompletionResultType]::ParameterName, 'Show version information.') diff --git a/assets/completions/bat.bash.in b/assets/completions/bat.bash.in index 66be3985..7593df8f 100644 --- a/assets/completions/bat.bash.in +++ b/assets/completions/bat.bash.in @@ -100,6 +100,7 @@ _bat() { --lessopen | \ --no-paging | \ --diagnostic | \ + --quiet-empty | \ --acknowledgements | \ -h | --help | \ -V | --version | \ @@ -227,6 +228,7 @@ _bat() { --lessopen --completion --diagnostic + --quiet-empty --acknowledgements --set-terminal-title --help diff --git a/assets/completions/bat.fish.in b/assets/completions/bat.fish.in index 09f6407b..21c07adf 100644 --- a/assets/completions/bat.fish.in +++ b/assets/completions/bat.fish.in @@ -61,7 +61,7 @@ function __bat_no_excl_args -s V -l version \ -l acknowledgements \ -l config-dir -l config-file \ - -l diagnostic \ + -l diagnostic -l quiet-empty \ -l list-languages -l list-themes end @@ -159,6 +159,7 @@ complete -c $bat -l config-file -f -d "Display location of configuration file" - complete -c $bat -l decorations -x -a "$decorations_opts" -d "When to use --style decorations" -n __bat_no_excl_args complete -c $bat -l diagnostic -d "Print diagnostic info for bug reports" -n __fish_is_first_arg +complete -c $bat -l quiet-empty -d "Do not produce any output when the input is empty" -n __fish_is_first_arg complete -c $bat -s d -l diff -d "Only show lines with Git changes" -n __bat_no_excl_args diff --git a/assets/completions/bat.zsh.in b/assets/completions/bat.zsh.in index 910ec9d0..da9a66e6 100644 --- a/assets/completions/bat.zsh.in +++ b/assets/completions/bat.zsh.in @@ -62,6 +62,7 @@ _{{PROJECT_EXECUTABLE}}_main() { --completion='[show shell completion for a certain shell]:shell:(bash fish zsh ps1)' --set-terminal-title'[sets terminal title to filenames when using a pager]' --diagnostic'[show diagnostic information for bug reports]' + --quiet-empty'[do not produce any output when the input is empty]' -P'[disable paging]' "--no-config[don't use the configuration file]" "--no-custom-assets[don't load custom assets]" diff --git a/assets/manual/bat.1.in b/assets/manual/bat.1.in index 0be4bb63..ff4cb76f 100644 --- a/assets/manual/bat.1.in +++ b/assets/manual/bat.1.in @@ -282,6 +282,10 @@ Show bat's cache directory. .IP Show diagnostic information for bug reports. .HP +\fB\-\-quiet\-empty\fR +.IP +Do not produce any output when the input is empty (e.g. an empty file or empty stdin). This is useful in scripts where silent behavior is preferred for empty input. +.HP \fB\-\-acknowledgements\fR .IP Show acknowledgements. diff --git a/doc/long-help.txt b/doc/long-help.txt index 8cb60812..994a3810 100644 --- a/doc/long-help.txt +++ b/doc/long-help.txt @@ -212,6 +212,10 @@ Options: --diagnostic Show diagnostic information for bug reports. + -E, --quiet-empty + When this flag is set, bat will produce no output at all when the input is empty. This is + useful when piping commands that may produce empty output, like 'git diff'. + --acknowledgements Show acknowledgements. diff --git a/doc/short-help.txt b/doc/short-help.txt index d67a51d0..41a0fdee 100644 --- a/doc/short-help.txt +++ b/doc/short-help.txt @@ -60,6 +60,8 @@ Options: Display all supported languages. --completion Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1] + -E, --quiet-empty + Produce no output when the input is empty. -h, --help Print help (see more with '--help') -V, --version diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index 1ba3e73d..f5f59ec7 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -461,6 +461,7 @@ impl App { Some("auto") => StripAnsiMode::Auto, _ => unreachable!("other values for --strip-ansi are not allowed"), }, + quiet_empty: self.matches.get_flag("quiet-empty"), theme: theme(self.theme_options()).to_string(), visible_lines: match self.matches.try_contains_id("diff").unwrap_or_default() && self.matches.get_flag("diff") diff --git a/src/bin/bat/clap_app.rs b/src/bin/bat/clap_app.rs index acb505ee..10bf7a8b 100644 --- a/src/bin/bat/clap_app.rs +++ b/src/bin/bat/clap_app.rs @@ -643,6 +643,18 @@ pub fn build_app(interactive_output: bool) -> Command { .hide_short_help(true) .help("Show diagnostic information for bug reports."), ) + .arg( + Arg::new("quiet-empty") + .long("quiet-empty") + .short('E') + .action(ArgAction::SetTrue) + .help("Produce no output when the input is empty.") + .long_help( + "When this flag is set, bat will produce no output at all when \ + the input is empty. This is useful when piping commands that may \ + produce empty output, like 'git diff'.", + ), + ) .arg( Arg::new("acknowledgements") .long("acknowledgements") diff --git a/src/config.rs b/src/config.rs index aa223186..7209c2fd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -107,6 +107,9 @@ pub struct Config<'a> { // Whether or not to strip ANSI escape codes from the input pub strip_ansi: StripAnsiMode, + + /// Whether or not to produce no output when input is empty + pub quiet_empty: bool, } #[cfg(all(feature = "minimal-application", feature = "paging"))] diff --git a/src/printer.rs b/src/printer.rs index 1ddd5e66..3c3facf5 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -454,6 +454,11 @@ impl Printer for InteractivePrinter<'_> { input: &OpenedInput, add_header_padding: bool, ) -> Result<()> { + // If input is empty and quiet_empty is enabled, skip all output + if self.content_type.is_none() && self.config.quiet_empty { + return Ok(()); + } + if add_header_padding && self.config.style_components.rule() { self.print_horizontal_line_term(handle, self.colors.rule)?; } @@ -556,6 +561,11 @@ impl Printer for InteractivePrinter<'_> { } fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> { + // If input is empty and quiet_empty is enabled, skip footer + if self.content_type.is_none() && self.config.quiet_empty { + return Ok(()); + } + if self.config.style_components.grid() && (self.content_type.is_some_and(|c| c.is_text()) || self.config.show_nonprintable diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 250b3d2e..7b4e2df4 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -3654,3 +3654,33 @@ fn plain_with_sized_terminal_width() { .stdout("hello \nworld\n") .stderr(""); } + +#[test] +fn quiet_empty_suppresses_output_on_empty_stdin() { + bat() + .arg("--quiet-empty") + .write_stdin("") + .assert() + .success() + .stdout(""); +} + +#[test] +fn quiet_empty_does_not_affect_non_empty_input() { + bat() + .arg("--quiet-empty") + .write_stdin("hello\n") + .assert() + .success() + .stdout("hello\n"); +} + +#[test] +fn quiet_empty_suppresses_output_on_empty_file() { + bat() + .arg("--quiet-empty") + .arg("empty.txt") + .assert() + .success() + .stdout(""); +}