Mercurial > hg > mercurial-crew-with-dirclash
diff mercurial/mdiff.py @ 2873:4ec58b157265
refactor text diff/patch code.
rename commands.dodiff to patch.diff.
rename commands.doexport to patch.export.
move some functions from commands to new mercurial.cmdutil module.
turn list of diff options into mdiff.diffopts class.
patch.diff and patch.export now has clean api for call from 3rd party
python code.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Sat, 12 Aug 2006 16:13:27 -0700 |
parents | 345bac2bc4ec |
children | 8b02af865990 |
line wrap: on
line diff
--- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -19,14 +19,39 @@ def splitnewlines(text): lines[-1] = lines[-1][:-1] return lines -def unidiff(a, ad, b, bd, fn, r=None, text=False, - showfunc=False, ignorews=False, ignorewsamount=False, - ignoreblanklines=False): +class diffopts(object): + '''context is the number of context lines + text treats all files as text + showfunc enables diff -p output + ignorews ignores all whitespace changes in the diff + ignorewsamount ignores changes in the amount of whitespace + ignoreblanklines ignores changes whose lines are all blank''' + defaults = { + 'context': 3, + 'text': False, + 'showfunc': True, + 'ignorews': False, + 'ignorewsamount': False, + 'ignoreblanklines': False, + } + + __slots__ = defaults.keys() + + def __init__(self, **opts): + for k in self.__slots__: + v = opts.get(k) + if v is None: + v = self.defaults[k] + setattr(self, k, v) + +defaultopts = diffopts() + +def unidiff(a, ad, b, bd, fn, r=None, opts=defaultopts): if not a and not b: return "" epoch = util.datestr((0, 0)) - if not text and (util.binary(a) or util.binary(b)): + if not opts.text and (util.binary(a) or util.binary(b)): l = ['Binary file %s has changed\n' % fn] elif not a: b = splitnewlines(b) @@ -49,10 +74,7 @@ def unidiff(a, ad, b, bd, fn, r=None, te else: al = splitnewlines(a) bl = splitnewlines(b) - l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, - showfunc=showfunc, ignorews=ignorews, - ignorewsamount=ignorewsamount, - ignoreblanklines=ignoreblanklines)) + l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, opts=opts)) if not l: return "" # difflib uses a space, rather than a tab l[0] = "%s\t%s\n" % (l[0][:-2], ad) @@ -72,21 +94,15 @@ def unidiff(a, ad, b, bd, fn, r=None, te # t1 and t2 are the text to be diffed # l1 and l2 are the text broken up into lines # header1 and header2 are the filenames for the diff output -# context is the number of context lines -# showfunc enables diff -p output -# ignorews ignores all whitespace changes in the diff -# ignorewsamount ignores changes in the amount of whitespace -# ignoreblanklines ignores changes whose lines are all blank -def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False, - ignorews=False, ignorewsamount=False, ignoreblanklines=False): +def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts): def contextend(l, len): - ret = l + context + ret = l + opts.context if ret > len: ret = len return ret def contextstart(l): - ret = l - context + ret = l - opts.context if ret < 0: return 0 return ret @@ -101,7 +117,7 @@ def bunidiff(t1, t2, l1, l2, header1, he blen = b2 - bstart + aend - a2 func = "" - if showfunc: + if opts.showfunc: # walk backwards from the start of the context # to find a line starting with an alphanumeric char. for x in xrange(astart, -1, -1): @@ -119,14 +135,14 @@ def bunidiff(t1, t2, l1, l2, header1, he header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ] - if showfunc: + if opts.showfunc: funcre = re.compile('\w') - if ignorewsamount: + if opts.ignorewsamount: wsamountre = re.compile('[ \t]+') wsappendedre = re.compile(' \n') - if ignoreblanklines: + if opts.ignoreblanklines: wsblanklinesre = re.compile('\n') - if ignorews: + if opts.ignorews: wsre = re.compile('[ \t]') # bdiff.blocks gives us the matching sequences in the files. The loop @@ -159,13 +175,13 @@ def bunidiff(t1, t2, l1, l2, header1, he if not old and not new: continue - if ignoreblanklines: + if opts.ignoreblanklines: wsold = wsblanklinesre.sub('', "".join(old)) wsnew = wsblanklinesre.sub('', "".join(new)) if wsold == wsnew: continue - if ignorewsamount: + if opts.ignorewsamount: wsold = wsamountre.sub(' ', "".join(old)) wsold = wsappendedre.sub('\n', wsold) wsnew = wsamountre.sub(' ', "".join(new)) @@ -173,7 +189,7 @@ def bunidiff(t1, t2, l1, l2, header1, he if wsold == wsnew: continue - if ignorews: + if opts.ignorews: wsold = wsre.sub('', "".join(old)) wsnew = wsre.sub('', "".join(new)) if wsold == wsnew: @@ -184,7 +200,7 @@ def bunidiff(t1, t2, l1, l2, header1, he prev = None if hunk: # join with the previous hunk if it falls inside the context - if astart < hunk[1] + context + 1: + if astart < hunk[1] + opts.context + 1: prev = hunk astart = hunk[1] bstart = hunk[3]