Mercurial > diff-colorize
comparison diff-colorize.py @ 18:83d58ccc70bf
Interleave adjacent runs of consecutive old and new lines into alternating old and new lines.
author | Peter Hosey <hg@boredzo.org> |
---|---|
date | Wed, 05 Jan 2011 06:56:01 -0800 |
parents | 54a209909531 |
children | b709258a2fc2 |
comparison
equal
deleted
inserted
replaced
17:54a209909531 | 18:83d58ccc70bf |
---|---|
38 * DIFF_NEW_MODE_COLOR (lines starting with "new 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 "-") | 39 * DIFF_REMOVED_COLOR (lines starting with "-") |
40 * DIFF_ADDED_COLOR (lines starting with "+") | 40 * DIFF_ADDED_COLOR (lines starting with "+") |
41 * DIFF_HUNK_START_COLOR (lines starting with "@@") | 41 * DIFF_HUNK_START_COLOR (lines starting with "@@") |
42 """.strip() | 42 """.strip() |
43 | |
44 def interleave(*sequences): | |
45 "Generator that yields one object from each sequence in turn." | |
46 | |
47 def zip_pad(*iterables, **kw): | |
48 "Downloaded from http://code.activestate.com/recipes/497007/" | |
49 from itertools import izip, chain | |
50 if kw: | |
51 assert len(kw) == 1 | |
52 pad = kw["pad"] | |
53 else: | |
54 pad = None | |
55 done = [len(iterables)-1] | |
56 def pad_iter(): | |
57 if not done[0]: | |
58 return | |
59 done[0] -= 1 | |
60 while 1: | |
61 yield pad | |
62 iterables = [chain(seq, pad_iter()) for seq in iterables] | |
63 return izip(*iterables) | |
64 | |
65 for objects in zip_pad(*sequences): | |
66 for obj in objects: | |
67 if obj is not None: | |
68 yield obj | |
43 | 69 |
44 # Everything in the unified diff format is identified by a prefix. The prefixes are: | 70 # Everything in the unified diff format is identified by a prefix. The prefixes are: |
45 # 'Index: ': File marker (unified diff) | 71 # 'Index: ': File marker (unified diff) |
46 # 'diff --git': File marker (git-style diff) | 72 # 'diff --git': File marker (git-style diff) |
47 # 'old mode': File permissions mode before change | 73 # 'old mode': File permissions mode before change |
125 if __name__ == "__main__": | 151 if __name__ == "__main__": |
126 if sys.stdin.isatty(): | 152 if sys.stdin.isatty(): |
127 # 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. | 153 # 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. |
128 sys.exit(USAGE) | 154 sys.exit(USAGE) |
129 | 155 |
156 # Buffers to support interleaving old and new lines that were contiguous runs. | |
157 buffer_old = [] # '-' lines | |
158 buffer_new = [] # '+' lines | |
159 | |
130 for line in fileinput.input(): | 160 for line in fileinput.input(): |
161 if line.startswith('-') and not line.startswith('---'): | |
162 buffer_old.append(line) | |
163 continue | |
164 elif line.startswith('+') and not line.startswith('+++'): | |
165 buffer_new.append(line) | |
166 continue | |
167 else: | |
168 # Flush the buffers, interleaving the lines. | |
169 for buffered_line in interleave(buffer_old, buffer_new): | |
170 prefix = '-' if buffered_line.startswith('-') else '+' | |
171 buffered_line = buffered_line[len(prefix):] | |
172 | |
173 sys.stdout.write(prefixes[prefix]) | |
174 sys.stdout.write(buffered_line) | |
175 sys.stdout.write(RESET_FORMAT) | |
176 | |
177 del buffer_old[:] | |
178 del buffer_new[:] | |
179 | |
131 for prefix_to_test in prefixes: | 180 for prefix_to_test in prefixes: |
132 if line.startswith(prefix_to_test): | 181 if line.startswith(prefix_to_test): |
133 sys.stdout.write(prefixes[prefix_to_test]) | 182 sys.stdout.write(prefixes[prefix_to_test]) |
134 line = line[len(prefix_to_test):] | 183 line = line[len(prefix_to_test):] |
135 | 184 |