comparison mercurial/mdiff.py @ 15528:a84698badf0b

annotate: support diff whitespace filtering flags (issue3030) splitblock() was added to handle blocks returned by bdiff.blocks() which differ only by blank lines but are not made only of blank lines. I do not know exactly how it could happen but mdiff.blocks() threshold behaviour makes me think it can if those blocks are made of very popular lines mixed with popular blank lines. If it is proven to be wrong, the function can be dropped. The first implementation made annotate share diff configuration entries. But it looks like users will user -w/b for annotate but not for diff, on both the command line and hgweb. Since the latter cannot use command line entries, we introduce a new [annotate] section duplicating the diff whitespace options.
author Patrick Mezard <pmezard@gmail.com>
date Fri, 18 Nov 2011 12:04:31 +0100
parents e6519c628454
children b35cf47286a6
comparison
equal deleted inserted replaced
15527:9926aab3d0b5 15528:a84698badf0b
73 text = text.replace(' \n', '\n') 73 text = text.replace(' \n', '\n')
74 if blank and opts.ignoreblanklines: 74 if blank and opts.ignoreblanklines:
75 text = re.sub('\n+', '\n', text).strip('\n') 75 text = re.sub('\n+', '\n', text).strip('\n')
76 return text 76 return text
77 77
78 def allblocks(text1, text2, opts=None, lines1=None, lines2=None): 78 def splitblock(base1, lines1, base2, lines2, opts):
79 # The input lines matches except for interwoven blank lines. We
80 # transform it into a sequence of matching blocks and blank blocks.
81 lines1 = [(wsclean(opts, l) and 1 or 0) for l in lines1]
82 lines2 = [(wsclean(opts, l) and 1 or 0) for l in lines2]
83 s1, e1 = 0, len(lines1)
84 s2, e2 = 0, len(lines2)
85 while s1 < e1 or s2 < e2:
86 i1, i2, btype = s1, s2, '='
87 if (i1 >= e1 or lines1[i1] == 0
88 or i2 >= e2 or lines2[i2] == 0):
89 # Consume the block of blank lines
90 btype = '~'
91 while i1 < e1 and lines1[i1] == 0:
92 i1 += 1
93 while i2 < e2 and lines2[i2] == 0:
94 i2 += 1
95 else:
96 # Consume the matching lines
97 while i1 < e1 and lines1[i1] == 1 and lines2[i2] == 1:
98 i1 += 1
99 i2 += 1
100 yield [base1 + s1, base1 + i1, base2 + s2, base2 + i2], btype
101 s1 = i1
102 s2 = i2
103
104 def allblocks(text1, text2, opts=None, lines1=None, lines2=None, refine=False):
79 """Return (block, type) tuples, where block is an mdiff.blocks 105 """Return (block, type) tuples, where block is an mdiff.blocks
80 line entry. type is '=' for blocks matching exactly one another 106 line entry. type is '=' for blocks matching exactly one another
81 (bdiff blocks), '!' for non-matching blocks and '~' for blocks 107 (bdiff blocks), '!' for non-matching blocks and '~' for blocks
82 matching only after having filtered blank lines. 108 matching only after having filtered blank lines. If refine is True,
109 then '~' blocks are refined and are only made of blank lines.
83 line1 and line2 are text1 and text2 split with splitnewlines() if 110 line1 and line2 are text1 and text2 split with splitnewlines() if
84 they are already available. 111 they are already available.
85 """ 112 """
86 if opts is None: 113 if opts is None:
87 opts = defaultopts 114 opts = defaultopts