Skip to content

Commit 78e2fdd

Browse files
authored
patch: add support for configuring suppress_blank_empty (#38)
Add support for configuring `--suppress-blank-empty` as is possible with GNU diff and git-diff. This allows suppressing the trailing space that would otherwise exist when formatting a patch with an empty context line.
1 parent acff31e commit 78e2fdd

2 files changed

Lines changed: 96 additions & 2 deletions

File tree

src/diff/tests.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,81 @@ void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size
642642
assert_patch!(original, a, expected_diffy);
643643
}
644644

645+
#[test]
646+
fn suppress_blank_empty() {
647+
let original = "\
648+
1
649+
2
650+
3
651+
652+
4
653+
";
654+
655+
let modified = "\
656+
1
657+
2
658+
3
659+
660+
5
661+
";
662+
663+
// Note that there is a space " " on the line after 3
664+
let expected = "\
665+
--- original
666+
+++ modified
667+
@@ -2,4 +2,4 @@
668+
2
669+
3
670+
671+
-4
672+
+5
673+
";
674+
675+
let f = PatchFormatter::new().suppress_blank_empty(false);
676+
let patch = create_patch(original, modified);
677+
let bpatch = create_patch_bytes(original.as_bytes(), modified.as_bytes());
678+
let patch_str = format!("{}", f.fmt_patch(&patch));
679+
let mut patch_bytes = Vec::new();
680+
f.write_patch_into(&bpatch, &mut patch_bytes).unwrap();
681+
682+
assert_eq!(patch_str, expected);
683+
assert_eq!(patch_bytes, patch_str.as_bytes());
684+
assert_eq!(patch_bytes, expected.as_bytes());
685+
assert_eq!(apply(original, &patch).unwrap(), modified);
686+
assert_eq!(
687+
crate::apply_bytes(original.as_bytes(), &bpatch).unwrap(),
688+
modified.as_bytes()
689+
);
690+
691+
// Note that there is no space " " on the line after 3
692+
let expected_suppressed = "\
693+
--- original
694+
+++ modified
695+
@@ -2,4 +2,4 @@
696+
2
697+
3
698+
699+
-4
700+
+5
701+
";
702+
703+
let f = PatchFormatter::new().suppress_blank_empty(true);
704+
let patch = create_patch(original, modified);
705+
let bpatch = create_patch_bytes(original.as_bytes(), modified.as_bytes());
706+
let patch_str = format!("{}", f.fmt_patch(&patch));
707+
let mut patch_bytes = Vec::new();
708+
f.write_patch_into(&bpatch, &mut patch_bytes).unwrap();
709+
710+
assert_eq!(patch_str, expected_suppressed);
711+
assert_eq!(patch_bytes, patch_str.as_bytes());
712+
assert_eq!(patch_bytes, expected_suppressed.as_bytes());
713+
assert_eq!(apply(original, &patch).unwrap(), modified);
714+
assert_eq!(
715+
crate::apply_bytes(original.as_bytes(), &bpatch).unwrap(),
716+
modified.as_bytes()
717+
);
718+
}
719+
645720
// In the event that a patch has an invalid hunk range we want to ensure that when apply is
646721
// attempting to search for a matching position to apply a hunk that the search algorithm runs in
647722
// time bounded by the length of the original image being patched. Before clamping the search space

src/patch/format.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::{
1010
pub struct PatchFormatter {
1111
with_color: bool,
1212
with_missing_newline_message: bool,
13+
suppress_blank_empty: bool,
1314

1415
context: Style,
1516
delete: Style,
@@ -26,6 +27,10 @@ impl PatchFormatter {
2627
with_color: false,
2728
with_missing_newline_message: true,
2829

30+
// TODO the default in git-diff and GNU diff is to have this set to false, on the next
31+
// semver breaking release we should contemplate switching this to be false by default
32+
suppress_blank_empty: true,
33+
2934
context: Style::new(),
3035
delete: Color::Red.normal(),
3136
insert: Color::Green.normal(),
@@ -54,6 +59,20 @@ impl PatchFormatter {
5459
self
5560
}
5661

62+
/// Sets whether to suppress printing of a space before empty lines.
63+
///
64+
/// Defaults to `true`.
65+
///
66+
/// For more information you can refer to the [Omitting trailing blanks] manual page of GNU
67+
/// diff or the [diff.suppressBlankEmpty] config for `git-diff`.
68+
///
69+
/// [Omitting trailing blanks]: https://www.gnu.org/software/diffutils/manual/html_node/Trailing-Blanks.html
70+
/// [diff.suppressBlankEmpty]: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt-codediffsuppressBlankEmptycode
71+
pub fn suppress_blank_empty(mut self, enable: bool) -> Self {
72+
self.suppress_blank_empty = enable;
73+
self
74+
}
75+
5776
/// Returns a `Display` impl which can be used to print a Patch
5877
pub fn fmt_patch<'a>(&'a self, patch: &'a Patch<'a, str>) -> impl Display + 'a {
5978
PatchDisplay { f: self, patch }
@@ -240,7 +259,7 @@ impl<T: AsRef<[u8]> + ?Sized> LineDisplay<'_, T> {
240259
write!(w, "{}", style.prefix())?;
241260
}
242261

243-
if sign == ' ' && line == b"\n" {
262+
if self.f.suppress_blank_empty && sign == ' ' && line == b"\n" {
244263
w.write_all(line)?;
245264
} else {
246265
write!(w, "{}", sign)?;
@@ -274,7 +293,7 @@ impl Display for LineDisplay<'_, str> {
274293
write!(f, "{}", style.prefix())?;
275294
}
276295

277-
if sign == ' ' && *line == "\n" {
296+
if self.f.suppress_blank_empty && sign == ' ' && *line == "\n" {
278297
write!(f, "{}", line)?;
279298
} else {
280299
write!(f, "{}{}", sign, line)?;

0 commit comments

Comments
 (0)