// Update after an insertion. public static unsafe void InsertionUpdate (TextTree tree, TextBuffer buffer, int offset, int length) { // NOTE: this is here to keep the method calls down to // a minimum... technically, this belongs in the // tree, but it's more efficient to do this here, // where we can access the line/node fields // directly // declare the start offset of the insertion line int lineStart; // find the insertion line TextLine line = tree.FindLineByCharOffset (offset, out lineStart); // get the parent of the insertion line TextNode parent = line.Parent; // get the end offset of the insertion line int lineEnd = line.end.Offset; // create a text slice TextSlice slice = new TextSlice(); // get the inserted data into the slice buffer.GetSlice(offset, length, slice); // get the current line start position int currStart = lineStart; // get the current line end position int currEnd = (offset + 1); // set the default new line list TextLine first = null; // set the default previous new line TextLine prev = null; // find and create new lines, quickly fixed(char* start = &slice.chars[slice.start]) { char* curr = start; // get the insertion end position char* end = (curr + slice.length); // find and create new lines while(curr != end) { if(*curr == '\n') { if(currStart == lineStart) { // shorten the insertion line line.end.Move(currEnd); } else { // create a new line TextLine newline = new TextLine (buffer.MarkPosition(currStart, true), buffer.MarkPosition(currEnd, true)); // update list links if(first == null) { // set the current line as the first first = newline; } else { // set the current line's prev newline.prev = prev; // set the previous line's next prev.next = newline; } // set the previous line to the current prev = newline; } // update the current line start position currStart = currEnd; } // increment the current input pointer ++curr; // increment the current line end position ++currEnd; } } // insert new lines and rebalance parent, if needed if(first != null) { // add any remaining characters to new line if(currEnd < lineEnd) { // create a new line TextLine newline = new TextLine (buffer.MarkPosition(currStart, true), buffer.MarkPosition(currEnd, true)); // set the current line's prev reference newline.prev = prev; // set the previous line's next reference prev.next = newline; } // insert the new lines parent.InsertChildren(line, first); // rebalance, starting at the new lines' parent parent.Rebalance(tree); } }