single.udiff 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. diff --git a/diffview b/diffview
  2. index 80ff9a2..f92c107 100755
  3. --- a/diffview
  4. +++ b/diffview
  5. @@ -2,20 +2,26 @@
  6. import sys
  7. import os
  8. +import re
  9. class Diff(object):
  10. - def __init__(self, diff_lines):
  11. - self.__diff_lines = diff_lines
  12. - self.__type = 'udiff'
  13. + def __init__(self):
  14. + pass
  15. +
  16. +
  17. +class Udiff(Diff):
  18. +
  19. + def __init__(self, patch):
  20. + self.__patch = patch
  21. def view_traditional(self, show_color):
  22. if show_color:
  23. - for line in self.__diff_lines:
  24. + for line in self.__patch:
  25. sys.stdout.write(self.__colorize(line))
  26. else:
  27. - for line in self.__diff_lines:
  28. + for line in self.__patch:
  29. sys.stdout.write(line)
  30. def view_side_by_side(self, show_color, show_number, width):
  31. @@ -27,47 +33,79 @@ class Diff(object):
  32. 'red': '\x1b[31m',
  33. 'green': '\x1b[32m',
  34. 'yellow': '\x1b[33m',
  35. + 'blue': '\x1b[34m',
  36. 'cyan': '\x1b[36m',
  37. 'none': '\x1b[0m',
  38. + 'lightblue': '\x1b[1;34m',
  39. }
  40. return colors.get(start_code, 'none') + text + colors.get(end_code,
  41. 'none')
  42. def __colorize(self, line):
  43. - if line.startswith('diff ') or line.startswith('--- ') or \
  44. - line.startswith('+++ '):
  45. + if line.startswith('--- ') or line.startswith('+++ '):
  46. return self.__mark_color(line, 'yellow')
  47. elif line.startswith('@@ '):
  48. - return self.__mark_color(line, 'cyan')
  49. + return self.__mark_color(line, 'lightblue')
  50. elif line.startswith('-'):
  51. return self.__mark_color(line, 'red')
  52. elif line.startswith('+'):
  53. return self.__mark_color(line, 'green')
  54. + elif not line.startswith(' '):
  55. + return self.__mark_color(line, 'cyan')
  56. else:
  57. return line
  58. class DiffParser(object):
  59. - def __init__(self, all_diff_lines):
  60. - self.__all_diff_lines = all_diff_lines
  61. + def __init__(self, patch_set):
  62. + for line in patch_set[:10]:
  63. + if line.startswith('--- '):
  64. + self.__type = 'udiff'
  65. + break
  66. + else:
  67. + raise RuntimeError('unknown diff type')
  68. +
  69. + self.__patch_set = patch_set
  70. def parse(self):
  71. - diffs = []
  72. + if self.__type == 'udiff':
  73. + return self.__parse_udiff()
  74. - # parse all diff lines here, construct a Diff object for diff lines of
  75. - # one file one time
  76. - #
  77. - diff_lines = self.__all_diff_lines
  78. - diffs.append(Diff(diff_lines))
  79. + def __parse_udiff(self):
  80. + """parse all diff lines here, construct a list of Udiff objects"""
  81. + diffs = []
  82. + patch = []
  83. + saw_diff = False
  84. +
  85. + while self.__patch_set:
  86. + line = self.__patch_set[0]
  87. + if re.match('^[+@ -]', line):
  88. + # see a diff line
  89. + saw_diff = True
  90. + patch.append(self.__patch_set.pop(0))
  91. + else:
  92. + # see a header line
  93. + if saw_diff:
  94. + # a header line for new file
  95. + diffs.append(Udiff(patch))
  96. + patch = []
  97. + saw_diff = False
  98. + else:
  99. + # still header line for current file
  100. + patch.append(self.__patch_set.pop(0))
  101. +
  102. + # the last patch
  103. + if patch:
  104. + diffs.append(Udiff(patch))
  105. return diffs
  106. class DiffViewer(object):
  107. - def __init__(self, all_diff_lines):
  108. - self.__diffs = DiffParser(all_diff_lines).parse()
  109. + def __init__(self, patch_set):
  110. + self.__diffs = DiffParser(patch_set).parse()
  111. def view(self, show_color=True, show_number=False, width=0, traditional=False):
  112. if traditional:
  113. @@ -130,11 +168,11 @@ if __name__ == '__main__':
  114. else:
  115. diff_hdl = sys.stdin
  116. - all_diff_lines = diff_hdl.readlines()
  117. + patch_set = diff_hdl.readlines()
  118. if diff_hdl != sys.stdin:
  119. diff_hdl.close()
  120. - diffviewer = DiffViewer(all_diff_lines)
  121. + diffviewer = DiffViewer(patch_set)
  122. diffviewer.view(show_color=show_color, show_number=opts.number,
  123. width=opts.width, traditional=opts.traditional)