From 7eedc0f854557e1ba28ce0cea35a4c80fe345fa2 Mon Sep 17 00:00:00 2001 From: Louis Maddox Date: Thu, 16 Oct 2025 13:27:11 +0100 Subject: [PATCH] feat(pipe-style): make output pipeable (any style) --- CHANGELOG.md | 1 + src/bin/bat/app.rs | 4 +- tests/integration_tests.rs | 77 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35df9a16..8a736c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - `--style=changes` no longer prints a two-space indent when the file is unmodified, see issue #2710 and PR #3406 (@jyn514) - Add missing shell completions, see #3411 (@keith-hall) - Execute help/version/diagnostic commands even with invalid config/arguments present, see #3414 (@keith-hall) +- Fixed line numbers (`-n`) and style components not printing when piping output, see issue #2935 and PR #3438 (@lmmx) ## Other diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index a8e1e0db..0304516e 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -276,7 +276,9 @@ impl App { .get_one::("decorations") .map(|s| s.as_str()) == Some("always") - || self.matches.get_flag("force-colorization")), + || self.matches.get_flag("force-colorization") + || self.matches.get_flag("number") + || self.matches.contains_id("style") && !style_components.plain()), tab_width: self .matches .get_one::("tabs") diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 1748a3d0..40f0ed3a 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -378,6 +378,83 @@ fn line_range_context_very_large() { ); } +#[test] +fn piped_output_with_implicit_auto_style() { + bat() + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout("hello\nworld\n"); +} + +#[test] +fn piped_output_with_line_number_flag() { + bat() + .arg("--number") + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout(" 1 hello\n 2 world\n"); +} + +#[test] +fn piped_output_with_line_numbers_style_flag() { + bat() + .arg("--style=numbers") + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout(" 1 hello\n 2 world\n"); +} + +#[test] +#[cfg(not(target_os = "windows"))] +fn piped_output_with_line_numbers_with_header_grid_style_flag() { + bat() + .arg("--style=header,grid,numbers") + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout( + "─────┬────────────────────────────────────────────────────────────────────────── + │ STDIN +─────┼────────────────────────────────────────────────────────────────────────── + 1 │ hello + 2 │ world +─────┴────────────────────────────────────────────────────────────────────────── +", + ); +} + +#[test] +fn piped_output_with_auto_style() { + bat() + .arg("--style=auto") + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout("hello\nworld\n"); // Should be plain when piped +} + +#[test] +#[cfg(not(target_os = "windows"))] +fn piped_output_with_default_style_flag() { + bat() + .arg("--style=default") + .write_stdin("hello\nworld\n") + .assert() + .success() + .stdout( + "─────┬────────────────────────────────────────────────────────────────────────── + │ STDIN +─────┼────────────────────────────────────────────────────────────────────────── + 1 │ hello + 2 │ world +─────┴────────────────────────────────────────────────────────────────────────── +", + ); +} + #[test] fn squeeze_blank() { bat()