--- a/eric6/UI/DiffDialog.py Fri Oct 09 17:17:21 2020 +0200 +++ b/eric6/UI/DiffDialog.py Fri Oct 09 17:19:29 2020 +0200 @@ -25,175 +25,7 @@ import Utilities import Preferences -from difflib import SequenceMatcher - - -def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', - tofiledate='', n=3, lineterm='\n'): - """ - Compare two sequences of lines; generate the delta as a unified diff. - - Unified diffs are a compact way of showing line changes and a few - lines of context. The number of context lines is set by 'n' which - defaults to three. - - By default, the diff control lines (those with ---, +++, or @@) are - created with a trailing newline. This is helpful so that inputs - created from file.readlines() result in diffs that are suitable for - file.writelines() since both the inputs and outputs have trailing - newlines. - - For inputs that do not have trailing newlines, set the lineterm - argument to "" so that the output will be uniformly newline free. - - The unidiff format normally has a header for filenames and modification - times. Any or all of these may be specified using strings for - 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification - times are normally expressed in the format returned by time.ctime(). - - Example: - - <pre> - >>> for line in unified_diff('one two three four'.split(), - ... 'zero one tree four'.split(), 'Original', 'Current', - ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003', - ... lineterm=''): - ... print line - --- Original Sat Jan 26 23:30:50 1991 - +++ Current Fri Jun 06 10:20:52 2003 - @@ -1,4 +1,4 @@ - +zero - one - -two - -three - +tree - four - </pre> - - @param a first sequence of lines (list of strings) - @param b second sequence of lines (list of strings) - @param fromfile filename of the first file (string) - @param tofile filename of the second file (string) - @param fromfiledate modification time of the first file (string) - @param tofiledate modification time of the second file (string) - @param n number of lines of context (integer) - @param lineterm line termination string (string) - @return a generator yielding lines of differences - """ - started = False - for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n): - if not started: - yield '--- {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) - yield '+++ {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) - started = True - i1 = group[0][1] - i2 = group[-1][2] - j1 = group[0][3] - j2 = group[-1][4] - yield "@@ -{0:d},{1:d} +{2:d},{3:d} @@{4}".format( - i1 + 1, i2 - i1, j1 + 1, j2 - j1, lineterm) - for tag, i1, i2, j1, j2 in group: - if tag == 'equal': - for line in a[i1:i2]: - yield ' ' + line - continue - if tag == 'replace' or tag == 'delete': - for line in a[i1:i2]: - yield '-' + line - if tag == 'replace' or tag == 'insert': - for line in b[j1:j2]: - yield '+' + line - - -def context_diff(a, b, fromfile='', tofile='', - fromfiledate='', tofiledate='', n=3, lineterm='\n'): - r""" - Compare two sequences of lines; generate the delta as a context diff. - - Context diffs are a compact way of showing line changes and a few - lines of context. The number of context lines is set by 'n' which - defaults to three. - - By default, the diff control lines (those with *** or ---) are - created with a trailing newline. This is helpful so that inputs - created from file.readlines() result in diffs that are suitable for - file.writelines() since both the inputs and outputs have trailing - newlines. - - For inputs that do not have trailing newlines, set the lineterm - argument to "" so that the output will be uniformly newline free. - - The context diff format normally has a header for filenames and - modification times. Any or all of these may be specified using - strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. - The modification times are normally expressed in the format returned - by time.ctime(). If not specified, the strings default to blanks. - - Example: - - <pre> - >>> print ''.join( - ... context_diff('one\ntwo\nthree\nfour\n'.splitlines(1), - ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current', - ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')), - *** Original Sat Jan 26 23:30:50 1991 - --- Current Fri Jun 06 10:22:46 2003 - *************** - *** 1,4 **** - one - ! two - ! three - four - --- 1,4 ---- - + zero - one - ! tree - four - </pre> - - @param a first sequence of lines (list of strings) - @param b second sequence of lines (list of strings) - @param fromfile filename of the first file (string) - @param tofile filename of the second file (string) - @param fromfiledate modification time of the first file (string) - @param tofiledate modification time of the second file (string) - @param n number of lines of context (integer) - @param lineterm line termination string (string) - @return a generator yielding lines of differences - """ - started = False - prefixmap = {'insert': '+ ', 'delete': '- ', 'replace': '! ', - 'equal': ' '} - for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n): - if not started: - yield '*** {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) - yield '--- {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) - started = True - - yield '***************{0}'.format(lineterm) - if group[-1][2] - group[0][1] >= 2: - yield '*** {0:d},{1:d} ****{2}'.format( - group[0][1] + 1, group[-1][2], lineterm) - else: - yield '*** {0:d} ****{1}'.format(group[-1][2], lineterm) - visiblechanges = [e for e in group if e[0] in ('replace', 'delete')] - if visiblechanges: - for tag, i1, i2, _, _ in group: - if tag != 'insert': - for line in a[i1:i2]: - yield prefixmap[tag] + line - - if group[-1][4] - group[0][3] >= 2: - yield '--- {0:d},{1:d} ----{2}'.format( - group[0][3] + 1, group[-1][4], lineterm) - else: - yield '--- {0:d} ----{1}'.format(group[-1][4], lineterm) - visiblechanges = [e for e in group if e[0] in ('replace', 'insert')] - if visiblechanges: - for tag, _, _, j1, j2 in group: - if tag != 'delete': - for line in b[j1:j2]: - yield prefixmap[tag] + line +from difflib import unified_diff, context_diff class DiffDialog(QWidget, Ui_DiffDialog):