internal void SetLineLength(DocumentLine line, Int32 lineLength) { line._exactLength = lineLength; _lineTree.UpdateNodeData(line._node); }
internal void Remove(Int32 offset, Int32 length, DocumentUpdate update) { if (offset == 0 && length == _doc.Length) { // 清除后会有空行 update.LineNumberNeedUpdate = 1; if (_lineTree.LineCount > 1) { update.RemovedStartLineNumber = 2; update.RemovedLineCount = _lineTree.LineCount - 1; } // 全删,直接重置 _lineTree.Clear(); return; } DocumentLine line = _lineTree.GetLineByOffset(offset); // 不允许在\r和\n之间删除文本 Int32 lineOffset = line.StartOffset; Int32 lengthAfterDeletion = lineOffset + line._exactLength - offset; if ((line._delimiterLength > 0 && length < lengthAfterDeletion) || (line._delimiterLength == 0 && length <= lengthAfterDeletion)) { update.LineNumberNeedUpdate = line.LineNumber; // 不需要删除行 SetLineLength(line, line._exactLength - length); return; } Int32 removedLineNum = -1, removedLineCnt = 0; DocumentLine firstLine = line; Int32 lengthBeforeDeletion = offset - lineOffset; DocumentLine nextLine = line.NextLine; removedLineNum = line.LineNumber; update.LineNumberNeedUpdate = removedLineNum; if (lengthBeforeDeletion == 0) { ++removedLineCnt; // 当前行需要删除 _lineTree.RemoveLine(line); firstLine = null; } else { ++removedLineNum; SetLineLength(line, line._exactLength - lengthAfterDeletion); line._delimiterLength = 0; } line = nextLine; length -= lengthAfterDeletion; // 删除中间行 while (length > 0) { if (length < line._exactLength) { break; } nextLine = line.NextLine; _lineTree.RemoveLine(line); ++removedLineCnt; length -= line._exactLength; line = nextLine; } if (line != null) { if (firstLine != null) { // 前置行没有删除,则合并这两行 SetLineLength(firstLine, firstLine._exactLength + (line._exactLength - length)); firstLine._delimiterLength = line._delimiterLength; _lineTree.RemoveLine(line); ++removedLineCnt; } else { update.LineNumberNeedUpdate += removedLineCnt; // 没有前置行了,保留该行 SetLineLength(line, line._exactLength - length); } } else { update.LineNumberNeedUpdate = -1; } if (removedLineCnt > 0) { update.RemovedStartLineNumber = removedLineNum; update.RemovedLineCount = removedLineCnt; } }