From 4175c1cf7f887f0e8e486b228bde7a6b502fc60a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 6 Feb 2014 11:21:43 +0530 Subject: [PATCH] Compare books: Fix non-optimal display of changes in some situations Extra changes were being displayed because the patience diff algorithm can return large replace blocks with identical leading lines. Instead of showing them as diffs, show them as extra context. --- src/calibre/gui2/tweak_book/diff/view.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/calibre/gui2/tweak_book/diff/view.py b/src/calibre/gui2/tweak_book/diff/view.py index 6ac2ade4d8..81db5f6a80 100644 --- a/src/calibre/gui2/tweak_book/diff/view.py +++ b/src/calibre/gui2/tweak_book/diff/view.py @@ -750,11 +750,29 @@ class DiffSplit(QSplitter): # {{{ self.changes.append(Change( rtop=start_block, rbot=current_block, ltop=l, lbot=l, kind='insert')) + def trim_identical_leading_lines(self, alo, ahi, blo, bhi): + ''' The patience diff algorithm sometimes results in a block of replace + lines with identical leading lines. Remove these. This can cause extra + lines of context, but that is better than having extra lines of diff + with no actual changes. ''' + a, b = self.left_lines, self.right_lines + leading = 0 + while alo < ahi and blo < bhi and a[alo] == b[blo]: + leading += 1 + alo += 1 + blo += 1 + if leading > 0: + self.equal(alo - leading, alo, blo - leading, blo) + return alo, ahi, blo, bhi + def replace(self, alo, ahi, blo, bhi): ''' When replacing one block of lines with another, search the blocks for *similar* lines; the best-matching pair (if any) is used as a synch point, and intraline difference marking is done on the similar pair. Lots of work, but often worth it. ''' + alo, ahi, blo, bhi = self.trim_identical_leading_lines(alo, ahi, blo, bhi) + if alo == ahi and blo == bhi: + return if ahi + bhi - alo - blo > 100: # Too many lines, this will be too slow # http://bugs.python.org/issue6931