Example #1
0
        /// <summary>
        /// Combines one text change with another
        /// </summary>
        public void Combine(TextChange other)
        {
            if (other.IsEmpty)
            {
                return;
            }

            FullParseRequired |= other.FullParseRequired;
            TextChangeType    |= other.TextChangeType;

            if (OldRange == TextRange.EmptyRange || NewRange == TextRange.EmptyRange)
            {
                OldRange        = other.OldRange;
                NewRange        = other.NewRange;
                OldTextProvider = other.OldTextProvider;
                NewTextProvider = other.NewTextProvider;
            }
            else
            {
                ITextSnapshotProvider oldSnapshotProvider      = OldTextProvider as ITextSnapshotProvider;
                ITextSnapshotProvider newSnapshotProvider      = NewTextProvider as ITextSnapshotProvider;
                ITextSnapshotProvider otherOldSnapshotProvider = other.OldTextProvider as ITextSnapshotProvider;
                ITextSnapshotProvider otherNewSnapshotProvider = other.NewTextProvider as ITextSnapshotProvider;
                bool changesAreFromNextSnapshot = false;

                if ((oldSnapshotProvider != null) && (newSnapshotProvider != null) &&
                    (otherOldSnapshotProvider != null) && (otherNewSnapshotProvider != null))
                {
                    ITextSnapshot newSnapshot      = newSnapshotProvider.Snapshot;
                    ITextSnapshot otherOldSnapshot = otherOldSnapshotProvider.Snapshot;
                    if (newSnapshot.Version.ReiteratedVersionNumber == otherOldSnapshot.Version.ReiteratedVersionNumber)
                    {
                        changesAreFromNextSnapshot = true;
                    }
                }

                if (!changesAreFromNextSnapshot)
                {
                    // Assume these changes are from the same snapshot
                    int oldStart = Math.Min(other.OldRange.Start, this.OldRange.Start);
                    int oldEnd   = Math.Max(other.OldRange.End, this.OldRange.End);

                    int newStart = Math.Min(other.NewRange.Start, this.NewRange.Start);
                    int newEnd   = Math.Max(other.NewRange.End, this.NewRange.End);

                    OldRange = TextRange.FromBounds(oldStart, oldEnd);
                    NewRange = TextRange.FromBounds(newStart, newEnd);
                }
                else
                {
                    // the "other" change is from the subsequent snapshot. Merge the changes.
                    ITextSnapshot oldSnapshot      = oldSnapshotProvider.Snapshot;
                    ITextSnapshot newSnapshot      = newSnapshotProvider.Snapshot;
                    ITextSnapshot otherOldSnapshot = otherOldSnapshotProvider.Snapshot;
                    ITextSnapshot otherNewSnapshot = otherNewSnapshotProvider.Snapshot;

                    SnapshotSpan otherOldSpan = other.OldRange.ToSnapshotSpan(otherOldSnapshot);
                    SnapshotSpan oldSpan      = otherOldSpan.TranslateTo(oldSnapshot, SpanTrackingMode.EdgeInclusive);

                    SnapshotSpan newSpan      = NewRange.ToSnapshotSpan(newSnapshot);
                    SnapshotSpan otherNewSpan = newSpan.TranslateTo(otherNewSnapshot, SpanTrackingMode.EdgeInclusive);

                    OldRange        = new TextRange(TextRange.Union(OldRange, oldSpan.ToTextRange()));
                    NewRange        = new TextRange(TextRange.Union(other.NewRange, otherNewSpan.ToTextRange()));
                    NewTextProvider = other.NewTextProvider;
                }
            }

            Version = Math.Max(this.Version, other.Version);
        }