Merge pull request #3643 from mvanhorn/feat/diff-plain-compatibility
feat: preserve change markers when combining --diff with --plain
This commit is contained in:
3 files changed
+160
-1
No files matched your search
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
- Preserve `--diff` change markers and snip separators when `--plain` is set. Closes #3630, see #3643 (@mvanhorn)
|
||||||
- Added support for `hidden_file_extensions` from `.sublime-syntax` files, see #3613 (@Matei02355)
|
- Added support for `hidden_file_extensions` from `.sublime-syntax` files, see #3613 (@Matei02355)
|
||||||
- Add word wrapping mode via `--wrap=word`, see #3597 (@veeceey)
|
- Add word wrapping mode via `--wrap=word`, see #3597 (@veeceey)
|
||||||
- Implement `--unbuffered` mode for streaming input, allowing partial lines to display immediately (e.g. `tail -f | bat -u`). Closes #3555, see #3583 (@mainnebula)
|
- Implement `--unbuffered` mode for streaming input, allowing partial lines to display immediately (e.g. `tail -f | bat -u`). Closes #3555, see #3583 (@mainnebula)
|
||||||
|
|||||||
+11
-1
@@ -590,7 +590,17 @@ impl App {
|
|||||||
|
|
||||||
// Plain if `--plain` is specified at least once.
|
// Plain if `--plain` is specified at least once.
|
||||||
if self.matches.get_count("plain") > 0 {
|
if self.matches.get_count("plain") > 0 {
|
||||||
return Some(StyleComponents(HashSet::from([StyleComponent::Plain])));
|
let mut components = HashSet::from([StyleComponent::Plain]);
|
||||||
|
// When --diff is active, preserve change markers and snip separators
|
||||||
|
// so that diff output remains visually useful.
|
||||||
|
if self.matches.try_contains_id("diff").unwrap_or_default()
|
||||||
|
&& self.matches.get_flag("diff")
|
||||||
|
{
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
components.insert(StyleComponent::Changes);
|
||||||
|
components.insert(StyleComponent::Snip);
|
||||||
|
}
|
||||||
|
return Some(StyleComponents(components));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior.
|
// Default behavior.
|
||||||
|
|||||||
@@ -3984,3 +3984,151 @@ fn word_wrap_short_line_no_wrap() {
|
|||||||
.success()
|
.success()
|
||||||
.stdout("Single Line\n");
|
.stdout("Single Line\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
fn setup_diff_test_repo() -> tempfile::TempDir {
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
let dir = tempfile::tempdir().expect("can create temporary directory");
|
||||||
|
let repo = dir.path();
|
||||||
|
|
||||||
|
// Initialize a git repo and commit a file
|
||||||
|
Command::new("git")
|
||||||
|
.args(["init"])
|
||||||
|
.current_dir(repo)
|
||||||
|
.output()
|
||||||
|
.expect("git init");
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(["config", "user.email", "test@test.com"])
|
||||||
|
.current_dir(repo)
|
||||||
|
.output()
|
||||||
|
.expect("git config email");
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(["config", "user.name", "Test"])
|
||||||
|
.current_dir(repo)
|
||||||
|
.output()
|
||||||
|
.expect("git config name");
|
||||||
|
|
||||||
|
std::fs::write(repo.join("test.txt"), "line 1\nline 2\nline 3\n").expect("can write test file");
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(["add", "test.txt"])
|
||||||
|
.current_dir(repo)
|
||||||
|
.output()
|
||||||
|
.expect("git add");
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(["commit", "-m", "initial"])
|
||||||
|
.current_dir(repo)
|
||||||
|
.output()
|
||||||
|
.expect("git commit");
|
||||||
|
|
||||||
|
// Modify the file so --diff has something to show
|
||||||
|
std::fs::write(
|
||||||
|
repo.join("test.txt"),
|
||||||
|
"line 1\nline 2 modified\nline 3\nline 4 added\n",
|
||||||
|
)
|
||||||
|
.expect("can write modified test file");
|
||||||
|
|
||||||
|
dir
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
#[test]
|
||||||
|
fn diff_plain_preserves_change_markers() {
|
||||||
|
let repo = setup_diff_test_repo();
|
||||||
|
|
||||||
|
// With --diff --plain, output should contain the change marker column
|
||||||
|
// but not other decorations like line numbers or grid
|
||||||
|
let output = bat()
|
||||||
|
.current_dir(repo.path())
|
||||||
|
.arg("--diff")
|
||||||
|
.arg("--plain")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--decorations=always")
|
||||||
|
.arg("test.txt")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.get_output()
|
||||||
|
.stdout
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let stdout = std::str::from_utf8(&output).expect("valid utf-8");
|
||||||
|
|
||||||
|
// The output should contain the modified and added lines
|
||||||
|
assert!(
|
||||||
|
stdout.contains("line 2 modified"),
|
||||||
|
"diff plain output should contain modified line, got: {stdout}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
stdout.contains("line 4 added"),
|
||||||
|
"diff plain output should contain added line, got: {stdout}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should NOT contain line numbers (a decoration that --plain disables)
|
||||||
|
assert!(
|
||||||
|
!stdout.contains(" 1"),
|
||||||
|
"diff plain output should not contain line numbers, got: {stdout}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
#[test]
|
||||||
|
fn diff_plain_does_not_show_grid_or_header() {
|
||||||
|
let repo = setup_diff_test_repo();
|
||||||
|
|
||||||
|
let output = bat()
|
||||||
|
.current_dir(repo.path())
|
||||||
|
.arg("--diff")
|
||||||
|
.arg("--plain")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--decorations=always")
|
||||||
|
.arg("--terminal-width=80")
|
||||||
|
.arg("test.txt")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.get_output()
|
||||||
|
.stdout
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let stdout = std::str::from_utf8(&output).expect("valid utf-8");
|
||||||
|
|
||||||
|
// Grid lines use box-drawing characters
|
||||||
|
assert!(
|
||||||
|
!stdout.contains('─'),
|
||||||
|
"diff plain output should not contain grid lines, got: {stdout}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!stdout.contains('│'),
|
||||||
|
"diff plain output should not contain grid separators, got: {stdout}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header shows "File: <filename>"
|
||||||
|
assert!(
|
||||||
|
!stdout.contains("File:"),
|
||||||
|
"diff plain output should not contain file header, got: {stdout}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
#[test]
|
||||||
|
fn plain_without_diff_still_works() {
|
||||||
|
let repo = setup_diff_test_repo();
|
||||||
|
|
||||||
|
// --plain without --diff should output file content with no decorations at all
|
||||||
|
bat()
|
||||||
|
.current_dir(repo.path())
|
||||||
|
.arg("--plain")
|
||||||
|
.arg("--color=never")
|
||||||
|
.arg("--decorations=always")
|
||||||
|
.arg("test.txt")
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout("line 1\nline 2 modified\nline 3\nline 4 added\n");
|
||||||
|
}
|
||||||
Reference in new issue
Block a user