public void SimpleMerge1() { HighlightedLine baseLine = new HighlightedLine(document, document.GetLineByNumber(1)); baseLine.Sections.Add(MakeSection(0, 1, "B")); HighlightedLine additionalLine = new HighlightedLine(document, document.GetLineByNumber(1)); additionalLine.Sections.Add(MakeSection(0, 2, "A")); baseLine.MergeWith(additionalLine); // The additional section gets split up so that it fits into the tree structure Assert.That(baseLine.Sections, Is.EqualTo( new[] { MakeSection(0, 1, "B"), MakeSection(0, 1, "A"), MakeSection(1, 2, "A") }).Using(new SectionComparer())); }
/// <summary> /// Merges the additional line into this line. /// </summary> public void MergeWith(HighlightedLine additionalLine) { if (additionalLine == null) { return; } #if DEBUG ValidateInvariants(); additionalLine.ValidateInvariants(); #endif var pos = 0; var activeSectionEndOffsets = new Stack <int>(); var lineEndOffset = DocumentLine.EndOffset; activeSectionEndOffsets.Push(lineEndOffset); foreach (var newSection in additionalLine.Sections) { var newSectionStart = newSection.Offset; // Track the existing sections using the stack, up to the point where // we need to insert the first part of the newSection while (pos < Sections.Count) { var s = Sections[pos]; if (newSection.Offset < s.Offset) { break; } while (s.Offset > activeSectionEndOffsets.Peek()) { activeSectionEndOffsets.Pop(); } activeSectionEndOffsets.Push(s.Offset + s.Length); pos++; } // Now insert the new section // Create a copy of the stack so that we can track the sections we traverse // during the insertion process: var insertionStack = new Stack <int>(activeSectionEndOffsets.Reverse()); // The stack enumerator reverses the order of the elements, so we call Reverse() to restore // the original order. int i; for (i = pos; i < Sections.Count; i++) { var s = Sections[i]; if (newSection.Offset + newSection.Length <= s.Offset) { break; } // Insert a segment in front of s: Insert(ref i, ref newSectionStart, s.Offset, newSection.Color, insertionStack); while (s.Offset > insertionStack.Peek()) { insertionStack.Pop(); } insertionStack.Push(s.Offset + s.Length); } Insert(ref i, ref newSectionStart, newSection.Offset + newSection.Length, newSection.Color, insertionStack); } #if DEBUG ValidateInvariants(); #endif }