3030import java .util .TreeMap ;
3131import java .util .TreeSet ;
3232import java .util .function .BiFunction ;
33+ import java .util .function .BiPredicate ;
3334import java .util .function .Function ;
3435import java .util .function .ToIntFunction ;
3536import java .util .stream .Collectors ;
@@ -971,6 +972,8 @@ public static List<DiffUnit> combineToDiffBlocks(final List<DiffEdit> diff) {
971972 return combineToDiffBlocks (diff , false );
972973 }
973974
975+ private static final BiPredicate <DiffEdit , DiffEdit > ALWAYS_SHOULD_COMBINE = (x , y ) -> true ;
976+
974977 /**
975978 * Combines consecutive DiffEdit to form DiffBlock when possible
976979 *
@@ -980,12 +983,32 @@ public static List<DiffUnit> combineToDiffBlocks(final List<DiffEdit> diff) {
980983 * @return
981984 */
982985 public static List <DiffUnit > combineToDiffBlocks (final List <DiffEdit > diff , final boolean allowReplacements ) {
986+ return combineToDiffBlocks (diff , allowReplacements , ALWAYS_SHOULD_COMBINE );
987+ }
988+
989+ /**
990+ * Combines consecutive DiffEdit to form DiffBlock when possible and <code>shouldCombinePredicate</code> returns true
991+ *
992+ * <p>The returned list will consist of DiffUnit objects (either DiffBlock or DiffEdit)</p>
993+ *
994+ * @param diff
995+ * @param allowReplacements
996+ * @param shouldCombinePredicate indicates whether the two DiffEdits should be combined, if this method determines they can be combined (return <code>false</code> to prevent the combining)
997+ * @return
998+ * @since 0.13
999+ */
1000+ public static List <DiffUnit > combineToDiffBlocks (final List <DiffEdit > diff , final boolean allowReplacements ,
1001+ final BiPredicate <DiffEdit , DiffEdit > shouldCombinePredicate ) {
9831002 List <DiffUnit > diffBlocks = new ArrayList <>();
9841003
1004+ BiPredicate <DiffEdit , DiffEdit > usedShouldCombinePredicate = shouldCombinePredicate != null
1005+ ? shouldCombinePredicate
1006+ : ALWAYS_SHOULD_COMBINE ;
1007+
9851008 for (int i = 0 ; i < diff .size (); i ++) {
9861009 DiffEdit diffEdit = diff .get (i );
9871010
988- if (isNextDiffPartOfBlock (diff , i , allowReplacements )) {
1011+ if (isNextDiffPartOfBlock (diff , i , allowReplacements , usedShouldCombinePredicate )) {
9891012 DiffType blockDiffType = diffEdit .getType ();
9901013
9911014 List <DiffEdit > edits = new ArrayList <>();
@@ -997,7 +1020,7 @@ public static List<DiffUnit> combineToDiffBlocks(final List<DiffEdit> diff, fina
9971020 if (blockDiffType != REPLACEMENT_BLOCK && !blockDiffType .equals (nextDiffEdit .getType ())) {
9981021 blockDiffType = REPLACEMENT_BLOCK ;
9991022 }
1000- } while (isNextDiffPartOfBlock (diff , i , allowReplacements ));
1023+ } while (isNextDiffPartOfBlock (diff , i , allowReplacements , usedShouldCombinePredicate ));
10011024
10021025 diffBlocks .add (new DiffBlock (blockDiffType , edits ));
10031026 } else {
@@ -1017,7 +1040,7 @@ public static List<DiffUnit> combineToDiffBlocks(final List<DiffEdit> diff, fina
10171040 * @return
10181041 */
10191042 private static boolean isNextDiffPartOfBlock (final List <DiffEdit > diff , final int i ,
1020- final boolean allowReplacements ) {
1043+ final boolean allowReplacements , final BiPredicate < DiffEdit , DiffEdit > shouldCombinePredicate ) {
10211044
10221045 if (i + 1 >= diff .size ()) {
10231046 return false ;
@@ -1040,7 +1063,8 @@ private static boolean isNextDiffPartOfBlock(final List<DiffEdit> diff, final in
10401063 }
10411064 }
10421065
1043- return hasConsecutiveLines (diffEdit , nextDiffEdit , isReplancement );
1066+ return hasConsecutiveLines (diffEdit , nextDiffEdit , isReplancement )
1067+ && shouldCombinePredicate .test (diffEdit , nextDiffEdit );
10441068 }
10451069
10461070 private static boolean canBePartOfReplacement (final DiffEdit diffEdit ) {
0 commit comments