/// <summary> /// Source Text constructor /// </summary> public SourceDocument(SourceText text) { Source = text; lines = new SourceLine[1]; lines[0] = new SourceLine(new Position(0, 0), new Position(0, 0)); nlines = 0; lastIndex = -1; ///Add a listener to us. text.Observers += TextChangeObserver; ///Build all lines SourceText.TextChangeInfo info = new SourceText.TextChangeInfo(SourceText.TextChanges.TextReplaced, 0, 0, text.Size); text.Send(info, text); }
/// <summary> /// The Text Change event Observer /// </summary> /// <param name="source"></param> /// <param name="args"></param> private void TextChangeObserver(object source, EventArgs args) { SourceText.TextChangeInfo info = (SourceText.TextChangeInfo)args; switch (info.Kind) { case SourceText.TextChanges.TextReplaced: //Insertion { int from = info.From; int length = info.Size; int index = GetLineIndex(from); SourceLine removeLine = this[index]; int removeFrom = removeLine != null ? removeLine.From : 0; int removeTo = removeLine != null ? removeLine.To : 0; int lastPos = removeFrom; try { List <SourceLine> added = new List <SourceLine>(); IEnumerable <char> s = info.Data == null?this.Source.GetTextAt(from, from + info.Size) : info.Data; bool hasLineFeed = false; int i = -1; foreach (char c in s) { //Check line feed to detect splitted lines i++; if (c == '\n') { int lineFeedPos = from + i + 1; added.Add(new SourceLine(Source.AddPosition(new Position(lastPos, 0)), Source.AddPosition(new Position(lineFeedPos)))); lastPos = lineFeedPos; hasLineFeed = true; } } if (hasLineFeed) { int nremoved = removeLine != null ? 1 : 0; if ((from + length == removeTo) && (lastPos != removeTo) && ((index + 1) < LineCount)) { SourceLine l = this[index + 1]; removeTo = l.To; nremoved++; } if (lastPos < removeTo) { added.Add(new SourceLine(Source.AddPosition(new Position(lastPos, 0)), Source.AddPosition(new Position(removeTo, 0)))); } SourceLine[] added_lines = added.ToArray(); Replace(index, nremoved, added_lines); } } catch (Exception e) { throw e; } } break; case SourceText.TextChanges.TextAboutDeleted: { int from = info.From; int firstLine = GetLineIndex(from); int lastLine = GetLineIndex(info.To); if (firstLine != lastLine) { int nremoved = (lastLine - firstLine) + 1;//Count of line removed int startPos = this[firstLine].From; int endPos = this[lastLine].To; SourceLine[] added_lines = new SourceLine[1]; added_lines[0] = new SourceLine(Source.AddPosition(new Position(startPos, 0)), Source.AddPosition(new Position(endPos, 0))); Replace(firstLine, nremoved, added_lines); } } break; default: break; } }