[PATCH v7] patch: add within-line color diff capacity

Yuya Nishihara yuya at tcha.org
Thu Dec 7 08:07:30 EST 2017


On Thu, 07 Dec 2017 18:26:39 +0900, matthieu.laneuville at octobus.net wrote:
> # HG changeset patch
> # User Matthieu Laneuville <matthieu.laneuville at octobus.net>
> # Date 1508944418 -32400
> #      Thu Oct 26 00:13:38 2017 +0900
> # Node ID 6a7378611408a4bb77ad2aca8c8d0ccfe697ea26
> # Parent  fcc96cf0983d01c542a9b5e529b434b98941371d
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 6a7378611408
> # EXP-Topic inline-diff
> patch: add within-line color diff capacity

Queued, thanks.

There are some nits and minor bugs. Can you send follow-up patches?

>  def difflabel(func, *args, **kw):
>      '''yields 2-tuples of (output, label) based on the output of func()'''
> +    inlinecolor = False
> +    if 'opts' in kw.keys():

Dropped '.keys()'.

> +        inlinecolor = kw['opts'].worddiff
>      headprefixes = [('diff', 'diff.diffline'),
>                      ('copy', 'diff.extended'),
>                      ('rename', 'diff.extended'),
> @@ -2479,6 +2484,9 @@ def difflabel(func, *args, **kw):
>      head = False
>      for chunk in func(*args, **kw):
>          lines = chunk.split('\n')
> +        matches = {}
> +        if inlinecolor:
> +            matches = _findmatches(lines)
>          for i, line in enumerate(lines):
>              if i != 0:
>                  yield ('\n', '')
> @@ -2506,7 +2514,14 @@ def difflabel(func, *args, **kw):
>                              if '\t' == token[0]:
>                                  yield (token, 'diff.tab')
>                              else:
> -                                yield (token, label)
> +                                if i in matches:
> +                                    for l, t in _inlinediff(

Nit: I prefer (token, label) order for consistency.

> +                                                  lines[i].rstrip(),
> +                                                  lines[matches[i]].rstrip(),
> +                                                  label):
> +                                        yield (t, l)

This doesn't work if '\t' is in stripline. See 'hg log -p Makefile' as an
example. Perhaps we'll have to move 'diff.tab' handling to _inlinediff().

> +def _inlinediff(s1, s2, operation):
> +    '''Perform string diff to highlight specific changes.'''
> +    operation_skip = '+?' if operation == 'diff.deleted' else '-?'
> +    if operation == 'diff.deleted':
> +        s2, s1 = s1, s2
> +
> +    buff = []
> +    # we never want to higlight the leading +-
> +    if operation == 'diff.deleted' and s2.startswith('-'):
> +        label = operation
> +        token = '-'
> +        s2 = s2[1:]
> +        s1 = s1[1:]
> +    elif operation == 'diff.inserted' and s1.startswith('+'):
> +        label = operation
> +        token = '+'
> +        s2 = s2[1:]
> +        s1 = s1[1:]

else:
    raise ProgrammingError?

Otherwise label and token would be unassigned.

> +    s = difflib.ndiff(re.split(br'(\W)', s2), re.split(br'(\W)', s1))
> +    for part in s:
> +        if part[0] in operation_skip:
> +            continue
> +        l = operation + '.highlight'
> +        if part[0] in ' ':
> +            l = operation
> +        if l == label: # contiguous token with same label
> +            token += part[2:]
> +            continue
> +        else:
> +            buff.append((label, token))
> +            label = l
> +            token = part[2:]
> +    buff.append((label, token))


More information about the Mercurial-devel mailing list