Esempio n. 1
0
 internal static bool Intersects(TextSpan span1, TextSpan span2)
 {
     return(TextSpanHelper.StartsBeforeEndOf(span1, span2) &&
            TextSpanHelper.EndsAfterStartOf(span1, span2));
 }
Esempio n. 2
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);
        }