--- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitDiffParser.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitDiffParser.py Wed Jul 13 14:55:47 2022 +0200 @@ -15,26 +15,26 @@ """ Class implementing a class to store and parse diff output. """ - HunkHeaderRegexp = re.compile(r'^@@ -([0-9,]+) \+([0-9,]+) @@(.*)', - re.DOTALL) - + + HunkHeaderRegexp = re.compile(r"^@@ -([0-9,]+) \+([0-9,]+) @@(.*)", re.DOTALL) + def __init__(self, diff): """ Constructor - + @param diff output of the diff command (list of string) """ self.__diff = diff[:] - + self.__headerLines = [] self.__hunks = [] self.__parsed = False # diff parsing is done on demand - + def __initHunk(self): """ Private method to initialize a hunk data structure. - + @return hunk data structure (dictionary) """ hunk = { @@ -48,24 +48,24 @@ "heading": "", } return hunk - + def __parseRange(self, headerRange): """ Private method to parse the hunk header range part. - + @param headerRange hunk header range (string) @return tuple of hunk start and hunk length (integer, integer) """ - if ',' in headerRange: - begin, end = headerRange.split(',', 1) + if "," in headerRange: + begin, end = headerRange.split(",", 1) return int(begin), int(end) else: return int(headerRange), 1 - + def __parseDiff(self): """ Private method to parse the diff output. - + @exception AssertionError raised when a malformed hunk header is encountered """ @@ -76,34 +76,34 @@ self.__headerLines.append(line) else: break - + # step 2: break the rest into diff hunks - for lineIdx, line in enumerate( - self.__diff[len(self.__headerLines):]): + for lineIdx, line in enumerate(self.__diff[len(self.__headerLines) :]): # disect the hunk header line m = self.HunkHeaderRegexp.match(line) if m: self.__hunks.append(self.__initHunk()) self.__hunks[-1]["start"] = lineIdx - (self.__hunks[-1]["oldStart"], - self.__hunks[-1]["oldCount"]) = self.__parseRange( - m.group(1)) - (self.__hunks[-1]["newStart"], - self.__hunks[-1]["newCount"]) = self.__parseRange( - m.group(2)) + ( + self.__hunks[-1]["oldStart"], + self.__hunks[-1]["oldCount"], + ) = self.__parseRange(m.group(1)) + ( + self.__hunks[-1]["newStart"], + self.__hunks[-1]["newCount"], + ) = self.__parseRange(m.group(2)) self.__hunks[-1]["heading"] = m.group(3) elif not self.__hunks: - raise AssertionError("Malformed hunk header: '{0}'" - .format(line)) + raise AssertionError("Malformed hunk header: '{0}'".format(line)) self.__hunks[-1]["lines"].append(line) # step 3: calculate hunk end lines for hunk in self.__hunks: hunk["end"] = hunk["start"] + len(hunk["lines"]) - 1 - + def __generateRange(self, start, count): """ Private method to generate a hunk header range. - + @param start start line (integer) @param count line count (integer) @return hunk header range (string) @@ -112,12 +112,13 @@ return "{0}".format(start) else: return "{0},{1}".format(start, count) - - def __generateHunkHeader(self, oldStart, oldCount, newStart, newCount, - heading=os.linesep): + + def __generateHunkHeader( + self, oldStart, oldCount, newStart, newCount, heading=os.linesep + ): """ Private method to generate a hunk header line. - + @param oldStart start line of the old part (integer) @param oldCount line count of the old part (integer) @param newStart start line of the new part (integer) @@ -128,62 +129,63 @@ return "@@ -{0} +{1} @@{2}".format( self.__generateRange(oldStart, oldCount), self.__generateRange(newStart, newCount), - heading) - + heading, + ) + def headerLength(self): """ Public method to get the header length. - + @return length of the header (integer) """ self.__parseDiff() return len(self.__headerLines) - + def createHunkPatch(self, lineIndex): """ Public method to create a hunk based patch. - + @param lineIndex line number of the hunk (integer) @return diff lines of the patch (string) """ self.__parseDiff() - + patch = self.__headerLines[:] for hunk in self.__hunks: if hunk["start"] <= lineIndex <= hunk["end"]: patch.extend(hunk["lines"]) break - + return "".join(patch) - + def createLinesPatch(self, startIndex, endIndex, reverse=False): """ Public method to create a selected lines based patch. - + @param startIndex start line number (integer) @param endIndex end line number (integer) @param reverse flag indicating a reverse patch (boolean) @return diff lines of the patch (string) """ self.__parseDiff() - + ADDITION = "+" DELETION = "-" CONTEXT = " " NONEWLINE = "\\" - + patch = [] startOffset = 0 - + for hunk in self.__hunks: if hunk["end"] < startIndex: # skip hunks before the selected lines continue - + if hunk["start"] > endIndex: # done, exit the loop break - + counts = { ADDITION: 0, DELETION: 0, @@ -191,37 +193,36 @@ } previousLineSkipped = False processedLines = [] - - for lineIndex, line in enumerate(hunk["lines"][1:], - start=hunk["start"] + 1): + + for lineIndex, line in enumerate( + hunk["lines"][1:], start=hunk["start"] + 1 + ): lineType = line[0] lineContent = line[1:] - + if not (startIndex <= lineIndex <= endIndex): - if ( - (not reverse and lineType == ADDITION) or - (reverse and lineType == DELETION) + if (not reverse and lineType == ADDITION) or ( + reverse and lineType == DELETION ): previousLineSkipped = True continue - - elif ( - (not reverse and lineType == DELETION) or - (reverse and lineType == ADDITION) + + elif (not reverse and lineType == DELETION) or ( + reverse and lineType == ADDITION ): lineType = CONTEXT - + if lineType == NONEWLINE and previousLineSkipped: continue - + processedLines.append(lineType + lineContent) counts[lineType] += 1 previousLineSkipped = False - + # hunks consisting of pure context lines are excluded if counts[ADDITION] == 0 and counts[DELETION] == 0: continue - + oldCount = counts[CONTEXT] + counts[DELETION] newCount = counts[CONTEXT] + counts[ADDITION] oldStart = hunk["oldStart"] @@ -230,14 +231,16 @@ newStart += 1 if newCount == 0: newStart -= 1 - + startOffset += counts[ADDITION] - counts[DELETION] - - patch.append(self.__generateHunkHeader(oldStart, oldCount, - newStart, newCount, - hunk["heading"])) + + patch.append( + self.__generateHunkHeader( + oldStart, oldCount, newStart, newCount, hunk["heading"] + ) + ) patch.extend(processedLines) - + if not patch: return "" else: