Mercurial > diff-colorize
annotate diff-colorize.py @ 19:b709258a2fc2
Added highlighting differences between consecutive old and new lines.
author | Peter Hosey <hg@boredzo.org> |
---|---|
date | Wed, 05 Jan 2011 07:53:57 -0800 |
parents | 83d58ccc70bf |
children | b4caea436f4d |
rev | line source |
---|---|
0 | 1 #!/usr/bin/env python |
2 | |
6
d58b4e2e12d4
Moved the imports of sys and fileinput, so that all the imports are together.
Peter Hosey
parents:
5
diff
changeset
|
3 import sys |
4
b8b2d1931a9e
Get our color constants from the environment, if possible.
Peter Hosey
parents:
3
diff
changeset
|
4 import os |
6
d58b4e2e12d4
Moved the imports of sys and fileinput, so that all the imports are together.
Peter Hosey
parents:
5
diff
changeset
|
5 import fileinput |
4
b8b2d1931a9e
Get our color constants from the environment, if possible.
Peter Hosey
parents:
3
diff
changeset
|
6 |
15
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
7 has_256_color = (os.environ.get('TERM', None) == 'xterm-256color') |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
8 |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
9 index_color = int(os.environ.get('DIFF_INDEX_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
10 32 if has_256_color else 36)) |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
11 old_mode_color = int(os.environ.get('DIFF_OLD_MODE_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
12 88 if has_256_color else 31)) |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
13 new_mode_color = int(os.environ.get('DIFF_NEW_MODE_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
14 28 if has_256_color else 32)) |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
15 removed_color = int(os.environ.get('DIFF_REMOVED_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
16 160 if has_256_color else 31)) |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
17 added_color = int(os.environ.get('DIFF_ADDED_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
18 2 if has_256_color else 32)) |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
19 hunk_start_color = int(os.environ.get('DIFF_HUNK_START_COLOR', |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
20 32 if has_256_color else 36)) |
0 | 21 |
3
10948e4fd070
Move the color constants above the format strings, since the color constants are more editable.
Peter Hosey
parents:
2
diff
changeset
|
22 RESET_FORMAT = '\033[0m' |
15
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
23 COLOR_FORMAT_256 = '\033[38;5;%um' |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
24 COLOR_FORMAT_16 = '\033[38;%um' |
a7214992f904
Added a different set of default color codes and a different colorization format string. Both of these are to support 16-color mode (which is all Terminal supports).
Peter Hosey
parents:
13
diff
changeset
|
25 COLOR_FORMAT = COLOR_FORMAT_256 if has_256_color else COLOR_FORMAT_16 |
3
10948e4fd070
Move the color constants above the format strings, since the color constants are more editable.
Peter Hosey
parents:
2
diff
changeset
|
26 BEGIN_REVERSE_FORMAT = '\033[7m' |
10948e4fd070
Move the color constants above the format strings, since the color constants are more editable.
Peter Hosey
parents:
2
diff
changeset
|
27 END_REVERSE_FORMAT = '\033[27m' |
10948e4fd070
Move the color constants above the format strings, since the color constants are more editable.
Peter Hosey
parents:
2
diff
changeset
|
28 |
9 | 29 USAGE = """ |
30 Usage: diff ... | diff-colorize | |
31 or: diff-colorize < foo.diff | |
32 | |
33 Reads unified or git-style diff data from standard input, colorizes it, and writes the result to standard output. | |
34 | |
35 You can customize the color numbers used by setting these variables in your environment: | |
36 * DIFF_INDEX_COLOR (lines starting with "Index: " or "diff --git ") | |
37 * DIFF_OLD_MODE_COLOR (lines starting with "old mode"; these only appear in git-style diffs) | |
38 * DIFF_NEW_MODE_COLOR (lines starting with "new mode"; these only appear in git-style diffs) | |
39 * DIFF_REMOVED_COLOR (lines starting with "-") | |
40 * DIFF_ADDED_COLOR (lines starting with "+") | |
41 * DIFF_HUNK_START_COLOR (lines starting with "@@") | |
42 """.strip() | |
43 | |
18
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
44 def interleave(*sequences): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
45 "Generator that yields one object from each sequence in turn." |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
46 |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
47 def zip_pad(*iterables, **kw): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
48 "Downloaded from http://code.activestate.com/recipes/497007/" |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
49 from itertools import izip, chain |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
50 if kw: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
51 assert len(kw) == 1 |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
52 pad = kw["pad"] |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
53 else: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
54 pad = None |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
55 done = [len(iterables)-1] |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
56 def pad_iter(): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
57 if not done[0]: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
58 return |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
59 done[0] -= 1 |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
60 while 1: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
61 yield pad |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
62 iterables = [chain(seq, pad_iter()) for seq in iterables] |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
63 return izip(*iterables) |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
64 |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
65 for objects in zip_pad(*sequences): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
66 for obj in objects: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
67 if obj is not None: |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
68 yield obj |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
69 |
19
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
70 class Substring(object): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
71 def __init__(self, a, a_start, a_stop, b, b_start, b_stop): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
72 self.a = a |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
73 self.a_start = a_start |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
74 self.a_stop = a_stop |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
75 self.b = b |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
76 self.b_start = b_start |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
77 self.b_stop = b_stop |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
78 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
79 def before_a_substring(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
80 return self.a[:self.a_start] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
81 def before_b_substring(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
82 return self.b[:self.b_start] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
83 def substring(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
84 return ''.join(self.a[self.a_start:self.a_stop]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
85 a_substring = substring |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
86 b_substring = substring |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
87 def after_a_substring(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
88 return self.a[self.a_stop:] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
89 def after_b_substring(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
90 return self.b[self.b_stop:] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
91 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
92 def __hash__(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
93 return hash(self.substring()) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
94 def __cmp__(self, other): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
95 return cmp(self.a_start, other.a_start) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
96 def __eq__(self, other): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
97 return self.substring() == other.substring() |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
98 def __str__(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
99 return self.substring() |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
100 def __repr__(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
101 return 'Substring(%r)' % (self.substring(),) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
102 return 'Substring(%r from %r, %r, %r, %r, %r, %r)' % ( |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
103 self.substring(), |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
104 self.a, self.a_start, self.a_stop, |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
105 self.b, self.b_start, self.b_stop, |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
106 ) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
107 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
108 def longest_common_substring(a, b): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
109 """Returns a set of common substrings between a and b, which can be any finite indexable sliceable sequences. Substrings are returned as Substring objects. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
110 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
111 Clarified and slightly modified (to use a special Substring object) from http://en.wikibooks.org/w/index.php?title=Algorithm_implementation/Strings/Longest_common_substring&oldid=1419225#Python |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
112 """ |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
113 a_len = len(a) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
114 b_len = len(b) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
115 lengths = [[0] * (b_len + 1) for i in xrange(a_len + 1)] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
116 substrings = set() |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
117 greatest_length = current_run_length = 0 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
118 for a_idx in xrange(a_len): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
119 for b_idx in xrange(b_len): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
120 if a[a_idx] == b[b_idx]: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
121 current_run_length = lengths[a_idx][b_idx] + 1 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
122 lengths[a_idx+1][b_idx+1] = current_run_length |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
123 if current_run_length > greatest_length: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
124 greatest_length = current_run_length |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
125 substrings.clear() |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
126 if current_run_length == greatest_length: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
127 # substrings.add(a[a_idx - current_run_length + 1:a_idx + 1]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
128 substrings.add(Substring(a, a_idx - current_run_length + 1, a_idx + 1, b, b_idx - current_run_length + 1, b_idx + 1)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
129 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
130 if current_run_length > 0: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
131 substrings.add(Substring(a, a_idx - current_run_length + 1, a_idx + 1, b, b_idx - current_run_length + 1, b_idx + 1)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
132 return substrings |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
133 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
134 def common_and_distinct_substrings(a, b): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
135 "Takes two strings, a and b, tokenizes them, and returns a linked list whose nodes contain runs of either common or unique tokens." |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
136 def tokenize(a): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
137 "Each token is an identifier, a number, or a single character." |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
138 import re |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
139 # Identifier, binary number, hex number, decimal number, operator, other punctuation. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
140 token_exp = re.compile('[_a-zA-Z][_a-zA-Z0-9]+:?|0b[01]+|0[xX][0-9A-Fa-f]+|[0-9]+|[-+*|&^/%\[\]<=>,]|[()\\\\;`{}]') |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
141 start = 0 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
142 for match in token_exp.finditer(a): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
143 for ch in a[start:match.start()]: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
144 yield ch |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
145 yield match.group(0) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
146 start = match.end() |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
147 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
148 remainder = a[start:] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
149 if remainder: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
150 yield remainder |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
151 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
152 a = list(tokenize(a)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
153 b = list(tokenize(b)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
154 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
155 class DualPayloadLinkedListNode(object): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
156 "This linked list gives each node two next pointers." |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
157 def __init__(self, a, b, differ=None): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
158 self.a = a |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
159 self.b = b |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
160 self.next = None |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
161 if differ is None: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
162 differ = (self.a != self.b) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
163 self.differ = differ |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
164 def __iter__(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
165 def walk_linked_list(x): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
166 while x is not None: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
167 yield x |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
168 x = x.next |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
169 return walk_linked_list(self) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
170 def __repr__(self): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
171 return repr([('(%r, %r)' % (x.a, x.b)) if x.differ else repr(x.a) for x in self]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
172 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
173 # Linked-list nodes for common substrings will have a single Substring object in both payloads. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
174 # Nodes for difference runs will have a string in each payload. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
175 empty_substring = Substring(a, 0, 0, b, 0, 0) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
176 chunks_head = DualPayloadLinkedListNode(empty_substring, empty_substring, False) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
177 # This node is used when the input strings have no common substrings. When they do have common substrings, this node will be replaced with a real node. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
178 chunks_head.next = DualPayloadLinkedListNode(empty_substring, empty_substring, False) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
179 # Not chunks_head.next, since it will be replaced. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
180 chunks_tail = chunks_head |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
181 for sub in sorted(longest_common_substring(a, b)): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
182 last_sub = chunks_tail.a |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
183 a_dif_run = ''.join(a[last_sub.a_stop:sub.a_start]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
184 b_dif_run = ''.join(b[last_sub.b_stop:sub.b_start]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
185 if a_dif_run or b_dif_run: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
186 chunks_tail.next = DualPayloadLinkedListNode(a_dif_run, b_dif_run, True) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
187 chunks_tail = chunks_tail.next |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
188 chunks_tail.next = DualPayloadLinkedListNode(sub, sub, False) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
189 chunks_tail = chunks_tail.next |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
190 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
191 # Get what comes after the last substring, if anything. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
192 last_sub = chunks_tail.a |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
193 a_dif_run = ''.join(a[last_sub.a_stop:]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
194 b_dif_run = ''.join(b[last_sub.b_stop:]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
195 if a_dif_run or b_dif_run: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
196 chunks_tail.next = DualPayloadLinkedListNode(a_dif_run, b_dif_run, True) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
197 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
198 return chunks_head.next |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
199 |
7
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
200 # Everything in the unified diff format is identified by a prefix. The prefixes are: |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
201 # 'Index: ': File marker (unified diff) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
202 # 'diff --git': File marker (git-style diff) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
203 # 'old mode': File permissions mode before change |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
204 # 'new mode': File permissions mode after change |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
205 # '---': Defining '-' (giving the name and modification date of the file before change) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
206 # '+++': Defining '+' (giving the name and modification date of the file after change) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
207 # '-': Line before change (i.e., removed) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
208 # '+': Line after change (i.e., added) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
209 # ' ': Line that hasn't changed |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
210 # '@@': Hunk start (@@ -start,length +start, length @@) |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
211 # |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
212 # We need to look for these prefixes in order, in order to handle '---'/'+++' before '-'/'+'. Hence the OrderedDict. |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
213 class OrderedDict(dict): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
214 def __init__(self, input=None): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
215 if input is None: |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
216 self.keys = [] |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
217 super(OrderedDict, self).__init__() |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
218 elif isinstance(input, dict): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
219 self.keys = list(input) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
220 super(OrderedDict, self).__init__(input) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
221 else: |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
222 self.keys = [k for k, v in input] |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
223 super(OrderedDict, self).__init__(input) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
224 def __iter__(self): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
225 return iter(self.keys) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
226 def __setitem__(self, k, v): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
227 if k not in self: |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
228 self.keys.append(k) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
229 super(OrderedDict, self).__setitem__(k, v) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
230 def __delitem__(self, k): |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
231 super(OrderedDict, self).__delitem__(k) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
232 self.keys.remove(k) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
233 |
7
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
234 # Each value includes not only the terminal-config characters, but also the key, somewhere within it (possibly between two terminal-config strings). |
c6337f653d9b
Added some comments documenting the OrderedDict class and our instance's contents.
Peter Hosey
parents:
6
diff
changeset
|
235 # Theoretically, you could replace the key with some other string or leave it out entirely, if you wanted to, but I wouldn't recommend it. |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
236 prefixes = OrderedDict() |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
237 prefixes['---'] = ( |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
238 COLOR_FORMAT % (removed_color,) |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
239 + BEGIN_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
240 + '---' |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
241 + END_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
242 ) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
243 prefixes['+++'] = ( |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
244 COLOR_FORMAT % (added_color,) |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
245 + BEGIN_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
246 + '+++' |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
247 + END_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
248 ) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
249 prefixes['-'] = ( |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
250 COLOR_FORMAT % (removed_color,) |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
251 + BEGIN_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
252 + '-' |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
253 + END_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
254 ) |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
255 prefixes['+'] = ( |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
256 COLOR_FORMAT % (added_color,) |
1
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
257 + BEGIN_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
258 + '+' |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
259 + END_REVERSE_FORMAT |
44f86539d245
Refactored to allow me to more easily add new prefixes.
Peter Hosey
parents:
0
diff
changeset
|
260 ) |
5
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
261 prefixes['old mode'] = ( # Git-style diffs only |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
262 COLOR_FORMAT % (old_mode_color,) |
5
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
263 + BEGIN_REVERSE_FORMAT |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
264 + 'old mode' |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
265 + END_REVERSE_FORMAT |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
266 ) |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
267 prefixes['new mode'] = ( # Git-style diffs only |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
268 COLOR_FORMAT % (new_mode_color,) |
5
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
269 + BEGIN_REVERSE_FORMAT |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
270 + 'new mode' |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
271 + END_REVERSE_FORMAT |
fa7cd4c2716b
Added prefixes “old mode” and “new mode”, found in Git-style diffs, along with new color constants for them. We treat these the same way we treat “---” and “+++”.
Peter Hosey
parents:
4
diff
changeset
|
272 ) |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
273 prefixes['Index: '] = COLOR_FORMAT % (index_color,) + 'Index: ' |
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
274 prefixes['diff --git '] = COLOR_FORMAT % (index_color,) + 'diff --git ' |
2
9eda9139d627
Added support for hunk start markers (@@…@@). For these, we set the whole line in reverse video, in the same color we use for index lines.
Peter Hosey
parents:
1
diff
changeset
|
275 prefixes['@@'] = ( |
8
4bb2557d24cd
Now that these can come from the environment, they are variables. Lowercasing their names for this reason.
Peter Hosey
parents:
7
diff
changeset
|
276 COLOR_FORMAT % (hunk_start_color,) |
2
9eda9139d627
Added support for hunk start markers (@@…@@). For these, we set the whole line in reverse video, in the same color we use for index lines.
Peter Hosey
parents:
1
diff
changeset
|
277 + BEGIN_REVERSE_FORMAT |
9eda9139d627
Added support for hunk start markers (@@…@@). For these, we set the whole line in reverse video, in the same color we use for index lines.
Peter Hosey
parents:
1
diff
changeset
|
278 + '@@' |
9eda9139d627
Added support for hunk start markers (@@…@@). For these, we set the whole line in reverse video, in the same color we use for index lines.
Peter Hosey
parents:
1
diff
changeset
|
279 ) |
0 | 280 |
17
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
281 if __name__ == "__main__": |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
282 if sys.stdin.isatty(): |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
283 # Standard input is a TTY, meaning that the user ran 'diff-colorize' at the shell prompt, without redirecting anything into it. Print usage info and exit. |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
284 sys.exit(USAGE) |
9 | 285 |
18
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
286 # Buffers to support interleaving old and new lines that were contiguous runs. |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
287 buffer_old = [] # '-' lines |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
288 buffer_new = [] # '+' lines |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
289 |
19
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
290 def flush_buffers(buffer_old, buffer_new): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
291 "Flush the buffers, interleaving the lines and highlighting differences between them." |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
292 def print_single_line(buffered_line): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
293 prefix = '-' if buffered_line.startswith('-') else '+' |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
294 buffered_line = buffered_line[len(prefix):] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
295 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
296 sys.stdout.write(prefixes[prefix]) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
297 sys.stdout.write(buffered_line) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
298 sys.stdout.write(RESET_FORMAT) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
299 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
300 last_line_if_old = None |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
301 for buffered_line in interleave(buffer_old, buffer_new): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
302 if buffered_line.startswith('-'): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
303 if last_line_if_old is not None: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
304 print_single_line(last_line_if_old) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
305 last_line_if_old = buffered_line |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
306 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
307 if last_line_if_old is None: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
308 # No old line immediately preceding this, so just print it. |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
309 print_single_line(buffered_line) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
310 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
311 old_line = last_line_if_old |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
312 new_line = buffered_line |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
313 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
314 old_line_output = [prefixes['-']] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
315 new_line_output = [prefixes['+']] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
316 for node in common_and_distinct_substrings(old_line[1:], new_line[1:]): |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
317 if node.differ: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
318 old_line_output.append(BEGIN_REVERSE_FORMAT) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
319 old_line_output.append(str(node.a)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
320 old_line_output.append(END_REVERSE_FORMAT) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
321 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
322 new_line_output.append(BEGIN_REVERSE_FORMAT) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
323 new_line_output.append(str(node.b)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
324 new_line_output.append(END_REVERSE_FORMAT) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
325 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
326 old_line_output.append(str(node.a)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
327 new_line_output.append(str(node.b)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
328 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
329 last_line_if_old = None |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
330 sys.stdout.writelines(''.join(old_line_output)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
331 sys.stdout.writelines(''.join(new_line_output)) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
332 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
333 if last_line_if_old is not None: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
334 print_single_line(last_line_if_old) |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
335 |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
336 del buffer_old[:] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
337 del buffer_new[:] |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
338 |
17
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
339 for line in fileinput.input(): |
18
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
340 if line.startswith('-') and not line.startswith('---'): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
341 buffer_old.append(line) |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
342 continue |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
343 elif line.startswith('+') and not line.startswith('+++'): |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
344 buffer_new.append(line) |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
345 continue |
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
346 else: |
19
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
347 flush_buffers(buffer_old, buffer_new) |
18
83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
17
diff
changeset
|
348 |
17
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
349 for prefix_to_test in prefixes: |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
350 if line.startswith(prefix_to_test): |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
351 sys.stdout.write(prefixes[prefix_to_test]) |
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
352 line = line[len(prefix_to_test):] |
0 | 353 |
17
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
354 sys.stdout.write(line) |
0 | 355 |
17
54a209909531
Make the file importable for debugging purposes by wrapping the main-program-only bits in an if __name__ == "__main__" block.
Peter Hosey <hg@boredzo.org>
parents:
15
diff
changeset
|
356 sys.stdout.write(RESET_FORMAT) |
19
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
357 else: |
b709258a2fc2
Added highlighting differences between consecutive old and new lines.
Peter Hosey <hg@boredzo.org>
parents:
18
diff
changeset
|
358 flush_buffers(buffer_old, buffer_new) |