public SplitDiffModel(DiffTextModel sideA, DiffTextModel sideB, List <IAnchorPos> diffAnchors) { SideA = sideA; SideB = sideB; DiffAnchors = diffAnchors; }
public void TestUnifiedDiffParsing_AddedRemoved() { string inputA = "This is a test file!\n" + "Added another line to test file\n" + "Adding a third line to test file"; string inputB = "This is a test file!\n" + "Adding a third line to test file\n" + "Adding a fourth line to test file"; List <Diff.Diff> diff = DiffFactory.GenerateDiffCache(inputA, inputB); DiffTextModel textModel = DiffFactory.GenerateUnifiedDiff(diff); Assert.IsTrue(textModel.LineCount == 5); DiffTextLine removedLine = textModel.GetLine(1) as DiffTextLine; Assert.IsTrue(removedLine.ToString() == "Added another line to test file"); Assert.IsTrue(removedLine.BeforeLineNo == 2); Assert.IsTrue(removedLine.ChangeType == DiffLineType.Remove); DiffTextLine addedLine = textModel.GetLine(3) as DiffTextLine; Assert.IsTrue(addedLine.ToString() == "Adding a third line to test file"); Assert.IsTrue(addedLine.BeforeLineNo == -1); Assert.IsTrue(addedLine.LineNo == 2); Assert.IsTrue(addedLine.ChangeType == DiffLineType.Insert); }
public static SplitDiffModel GenerateSplitDiff(List <Diff> diffs) { // Generate the model List <DiffTextLine> sideABuffer = new List <DiffTextLine>(); List <DiffTextLine> sideBBuffer = new List <DiffTextLine>(); DiffTextModel sideAModel = new DiffTextModel(); DiffTextModel sideBModel = new DiffTextModel(); List <IAnchorPos> diffAnchors = new List <IAnchorPos>(); foreach (Diff d in diffs) { bool hasAddedDiffAnchor = false; foreach (string line in d.text.SplitToLines()) { switch (d.operation) { case Operation.DELETE: { // removed on left DiffTextLine newLine = new DiffTextLine(line, DiffLineType.Remove); sideABuffer.Add(newLine); if (!hasAddedDiffAnchor) { diffAnchors.Add(sideAModel.CreateAnchor(newLine)); hasAddedDiffAnchor = true; } } break; case Operation.EQUAL: { sideABuffer.Add(new DiffTextLine(line, DiffLineType.Unchanged)); sideBBuffer.Add(new DiffTextLine(line, DiffLineType.Unchanged)); } break; case Operation.INSERT: { // added on the right DiffTextLine newLine = new DiffTextLine(line, DiffLineType.Insert); sideBBuffer.Add(newLine); if (!hasAddedDiffAnchor) { diffAnchors.Add(sideBModel.CreateAnchor(newLine)); hasAddedDiffAnchor = true; } } break; } } } int leftLineNo = 1; int rightLineNo = 1; int lineNoCount = Math.Max(sideABuffer.Count, sideBBuffer.Count); DiffTextLine leftLine = null; DiffTextLine rightLine = null; DiffTextLine emptyTextLine = new DiffTextLine("", DiffLineType.Empty); // Make sure we visit every line for (int i = 0; i < lineNoCount; i++) { leftLine = leftLineNo <= sideABuffer.Count ? sideABuffer[leftLineNo - 1] : null; rightLine = rightLineNo <= sideBBuffer.Count ? sideBBuffer[rightLineNo - 1] : null; if (leftLine == null && rightLine != null) { rightLine.LineNo = rightLineNo; sideBModel.InsertLine(rightLine); rightLineNo++; continue; } if (leftLine != null && rightLine == null) { leftLine.LineNo = leftLineNo; sideAModel.InsertLine(leftLine); leftLineNo++; continue; } if (leftLine.ChangeType == DiffLineType.Unchanged && rightLine.ChangeType == DiffLineType.Unchanged) { leftLine.LineNo = leftLineNo; rightLine.LineNo = rightLineNo; // easymode: unchanged lines sideAModel.InsertLine(leftLine); sideBModel.InsertLine(rightLine); leftLineNo++; rightLineNo++; } else if (leftLine.ChangeType == DiffLineType.Remove && rightLine.ChangeType == DiffLineType.Insert) { leftLine.LineNo = leftLineNo; rightLine.LineNo = rightLineNo; // removed left, added right, so it's 1-to-1 sideAModel.InsertLine(leftLine); sideBModel.InsertLine(rightLine); leftLineNo++; rightLineNo++; } else if (leftLine.ChangeType == DiffLineType.Remove && rightLine.ChangeType == DiffLineType.Unchanged) { leftLine.LineNo = leftLineNo; // removed on left, but wasn't replaced with anything on right sideAModel.InsertLine(leftLine); sideBModel.InsertLine(emptyTextLine); leftLineNo++; // only advance the left line counter because empty lines don't count } else if (leftLine.ChangeType == DiffLineType.Unchanged && rightLine.ChangeType == DiffLineType.Insert) { rightLine.LineNo = rightLineNo; // added on right, but didn't have existing change on left sideAModel.InsertLine(emptyTextLine); sideBModel.InsertLine(rightLine); rightLineNo++; // only advance the right line counter because empty lines don't count } } return(new SplitDiffModel(sideAModel, sideBModel, diffAnchors)); }