AvalonStudio.TextEditor.Document.LineManager.Remove C# (CSharp) Method

Remove() public method

Gets the list of lines deleted since the last RetrieveChangedLines() call. The returned list is unsorted. Gets the list of lines changed since the last RetrieveChangedLines() call. The returned list is sorted by line number and does not contain deleted lines. Gets the list of lines changed since the last RetrieveDeletedOrChangedLines() call. The returned list is not sorted.
public Remove ( int offset, int length ) : void
offset int
length int
return void
		public void Remove(int offset, int length)
		{
			Debug.Assert(length >= 0);
			if (length == 0) return;
			var startLine = documentLineTree.GetByOffset(offset);
			var startLineOffset = startLine.Offset;

			Debug.Assert(offset < startLineOffset + startLine.TotalLength);
			if (offset > startLineOffset + startLine.Length)
			{
				Debug.Assert(startLine.DelimiterLength == 2);
				// we are deleting starting in the middle of a delimiter

				// remove last delimiter part
				SetLineLength(startLine, startLine.TotalLength - 1);
				// remove remaining text
				Remove(offset, length - 1);
				return;
			}

			if (offset + length < startLineOffset + startLine.TotalLength)
			{
				// just removing a part of this line
				//startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, length);
				SetLineLength(startLine, startLine.TotalLength - length);
				return;
			}
			// merge startLine with another line because startLine's delimiter was deleted
			// possibly remove lines in between if multiple delimiters were deleted
			var charactersRemovedInStartLine = startLineOffset + startLine.TotalLength - offset;
			Debug.Assert(charactersRemovedInStartLine > 0);
			//startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, charactersRemovedInStartLine);


			var endLine = documentLineTree.GetByOffset(offset + length);
			if (endLine == startLine)
			{
				// special case: we are removing a part of the last line up to the
				// end of the document
				SetLineLength(startLine, startLine.TotalLength - length);
				return;
			}
			var endLineOffset = endLine.Offset;
			var charactersLeftInEndLine = endLineOffset + endLine.TotalLength - (offset + length);
			//endLine.RemovedLinePart(ref deferredEventList, 0, endLine.TotalLength - charactersLeftInEndLine);
			//startLine.MergedWith(endLine, offset - startLineOffset);

			// remove all lines between startLine (excl.) and endLine (incl.)
			var tmp = startLine.NextLine;
			DocumentLine lineToRemove;
			do
			{
				lineToRemove = tmp;
				tmp = tmp.NextLine;
				RemoveLine(lineToRemove);
			} while (lineToRemove != endLine);

			SetLineLength(startLine, startLine.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
		}

Usage Example

Example #1
0
        private void DoReplace(int offset, int length, ITextSource newText, OffsetChangeMap offsetChangeMap)
        {
            if (length == 0 && newText.TextLength == 0)
            {
                return;
            }

            // trying to replace a single character in 'Normal' mode?
            // for single characters, 'CharacterReplace' mode is equivalent, but more performant
            // (we don't have to touch the anchorTree at all in 'CharacterReplace' mode)
            if (length == 1 && newText.TextLength == 1 && offsetChangeMap == null)
            {
                offsetChangeMap = OffsetChangeMap.Empty;
            }

            ITextSource removedText;

            if (length == 0)
            {
                removedText = StringTextSource.Empty;
            }
            else if (length < 100)
            {
                removedText = new StringTextSource(rope.ToString(offset, length));
            }
            else
            {
                // use a rope if the removed string is long
                removedText = new RopeTextSource(rope.GetRange(offset, length));
            }
            var args = new DocumentChangeEventArgs(offset, removedText, newText, offsetChangeMap);

            // fire DocumentChanging event
            if (Changing != null)
            {
                Changing(this, args);
            }
            if (textChanging != null)
            {
                textChanging(this, args);
            }

            undoStack.Push(this, args);

            cachedText      = null; // reset cache of complete document text
            fireTextChanged = true;
            var delayedEvents = new DelayedEvents();

            lock (lockObject)
            {
                // create linked list of checkpoints
                versionProvider.AppendChange(args);

                // now update the textBuffer and lineTree
                if (offset == 0 && length == rope.Length)
                {
                    // optimize replacing the whole document
                    rope.Clear();
                    var newRopeTextSource = newText as RopeTextSource;
                    if (newRopeTextSource != null)
                    {
                        rope.InsertRange(0, newRopeTextSource.GetRope());
                    }
                    else
                    {
                        rope.InsertText(0, newText.Text);
                    }
                    lineManager.Rebuild();
                }
                else
                {
                    rope.RemoveRange(offset, length);
                    lineManager.Remove(offset, length);
#if DEBUG
                    lineTree.CheckProperties();
#endif
                    var newRopeTextSource = newText as RopeTextSource;
                    if (newRopeTextSource != null)
                    {
                        rope.InsertRange(offset, newRopeTextSource.GetRope());
                    }
                    else
                    {
                        rope.InsertText(offset, newText.Text);
                    }
                    lineManager.Insert(offset, newText);
#if DEBUG
                    lineTree.CheckProperties();
#endif
                }
            }

            // update text anchors
            if (offsetChangeMap == null)
            {
                anchorTree.HandleTextChange(args.CreateSingleChangeMapEntry(), delayedEvents);
            }
            else
            {
                foreach (var entry in offsetChangeMap)
                {
                    anchorTree.HandleTextChange(entry, delayedEvents);
                }
            }

            lineManager.ChangeComplete(args);

            // raise delayed events after our data structures are consistent again
            delayedEvents.RaiseEvents();

            // fire DocumentChanged event
            if (Changed != null)
            {
                Changed(this, args);
            }
            if (textChanged != null)
            {
                textChanged(this, args);
            }
        }