diff: ignore replacements with moving of punctuation into another line

We do not detect such cases in ByWord diff - so we can't fully rely on inner fragments
Squash such blocks into a single one
This commit is contained in:
Aleksey Pivovarov
2015-02-03 20:14:07 +03:00
parent 47b478d961
commit e47e0a695a
2 changed files with 19 additions and 6 deletions
@@ -255,8 +255,10 @@ public class ComparisonUtil {
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if (fragment.getFineFragments() != null && !fragment.getFineFragments().isEmpty()) break;
if (!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) break;
if ((fragment.getFineFragments() == null || !fragment.getFineFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
start++;
}
while (start < end) {
@@ -264,8 +266,10 @@ public class ComparisonUtil {
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if (fragment.getFineFragments() != null && !fragment.getFineFragments().isEmpty()) break;
if (!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) break;
if ((fragment.getFineFragments() == null || !fragment.getFineFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
end--;
}
}
@@ -116,8 +116,7 @@ class LineFragmentSplitter {
private boolean shouldMergeBlocks(@NotNull WordBlock lastBlock, @NotNull WordBlock newBlock) {
if (!lastHasEqualWords && !hasEqualWords) return true; // combine lines, that matched only by '\n'
if (isEqualsIgnoreWhitespace(newBlock) && isEqualsIgnoreWhitespace(lastBlock)) return true; // combine whitespace-only changed lines
// TODO: squash if new/old block contain no words, and non-space characters could be attached to the end of the second one
// TODO: or squash all blocks without words in it ?
if (noWordsInside(lastBlock) || noWordsInside(newBlock)) return true; // squash block without words in it
return false;
}
@@ -151,6 +150,16 @@ class LineFragmentSplitter {
return words1.get(index - 1) instanceof NewlineChunk;
}
private boolean noWordsInside(@NotNull WordBlock block) {
for (int i = block.words.start1; i < block.words.end1; i++) {
if (!(myWords1.get(i) instanceof NewlineChunk)) return false;
}
for (int i = block.words.start2; i < block.words.end2; i++) {
if (!(myWords2.get(i) instanceof NewlineChunk)) return false;
}
return true;
}
//
// Helpers
//