conflicts: allow stripped trailing whitespace in diffs

Some editors strip trailing whitespace on save, which breaks any diffs
which have context lines, since the parsing function expects them to
start with a space. There's no visual difference between " \n" and "\n",
so it seems reasonable to accept both.
This commit is contained in:
Scott Taylor 2024-11-20 18:04:32 -06:00 committed by Scott Taylor
parent efacbcbd45
commit 6e959fa12c
2 changed files with 28 additions and 3 deletions

View file

@ -467,6 +467,12 @@ fn parse_conflict_hunk(input: &[u8]) -> Merge<BString> {
} else if let Some(rest) = line.strip_prefix(b" ") {
removes.last_mut().unwrap().extend_from_slice(rest);
adds.last_mut().unwrap().extend_from_slice(rest);
} else if line == b"\n" || line == b"\r\n" {
// Some editors strip trailing whitespace, so " \n" might become "\n". It would
// be unfortunate if this prevented the conflict from being parsed, so we add
// the empty line to the "remove" and "add" as if there was a space in front
removes.last_mut().unwrap().extend_from_slice(line);
adds.last_mut().unwrap().extend_from_slice(line);
} else {
// Doesn't look like a valid conflict
return Merge::resolved(BString::new(vec![]));

View file

@ -768,8 +768,9 @@ fn test_parse_conflict_crlf_markers() {
#[test]
fn test_parse_conflict_diff_stripped_whitespace() {
// Conflict parsing fails since diff contains empty line without leading space
assert_eq!(
// Should be able to parse conflict even if diff contains empty line (without
// even a leading space, which is sometimes stripped by text editors)
insta::assert_debug_snapshot!(
parse_conflict(
indoc! {b"
line 1
@ -788,7 +789,25 @@ fn test_parse_conflict_diff_stripped_whitespace() {
"},
2
),
None
@r#"
Some(
[
Resolved(
"line 1\n",
),
Conflicted(
[
"line 2\n\nleft\n\r\nline 4\n",
"line 2\n\nline 3\n\r\nline 4\n",
"right\n",
],
),
Resolved(
"line 5\n",
),
],
)
"#
);
}