equal
deleted
inserted
replaced
58 # public functions |
58 # public functions |
59 |
59 |
60 def split(stream): |
60 def split(stream): |
61 '''return an iterator of individual patches from a stream''' |
61 '''return an iterator of individual patches from a stream''' |
62 def isheader(line, inheader): |
62 def isheader(line, inheader): |
63 if inheader and line[0] in (' ', '\t'): |
63 if inheader and line.startswith((' ', '\t')): |
64 # continuation |
64 # continuation |
65 return True |
65 return True |
66 if line[0] in (' ', '-', '+'): |
66 if line.startswith((' ', '-', '+')): |
67 # diff line - don't check for header pattern in there |
67 # diff line - don't check for header pattern in there |
68 return False |
68 return False |
69 l = line.split(': ', 1) |
69 l = line.split(': ', 1) |
70 return len(l) == 2 and ' ' not in l[0] |
70 return len(l) == 2 and ' ' not in l[0] |
71 |
71 |
1389 top = 0 |
1389 top = 0 |
1390 bot = 0 |
1390 bot = 0 |
1391 hlen = len(self.hunk) |
1391 hlen = len(self.hunk) |
1392 for x in xrange(hlen - 1): |
1392 for x in xrange(hlen - 1): |
1393 # the hunk starts with the @@ line, so use x+1 |
1393 # the hunk starts with the @@ line, so use x+1 |
1394 if self.hunk[x + 1][0] == ' ': |
1394 if self.hunk[x + 1].startswith(' '): |
1395 top += 1 |
1395 top += 1 |
1396 else: |
1396 else: |
1397 break |
1397 break |
1398 if not toponly: |
1398 if not toponly: |
1399 for x in xrange(hlen - 1): |
1399 for x in xrange(hlen - 1): |
1400 if self.hunk[hlen - bot - 1][0] == ' ': |
1400 if self.hunk[hlen - bot - 1].startswith(' '): |
1401 bot += 1 |
1401 bot += 1 |
1402 else: |
1402 else: |
1403 break |
1403 break |
1404 |
1404 |
1405 bot = min(fuzz, bot) |
1405 bot = min(fuzz, bot) |
1797 tofile = lr.readline() |
1797 tofile = lr.readline() |
1798 header += [fromfile, tofile] |
1798 header += [fromfile, tofile] |
1799 else: |
1799 else: |
1800 lr.push(fromfile) |
1800 lr.push(fromfile) |
1801 yield 'file', header |
1801 yield 'file', header |
1802 elif line[0:1] == ' ': |
1802 elif line.startswith(' '): |
1803 yield 'context', scanwhile(line, lambda l: l[0] in ' \\') |
1803 cs = (' ', '\\') |
1804 elif line[0] in '-+': |
1804 yield 'context', scanwhile(line, lambda l: l.startswith(cs)) |
1805 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\') |
1805 elif line.startswith(('-', '+')): |
|
1806 cs = ('-', '+', '\\') |
|
1807 yield 'hunk', scanwhile(line, lambda l: l.startswith(cs)) |
1806 else: |
1808 else: |
1807 m = lines_re.match(line) |
1809 m = lines_re.match(line) |
1808 if m: |
1810 if m: |
1809 yield 'range', m.groups() |
1811 yield 'range', m.groups() |
1810 else: |
1812 else: |
2502 yield ('\n', '') |
2504 yield ('\n', '') |
2503 if head: |
2505 if head: |
2504 if line.startswith('@'): |
2506 if line.startswith('@'): |
2505 head = False |
2507 head = False |
2506 else: |
2508 else: |
2507 if line and line[0] not in ' +-@\\': |
2509 if line and not line.startswith((' ', '+', '-', '@', '\\')): |
2508 head = True |
2510 head = True |
2509 stripline = line |
2511 stripline = line |
2510 diffline = False |
2512 diffline = False |
2511 if not head and line and line[0] in '+-': |
2513 if not head and line and line.startswith(('+', '-')): |
2512 # highlight tabs and trailing whitespace, but only in |
2514 # highlight tabs and trailing whitespace, but only in |
2513 # changed lines |
2515 # changed lines |
2514 stripline = line.rstrip() |
2516 stripline = line.rstrip() |
2515 diffline = True |
2517 diffline = True |
2516 |
2518 |
2546 lastmatch = 0 |
2548 lastmatch = 0 |
2547 matches = {} |
2549 matches = {} |
2548 for i, line in enumerate(slist): |
2550 for i, line in enumerate(slist): |
2549 if line == '': |
2551 if line == '': |
2550 continue |
2552 continue |
2551 if line[0] == '-': |
2553 if line.startswith('-'): |
2552 lastmatch = max(lastmatch, i) |
2554 lastmatch = max(lastmatch, i) |
2553 newgroup = False |
2555 newgroup = False |
2554 for j, newline in enumerate(slist[lastmatch + 1:]): |
2556 for j, newline in enumerate(slist[lastmatch + 1:]): |
2555 if newline == '': |
2557 if newline == '': |
2556 continue |
2558 continue |
2557 if newline[0] == '-' and newgroup: # too far, no match |
2559 if newline.startswith('-') and newgroup: # too far, no match |
2558 break |
2560 break |
2559 if newline[0] == '+': # potential match |
2561 if newline.startswith('+'): # potential match |
2560 newgroup = True |
2562 newgroup = True |
2561 sim = difflib.SequenceMatcher(None, line, newline).ratio() |
2563 sim = difflib.SequenceMatcher(None, line, newline).ratio() |
2562 if sim > 0.7: |
2564 if sim > 0.7: |
2563 lastmatch = lastmatch + 1 + j |
2565 lastmatch = lastmatch + 1 + j |
2564 matches[i] = lastmatch |
2566 matches[i] = lastmatch |
2566 break |
2568 break |
2567 return matches |
2569 return matches |
2568 |
2570 |
2569 def _inlinediff(s1, s2, operation): |
2571 def _inlinediff(s1, s2, operation): |
2570 '''Perform string diff to highlight specific changes.''' |
2572 '''Perform string diff to highlight specific changes.''' |
2571 operation_skip = '+?' if operation == 'diff.deleted' else '-?' |
2573 operation_skip = ('+', '?') if operation == 'diff.deleted' else ('-', '?') |
2572 if operation == 'diff.deleted': |
2574 if operation == 'diff.deleted': |
2573 s2, s1 = s1, s2 |
2575 s2, s1 = s1, s2 |
2574 |
2576 |
2575 buff = [] |
2577 buff = [] |
2576 # we never want to higlight the leading +- |
2578 # we never want to higlight the leading +- |
2588 raise error.ProgrammingError("Case not expected, operation = %s" % |
2590 raise error.ProgrammingError("Case not expected, operation = %s" % |
2589 operation) |
2591 operation) |
2590 |
2592 |
2591 s = difflib.ndiff(_nonwordre.split(s2), _nonwordre.split(s1)) |
2593 s = difflib.ndiff(_nonwordre.split(s2), _nonwordre.split(s1)) |
2592 for part in s: |
2594 for part in s: |
2593 if part[0] in operation_skip or len(part) == 2: |
2595 if part.startswith(operation_skip) or len(part) == 2: |
2594 continue |
2596 continue |
2595 l = operation + '.highlight' |
2597 l = operation + '.highlight' |
2596 if part[0] in ' ': |
2598 if part.startswith(' '): |
2597 l = operation |
2599 l = operation |
2598 if part[2:] == '\t': |
2600 if part[2:] == '\t': |
2599 l = 'diff.tab' |
2601 l = 'diff.tab' |
2600 if l == label: # contiguous token with same label |
2602 if l == label: # contiguous token with same label |
2601 token += part[2:] |
2603 token += part[2:] |