예제 #1
0
        internal void ComputeSourceEdits(FrugalList <TextChange> changes)
        {
            ITextEdit xedit = this.group.GetEdit((BaseBuffer)this.sourceBuffer);

            foreach (TextChange change in changes)
            {
                if (change.OldLength > 0)
                {
                    IList <SnapshotSpan> sourceDeletionSpans = this.currentElisionSnapshot.MapToSourceSnapshots(new Span(change.OldPosition, change.OldLength));
                    foreach (SnapshotSpan sourceDeletionSpan in sourceDeletionSpans)
                    {
                        xedit.Delete(sourceDeletionSpan);
                    }
                }
                if (change.NewLength > 0)
                {
                    // change includes an insertion
                    ReadOnlyCollection <SnapshotPoint> sourceInsertionPoints = this.currentElisionSnapshot.MapInsertionPointToSourceSnapshots(change.OldPosition, null);

                    if (sourceInsertionPoints.Count == 1)
                    {
                        // the insertion point is unambiguous
                        xedit.Insert(sourceInsertionPoints[0].Position, change.NewText);
                    }
                    else
                    {
                        // the insertion is at the boundary of source spans
                        int[] insertionSizes = new int[sourceInsertionPoints.Count];

                        if (this.resolver != null)
                        {
                            this.resolver.FillInInsertionSizes(new SnapshotPoint(this.currentElisionSnapshot, change.OldPosition),
                                                               sourceInsertionPoints, change.NewText, insertionSizes);
                        }

                        // if resolver was not provided, we just use zeros for the insertion sizes, which will push the entire insertion
                        // into the last slot.

                        int pos = 0;
                        for (int i = 0; i < insertionSizes.Length; ++i)
                        {
                            // contend with any old garbage that the client passed back.
                            int size = (i == insertionSizes.Length - 1)
                                            ? change.NewLength - pos
                                            : Math.Min(insertionSizes[i], change.NewLength - pos);
                            if (size > 0)
                            {
                                xedit.Insert(sourceInsertionPoints[i].Position, TextChange.ChangeNewSubstring(change, pos, size));
                                pos += size;
                                if (pos == change.NewLength)
                                {
                                    break;  // inserted text is used up, whether we've visited all of the insertionSizes or not
                                }
                            }
                        }
                    }
                }
            }
            this.editApplicationInProgress = true;
        }