示例#1
0
        void Apply()
        {
            // use original edit spans to update the selection location so that we get the finest
            // granied selection update possible.  It should not be done on merged edits.
            ArrayList edits = this.editList;

            if (this.view != null)
            {
                // Now calculate the updated selection position based on what the edits are going to
                // do to the buffer.
                this.UpdateSelection(edits);
            }
            if (merge)
            {
                // Merge the edits into larger chunks for performance reasons.
                edits = this.MergeEdits(edits);
            }

            // Now apply the edits in reverse order because that one each edit will not interfere with the
            // span of the next edit.
            for (int i = edits.Count - 1; i >= 0; i--)
            {
                EditSpan es   = (EditSpan)edits[i];
                TextSpan span = es.Span;
                string   text = es.Text;
                this.source.SetText(span, text);
            }
            this.editList.Clear(); // done!
        }
示例#2
0
        /// <summary>
        /// Add a new atomic edit to the array.  The edits cannot intersect each other.
        /// The spans in each edit must be based on the current state of the buffer,
        /// and not based on post-edit spans.  This EditArray will calculate the
        /// post edit spans for you.
        /// </summary>
        /// <param name="editSpan"></param>
        internal void Add(EditSpan editSpan)
        {
            if (editSpan == null)
            {
                throw new ArgumentNullException("editSpan");
            }

            for (int i = this.editList.Count - 1; i >= 0; i--)
            {
                EditSpan e = (EditSpan)this.editList[i];
                if (TextSpanHelper.Intersects(editSpan.Span, e.Span))
                {
                    string msg = SR.GetString(SR.EditIntersects, i);
#if LANGTRACE
                    Debug.Assert(false, msg);
                    TraceEdits();
#endif
                    throw new System.ArgumentException(msg);
                }
                if (TextSpanHelper.StartsAfterStartOf(editSpan.Span, e.Span))
                {
                    this.editList.Insert(i + 1, editSpan);
                    return;
                }
            }
            this.editList.Insert(0, editSpan);
        }
示例#3
0
 void AddCombinedEdit(EditSpan combined, StringBuilder buffer, ArrayList merged)
 {
     if (combined != null)
     {
         // add combined edit span.
         combined.Text = buffer.ToString();
         merged.Add(combined);
         buffer.Length = 0;
     }
 }
示例#4
0
        public override string ToString()
        {
            StringBuilder s = new StringBuilder();

            for (int i = this.editList.Count - 1; i >= 0; i--)
            {
                EditSpan e = (EditSpan)this.editList[i];
                s.AppendFormat("({0},{1}:{2},{3})  >>> '{4}'", e.Span.iStartLine, e.Span.iStartIndex, e.Span.iEndLine, e.Span.iEndIndex, GetDebugString(e.Text));
                s.AppendLine();
            }
            return(s.ToString());
        }
示例#5
0
 void TraceEdits()
 {
     for (int j = 0; j < this.editList.Count - 1; j++)
     {
         EditSpan f    = (EditSpan)this.editList[j];
         TextSpan span = f.Span;
         string   t    = this.source.GetText(span);
         Trace.WriteLine(
             string.Format("{0}: {1},{2},{3},{4} '{5}'=>'{6}'",
                           j, span.iStartLine, span.iStartIndex, span.iEndLine, span.iEndIndex,
                           GetDebugString(t), GetDebugString(f.Text)));
     }
 }
示例#6
0
        const int ChunkThreshold = 1000; // don't combine chunks separate by more than 1000 characters.

        ArrayList MergeEdits(ArrayList edits)
        {
            StringBuilder buffer    = new StringBuilder();
            EditSpan      combined  = null;
            ArrayList     merged    = new ArrayList();
            ArrayList     markers   = GetTextMarkers();
            int           markerPos = 0;
            TextSpan      marker    = (markers.Count > 0) ? (TextSpan)markers[0] : new TextSpan();

            foreach (EditSpan editSpan in edits)
            {
                TextSpan span = editSpan.Span;
                string   text = editSpan.Text;

                if (markerPos < markers.Count &&
                    (TextSpanHelper.StartsAfterStartOf(span, marker) || TextSpanHelper.EndsAfterStartOf(span, marker)))
                {
                    AddCombinedEdit(combined, buffer, merged);
                    if (TextSpanHelper.Intersects(span, marker))
                    {
                        combined = null;
                        // Have to apply this as a distinct edit operation.
                        merged.Add(editSpan);
                    }
                    else
                    {
                        combined = editSpan;
                        buffer.Append(text);
                    }
                    while (++markerPos < markers.Count)
                    {
                        marker = (TextSpan)markers[markerPos];
                        if (!TextSpanHelper.StartsAfterStartOf(span, marker) && !TextSpanHelper.EndsAfterStartOf(span, marker))
                        {
                            break;
                        }
                    }
                }
                else if (combined == null)
                {
                    combined = editSpan;
                    buffer.Append(text);
                }
                else
                {
                    // A little sanity check here, if there are too many characters in between the two
                    // edits, then keep them separate.
                    int startOffset = source.GetPositionOfLineIndex(combined.Span.iEndLine, combined.Span.iEndIndex);
                    int endOffset   = source.GetPositionOfLineIndex(span.iStartLine, span.iStartIndex);
                    if (endOffset - startOffset > ChunkThreshold)
                    {
                        AddCombinedEdit(combined, buffer, merged);
                        combined = editSpan;
                        buffer.Append(text);
                    }
                    else
                    {
                        // merge edit spans by adding the text in-between the current and previous spans.
                        TextSpan s       = combined.Span;
                        string   between = this.source.GetText(s.iEndLine, s.iEndIndex, span.iStartLine, span.iStartIndex);
                        buffer.Append(between);
                        buffer.Append(text); // and add the new text.
                        s.iEndIndex   = span.iEndIndex;
                        s.iEndLine    = span.iEndLine;
                        combined.Span = s;
                    }
                }
            }
            AddCombinedEdit(combined, buffer, merged);
            return(merged);
        }
示例#7
0
 void AddCombinedEdit(EditSpan combined, StringBuilder buffer, ArrayList merged)
 {
     if (combined != null) {
         // add combined edit span.
         combined.Text = buffer.ToString();
         merged.Add(combined);
         buffer.Length = 0;
     }
 }
示例#8
0
        /// <include file='doc\EditArray.uex' path='docs/doc[@for="EditArray.Add"]/*' />
        /// <summary>
        /// Add a new atomic edit to the array.  The edits cannot intersect each other.  
        /// The spans in each edit must be based on the current state of the buffer, 
        /// and not based on post-edit spans.  This EditArray will calculate the
        /// post edit spans for you.
        /// </summary>
        /// <param name="editSpan"></param>
        internal void Add(EditSpan editSpan)
        {
            if (editSpan == null) {
                throw new ArgumentNullException("editSpan");
            }

            for (int i = this.editList.Count - 1; i>=0; i--){
                EditSpan e = (EditSpan)this.editList[i];
                if (TextSpanHelper.Intersects(editSpan.Span, e.Span)){
                    string msg = SR.GetString(SR.EditIntersects, i);
            #if LANGTRACE
                    Debug.Assert(false, msg);
                    TraceEdits();
            #endif
                    throw new System.ArgumentException(msg);
                }
                if (TextSpanHelper.StartsAfterStartOf(editSpan.Span, e.Span)) {
                    this.editList.Insert(i + 1, editSpan);
                    return;
                }
            }
            this.editList.Insert(0, editSpan);
        }