public void Replace(int offset, int length, string text) { Debug.WriteLine("Replace offset=" + offset + " length=" + length + " text.Length=" + text.Length); int lineStart = GetLineNumberForOffset(offset); int oldNumberOfLines = this.TotalNumberOfLines; DeferredEventList deferredEventList = new DeferredEventList(); RemoveInternal(ref deferredEventList, offset, length); int numberOfLinesAfterRemoving = this.TotalNumberOfLines; if (!string.IsNullOrEmpty(text)) { InsertInternal(offset, text); } // #if DEBUG // Console.WriteLine("New line collection:"); // Console.WriteLine(lineCollection.GetTreeAsString()); // Console.WriteLine("New text:"); // Console.WriteLine("'" + document.TextContent + "'"); // #endif // Only fire events after RemoveInternal+InsertInternal finished completely: // Otherwise we would expose inconsistent state to the event handlers. RunHighlighter(lineStart, 1 + Math.Max(0, this.TotalNumberOfLines - numberOfLinesAfterRemoving)); if (deferredEventList.removedLines != null) { foreach (LineSegment ls in deferredEventList.removedLines) { OnLineDeleted(new LineEventArgs(document, ls)); } } deferredEventList.RaiseEvents(); if (this.TotalNumberOfLines != oldNumberOfLines) { OnLineCountChanged(new LineCountChangeEventArgs(document, lineStart, this.TotalNumberOfLines - oldNumberOfLines)); } }