# HG changeset patch # User Brodie Rao # Date 1270239726 18000 # Node ID d14d45fae92750ea51a34b8911564e865f8b7e5a # Parent 2096496b40ec2102ff808c3e362db510ed194be3 diff: make use of output labeling diff -r 2096496b40ec -r d14d45fae927 mercurial/commands.py --- a/mercurial/commands.py Fri Apr 02 15:22:05 2010 -0500 +++ b/mercurial/commands.py Fri Apr 02 15:22:06 2010 -0500 @@ -1174,14 +1174,16 @@ diffopts = patch.diffopts(ui, opts) m = cmdutil.match(repo, pats, opts) - it = patch.diff(repo, node1, node2, match=m, opts=diffopts) if stat: + it = patch.diff(repo, node1, node2, match=m, opts=diffopts) width = ui.interactive() and util.termwidth() or 80 - ui.write(patch.diffstat(util.iterlines(it), width=width, - git=diffopts.git)) + for chunk, label in patch.diffstatui(util.iterlines(it), width=width, + git=diffopts.git): + ui.write(chunk, label=label) else: - for chunk in it: - ui.write(chunk) + it = patch.diffui(repo, node1, node2, match=m, opts=diffopts) + for chunk, label in it: + ui.write(chunk, label=label) def export(ui, repo, *changesets, **opts): """dump the header and diffs for one or more changesets diff -r 2096496b40ec -r d14d45fae927 mercurial/patch.py --- a/mercurial/patch.py Fri Apr 02 15:22:05 2010 -0500 +++ b/mercurial/patch.py Fri Apr 02 15:22:06 2010 -0500 @@ -1466,6 +1466,43 @@ else: return difffn(opts, None) +def difflabel(func, *args, **kw): + '''yields 2-tuples of (output, label) based on the output of func()''' + prefixes = [('diff', 'diff.diffline'), + ('copy', 'diff.extended'), + ('rename', 'diff.extended'), + ('old', 'diff.extended'), + ('new', 'diff.extended'), + ('deleted', 'diff.extended'), + ('---', 'diff.file_a'), + ('+++', 'diff.file_b'), + ('@@', 'diff.hunk'), + ('-', 'diff.deleted'), + ('+', 'diff.inserted')] + + for chunk in func(*args, **kw): + lines = chunk.split('\n') + for i, line in enumerate(lines): + if i != 0: + yield ('\n', '') + stripline = line + if line and line[0] in '+-': + # highlight trailing whitespace, but only in changed lines + stripline = line.rstrip() + for prefix, label in prefixes: + if stripline.startswith(prefix): + yield (stripline, label) + break + else: + yield (line, '') + if line != stripline: + yield (line[len(stripline):], 'diff.trailingwhitespace') + +def diffui(*args, **kw): + '''like diff(), but yields 2-tuples of (output, label) for ui.write()''' + return difflabel(diff, *args, **kw) + + def _addmodehdr(header, omode, nmode): if omode != nmode: header.append('old mode %s\n' % omode) @@ -1636,3 +1673,22 @@ % (len(stats), totaladds, totalremoves)) return ''.join(output) + +def diffstatui(*args, **kw): + '''like diffstat(), but yields 2-tuples of (output, label) for + ui.write() + ''' + + for line in diffstat(*args, **kw).splitlines(): + if line and line[-1] in '+-': + name, graph = line.rsplit(' ', 1) + yield (name + ' ', '') + m = re.search(r'\++', graph) + if m: + yield (m.group(0), 'diffstat.inserted') + m = re.search(r'-+', graph) + if m: + yield (m.group(0), 'diffstat.deleted') + else: + yield (line, '') + yield ('\n', '')