Przeglądaj źródła

more flexible mix color; discard hunk addr stuff

Matthew Wang 11 lat temu
rodzic
commit
51dbcfb00f
3 zmienionych plików z 136 dodań i 184 usunięć
  1. 4
    1
      Makefile
  2. 18
    40
      src/cdiff.py
  3. 114
    143
      tests/single.udiff

+ 4
- 1
Makefile Wyświetl plik

@@ -1,6 +1,9 @@
1 1
 # Makefile for testing
2 2
 
3
-.PHONY: test single-udiff multi-udiff
3
+.PHONY: dogfood test single-udiff multi-udiff
4
+
5
+dogfood:
6
+	git diff | src/cdiff.py
4 7
 
5 8
 test: single-udiff multi-udiff
6 9
 

+ 18
- 40
src/cdiff.py Wyświetl plik

@@ -17,7 +17,7 @@ COLORS = {
17 17
     'lightred'      : '\x1b[1;31m',
18 18
     'lightgreen'    : '\x1b[1;32m',
19 19
     'lightyellow'   : '\x1b[1;33m',
20
-    'lightblue  '   : '\x1b[1;34m',
20
+    'lightblue'     : '\x1b[1;34m',
21 21
     'lightmagenta'  : '\x1b[1;35m',
22 22
     'lightcyan'     : '\x1b[1;36m',
23 23
 }
@@ -31,23 +31,13 @@ def colorize(text, start_color, end_color='reset'):
31 31
 
32 32
 class Hunk(object):
33 33
 
34
-    def __init__(self, hunk_header, old_addr, old_offset, new_addr, new_offset):
34
+    def __init__(self, hunk_header):
35 35
         self._hunk_header = hunk_header
36
-        self._old_addr = old_addr
37
-        self._old_offset = old_offset
38
-        self._new_addr = new_addr
39
-        self._new_offset = new_offset
40 36
         self._hunk_list = []   # 2-element group (attr, line)
41 37
 
42 38
     def get_header(self):
43 39
         return self._hunk_header
44 40
 
45
-    def get_old_addr(self):
46
-        return (self._old_addr, self._old_offset)
47
-
48
-    def get_new_addr(self):
49
-        return (self._new_addr, self._new_offset)
50
-
51 41
     def append(self, attr, line):
52 42
         """attr: '-': old, '+': new, ' ': common"""
53 43
         self._hunk_list.append((attr, line))
@@ -117,10 +107,10 @@ class Diff(object):
117 107
                         line = from_info[1].strip('\x00\x01')
118 108
                         out.append(self._markup_old(line))
119 109
                     else:
120
-                        out.append(self._markup_old('-' +
121
-                            self._markup_old_mix(from_info[1])))
122
-                        out.append(self._markup_new('+' +
123
-                            self._markup_new_mix(to_info[1])))
110
+                        out.append(self._markup_old('-') +
111
+                            self._markup_old_mix(from_info[1]))
112
+                        out.append(self._markup_new('+') +
113
+                            self._markup_new_mix(to_info[1]))
124 114
                 else:
125 115
                     out.append(self._markup_common(' ' + from_info[1]))
126 116
         return ''.join(out)
@@ -139,7 +129,7 @@ class Diff(object):
139 129
         return colorize(line, 'yellow')
140 130
 
141 131
     def _markup_hunk_header(self, line):
142
-        return colorize(line, 'blue')
132
+        return colorize(line, 'lightblue')
143 133
 
144 134
     def _markup_common(self, line):
145 135
         return colorize(line, 'reset')
@@ -150,18 +140,20 @@ class Diff(object):
150 140
     def _markup_new(self, line):
151 141
         return colorize(line, 'lightgreen')
152 142
 
153
-    def _markup_mix(self, line, end_color):
154
-        line = line.replace('\x00-', ansi_code('red'))
155
-        line = line.replace('\x00+', ansi_code('green'))
156
-        line = line.replace('\x00^', ansi_code('lightyellow'))
157
-        line = line.replace('\x01', ansi_code(end_color))
158
-        return colorize(line, end_color)
143
+    def _markup_mix(self, line, base_color, del_color, add_color, chg_color):
144
+        line = line.replace('\x00-', ansi_code(del_color))
145
+        line = line.replace('\x00+', ansi_code(add_color))
146
+        line = line.replace('\x00^', ansi_code(chg_color))
147
+        line = line.replace('\x01', ansi_code(base_color))
148
+        return colorize(line, base_color)
159 149
 
160 150
     def _markup_old_mix(self, line):
161
-        return self._markup_mix(line, 'red')
151
+        return self._markup_mix(line, 'cyan', 'lightred', 'lightgreen',
152
+                'yellow')
162 153
 
163 154
     def _markup_new_mix(self, line):
164
-        return self._markup_mix(line, 'green')
155
+        return self._markup_mix(line, 'lightcyan', 'lightred', 'lightgreen',
156
+                'lightyellow')
165 157
 
166 158
 
167 159
 class Udiff(Diff):
@@ -278,21 +270,7 @@ class DiffParser(object):
278 270
                     hunks.append(hunk)
279 271
                     hunk = None
280 272
                 else:
281
-                    # @@ -3,7 +3,6 @@
282
-                    hunk_header = stream.pop(0)
283
-
284
-                    addr_info = hunk_header.split()[1]
285
-                    assert addr_info.startswith('-')
286
-                    old_addr = addr_info.split(',')[0]
287
-                    old_offset = addr_info.split(',')[1]
288
-
289
-                    addr_info = hunk_header.split()[2]
290
-                    assert addr_info.startswith('+')
291
-                    new_addr = addr_info.split(',')[0]
292
-                    new_offset = addr_info.split(',')[1]
293
-
294
-                    hunk = Hunk(hunk_header, old_addr, old_offset, new_addr,
295
-                            new_offset)
273
+                    hunk = Hunk(stream.pop(0))
296 274
 
297 275
             elif Udiff.is_old(stream[0]) or Udiff.is_new(stream[0]) or \
298 276
                     Udiff.is_common(stream[0]):

+ 114
- 143
tests/single.udiff Wyświetl plik

@@ -1,143 +1,114 @@
1
-diff --git a/diffview b/diffview
2
-index 80ff9a2..f92c107 100755
3
---- a/diffview
4
-+++ b/diffview
5
-@@ -2,20 +2,26 @@
6
- 
7
- import sys
8
- import os
9
-+import re
10
- 
11
- 
12
- class Diff(object):
13
- 
14
--    def __init__(self, diff_lines):
15
--        self.__diff_lines = diff_lines
16
--        self.__type = 'udiff'
17
-+    def __init__(self):
18
-+        pass
19
-+
20
-+
21
-+class Udiff(Diff):
22
-+
23
-+    def __init__(self, patch):
24
-+        self.__patch = patch
25
- 
26
-     def view_traditional(self, show_color):
27
-         if show_color:
28
--            for line in self.__diff_lines:
29
-+            for line in self.__patch:
30
-                 sys.stdout.write(self.__colorize(line))
31
-         else:
32
--            for line in self.__diff_lines:
33
-+            for line in self.__patch:
34
-                 sys.stdout.write(line)
35
- 
36
-     def view_side_by_side(self, show_color, show_number, width):
37
-@@ -27,47 +33,79 @@ class Diff(object):
38
-                 'red': '\x1b[31m',
39
-                 'green': '\x1b[32m',
40
-                 'yellow': '\x1b[33m',
41
-+                'blue': '\x1b[34m',
42
-                 'cyan': '\x1b[36m',
43
-                 'none': '\x1b[0m',
44
-+                'lightblue': '\x1b[1;34m',
45
-             }
46
-         return colors.get(start_code, 'none') + text + colors.get(end_code,
47
-                 'none')
48
- 
49
-     def __colorize(self, line):
50
--        if line.startswith('diff ') or line.startswith('--- ') or \
51
--                line.startswith('+++ '):
52
-+        if line.startswith('--- ') or line.startswith('+++ '):
53
-             return self.__mark_color(line, 'yellow')
54
-         elif line.startswith('@@ '):
55
--            return self.__mark_color(line, 'cyan')
56
-+            return self.__mark_color(line, 'lightblue')
57
-         elif line.startswith('-'):
58
-             return self.__mark_color(line, 'red')
59
-         elif line.startswith('+'):
60
-             return self.__mark_color(line, 'green')
61
-+        elif not line.startswith(' '):
62
-+            return self.__mark_color(line, 'cyan')
63
-         else:
64
-             return line
65
- 
66
- 
67
- class DiffParser(object):
68
- 
69
--    def __init__(self, all_diff_lines):
70
--        self.__all_diff_lines = all_diff_lines
71
-+    def __init__(self, patch_set):
72
-+        for line in patch_set[:10]:
73
-+            if line.startswith('--- '):
74
-+                self.__type = 'udiff'
75
-+                break
76
-+        else:
77
-+            raise RuntimeError('unknown diff type')
78
-+
79
-+        self.__patch_set = patch_set
80
- 
81
-     def parse(self):
82
--        diffs = []
83
-+        if self.__type == 'udiff':
84
-+            return self.__parse_udiff()
85
- 
86
--        # parse all diff lines here, construct a Diff object for diff lines of
87
--        # one file one time
88
--        #
89
--        diff_lines = self.__all_diff_lines
90
--        diffs.append(Diff(diff_lines))
91
-+    def __parse_udiff(self):
92
-+        """parse all diff lines here, construct a list of Udiff objects"""
93
-+        diffs = []
94
-+        patch = []
95
-+        saw_diff = False
96
-+
97
-+        while self.__patch_set:
98
-+            line = self.__patch_set[0]
99
-+            if re.match('^[+@ -]', line):
100
-+                # see a diff line
101
-+                saw_diff = True
102
-+                patch.append(self.__patch_set.pop(0))
103
-+            else:
104
-+                # see a header line
105
-+                if saw_diff:
106
-+                    # a header line for new file
107
-+                    diffs.append(Udiff(patch))
108
-+                    patch = []
109
-+                    saw_diff = False
110
-+                else:
111
-+                    # still header line for current file
112
-+                    patch.append(self.__patch_set.pop(0))
113
-+
114
-+        # the last patch
115
-+        if patch:
116
-+            diffs.append(Udiff(patch))
117
- 
118
-         return diffs
119
- 
120
- 
121
- class DiffViewer(object):
122
- 
123
--    def __init__(self, all_diff_lines):
124
--        self.__diffs = DiffParser(all_diff_lines).parse()
125
-+    def __init__(self, patch_set):
126
-+        self.__diffs = DiffParser(patch_set).parse()
127
- 
128
-     def view(self, show_color=True, show_number=False, width=0, traditional=False):
129
-         if traditional:
130
-@@ -130,11 +168,11 @@ if __name__ == '__main__':
131
-     else:
132
-         diff_hdl = sys.stdin
133
- 
134
--    all_diff_lines = diff_hdl.readlines()
135
-+    patch_set = diff_hdl.readlines()
136
-     if diff_hdl != sys.stdin:
137
-         diff_hdl.close()
138
- 
139
--    diffviewer = DiffViewer(all_diff_lines)
140
-+    diffviewer = DiffViewer(patch_set)
141
-     diffviewer.view(show_color=show_color, show_number=opts.number,
142
-             width=opts.width, traditional=opts.traditional)
143
- 
1
+diff --git a/src/cdiff.py b/src/cdiff.py
2
+index 1db7807..c17032f 100755
3
+--- a/src/cdiff.py
4
++++ b/src/cdiff.py
5
+@@ -17,7 +17,7 @@ COLORS = {
6
+     'lightred'      : '\x1b[1;31m',
7
+     'lightgreen'    : '\x1b[1;32m',
8
+     'lightyellow'   : '\x1b[1;33m',
9
+-    'lightblue  '   : '\x1b[1;34m',
10
++    'lightblue'     : '\x1b[1;34m',
11
+     'lightmagenta'  : '\x1b[1;35m',
12
+     'lightcyan'     : '\x1b[1;36m',
13
+ }
14
+@@ -31,23 +31,13 @@ def colorize(text, start_color, end_color='reset'):
15
+ 
16
+ class Hunk(object):
17
+ 
18
+-    def __init__(self, hunk_header, old_addr, old_offset, new_addr, new_offset):
19
++    def __init__(self, hunk_header):
20
+         self._hunk_header = hunk_header
21
+-        self._old_addr = old_addr
22
+-        self._old_offset = old_offset
23
+-        self._new_addr = new_addr
24
+-        self._new_offset = new_offset
25
+         self._hunk_list = []   # 2-element group (attr, line)
26
+ 
27
+     def get_header(self):
28
+         return self._hunk_header
29
+ 
30
+-    def get_old_addr(self):
31
+-        return (self._old_addr, self._old_offset)
32
+-
33
+-    def get_new_addr(self):
34
+-        return (self._new_addr, self._new_offset)
35
+-
36
+     def append(self, attr, line):
37
+         """attr: '-': old, '+': new, ' ': common"""
38
+         self._hunk_list.append((attr, line))
39
+@@ -117,10 +107,10 @@ class Diff(object):
40
+                         line = from_info[1].strip('\x00\x01')
41
+                         out.append(self._markup_old(line))
42
+                     else:
43
+-                        out.append(self._markup_old('-' +
44
+-                            self._markup_old_mix(from_info[1])))
45
+-                        out.append(self._markup_new('+' +
46
+-                            self._markup_new_mix(to_info[1])))
47
++                        out.append(self._markup_old('-') +
48
++                            self._markup_old_mix(from_info[1]))
49
++                        out.append(self._markup_new('+') +
50
++                            self._markup_new_mix(to_info[1]))
51
+                 else:
52
+                     out.append(self._markup_common(' ' + from_info[1]))
53
+         return ''.join(out)
54
+@@ -139,7 +129,7 @@ class Diff(object):
55
+         return colorize(line, 'yellow')
56
+ 
57
+     def _markup_hunk_header(self, line):
58
+-        return colorize(line, 'blue')
59
++        return colorize(line, 'lightblue')
60
+ 
61
+     def _markup_common(self, line):
62
+         return colorize(line, 'reset')
63
+@@ -150,18 +140,20 @@ class Diff(object):
64
+     def _markup_new(self, line):
65
+         return colorize(line, 'lightgreen')
66
+ 
67
+-    def _markup_mix(self, line, end_color):
68
+-        line = line.replace('\x00-', ansi_code('red'))
69
+-        line = line.replace('\x00+', ansi_code('green'))
70
+-        line = line.replace('\x00^', ansi_code('lightyellow'))
71
+-        line = line.replace('\x01', ansi_code(end_color))
72
+-        return colorize(line, end_color)
73
++    def _markup_mix(self, line, base_color, del_color, add_color, chg_color):
74
++        line = line.replace('\x00-', ansi_code(del_color))
75
++        line = line.replace('\x00+', ansi_code(add_color))
76
++        line = line.replace('\x00^', ansi_code(chg_color))
77
++        line = line.replace('\x01', ansi_code(base_color))
78
++        return colorize(line, base_color)
79
+ 
80
+     def _markup_old_mix(self, line):
81
+-        return self._markup_mix(line, 'red')
82
++        return self._markup_mix(line, 'cyan', 'lightred', 'lightgreen',
83
++                'yellow')
84
+ 
85
+     def _markup_new_mix(self, line):
86
+-        return self._markup_mix(line, 'green')
87
++        return self._markup_mix(line, 'lightcyan', 'lightred', 'lightgreen',
88
++                'lightyellow')
89
+ 
90
+ 
91
+ class Udiff(Diff):
92
+@@ -278,21 +270,7 @@ class DiffParser(object):
93
+                     hunks.append(hunk)
94
+                     hunk = None
95
+                 else:
96
+-                    # @@ -3,7 +3,6 @@
97
+-                    hunk_header = stream.pop(0)
98
+-
99
+-                    addr_info = hunk_header.split()[1]
100
+-                    assert addr_info.startswith('-')
101
+-                    old_addr = addr_info.split(',')[0]
102
+-                    old_offset = addr_info.split(',')[1]
103
+-
104
+-                    addr_info = hunk_header.split()[2]
105
+-                    assert addr_info.startswith('+')
106
+-                    new_addr = addr_info.split(',')[0]
107
+-                    new_offset = addr_info.split(',')[1]
108
+-
109
+-                    hunk = Hunk(hunk_header, old_addr, old_offset, new_addr,
110
+-                            new_offset)
111
++                    hunk = Hunk(stream.pop(0))
112
+ 
113
+             elif Udiff.is_old(stream[0]) or Udiff.is_new(stream[0]) or \
114
+                     Udiff.is_common(stream[0]):