public void Rebuild() { // keep the first document line DocumentLine ls = documentLineTree.GetByNumber(1); // but mark all other lines as deleted, and detach them from the other nodes for (DocumentLine line = ls.NextLine; line != null; line = line.NextLine) { line.isDeleted = true; line.parent = line.left = line.right = null; } // Reset the first line to detach it from the deleted lines ls.ResetLine(); SimpleSegment ds = NewLineFinder.NextNewLine(document, 0); List <DocumentLine> lines = new List <DocumentLine>(); int lastDelimiterEnd = 0; while (ds != SimpleSegment.Invalid) { ls.TotalLength = ds.Offset + ds.Length - lastDelimiterEnd; ls.DelimiterLength = ds.Length; lastDelimiterEnd = ds.Offset + ds.Length; lines.Add(ls); ls = new DocumentLine(document); ds = NewLineFinder.NextNewLine(document, lastDelimiterEnd); } ls.TotalLength = document.TextLength - lastDelimiterEnd; lines.Add(ls); documentLineTree.RebuildTree(lines); }
public void Insert(int offset, ITextSource text) { DocumentLine line = documentLineTree.GetByOffset(offset); int lineOffset = line.Offset; Debug.Assert(offset <= lineOffset + line.TotalLength); if (offset > lineOffset + line.Length) { Debug.Assert(line.DelimiterLength == 2); // we are inserting in the middle of a delimiter // shorten line SetLineLength(line, line.TotalLength - 1); // add new line line = InsertLineAfter(line, 1); line = SetLineLength(line, 1); } SimpleSegment ds = NewLineFinder.NextNewLine(text, 0); if (ds == SimpleSegment.Invalid) { // no newline is being inserted, all text is inserted in a single line //line.InsertedLinePart(offset - line.Offset, text.Length); SetLineLength(line, line.TotalLength + text.TextLength); return; } int lastDelimiterEnd = 0; while (ds != SimpleSegment.Invalid) { // split line segment at line delimiter int lineBreakOffset = offset + ds.Offset + ds.Length; lineOffset = line.Offset; int lengthAfterInsertionPos = lineOffset + line.TotalLength - (offset + lastDelimiterEnd); line = SetLineLength(line, lineBreakOffset - lineOffset); DocumentLine newLine = InsertLineAfter(line, lengthAfterInsertionPos); newLine = SetLineLength(newLine, lengthAfterInsertionPos); line = newLine; lastDelimiterEnd = ds.Offset + ds.Length; ds = NewLineFinder.NextNewLine(text, lastDelimiterEnd); } // insert rest after last delimiter if (lastDelimiterEnd != text.TextLength) { //line.InsertedLinePart(0, text.Length - lastDelimiterEnd); SetLineLength(line, line.TotalLength + text.TextLength - lastDelimiterEnd); } }