Пример #1
0
        protected virtual void OnTextChanged(object sender, TextContentChangedEventArgs e)
        {
            TextUtility.CombineChanges(e, out var start, out var oldLength, out var newLength);

            // check if change is still within current snapshot. the problem is that
            // change could have been calculated against projected buffer and then
            // host (HTML editor) could have dropped projections effectively
            // shortening buffer to nothing.

            var snapshot = this.TextBuffer.CurrentSnapshot;

            if (start > snapshot.Length || start + newLength > snapshot.Length)
            {
                start     = 0;
                newLength = snapshot.Length;
            }

            OnTextChanged(start, oldLength, newLength);
        }
Пример #2
0
        protected virtual void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            // In order to provide nicer experience when user presser and holds
            // ENTER or DELETE or just types really fast, we are going to track
            // regions optimistically and report changes without going through
            // async or idle processing. Idle/async is still going to hit later.

            if (e.Changes.Count > 0)
            {
                TextUtility.CombineChanges(e, out var start, out var oldLength, out var newLength);

                var changeStart = int.MaxValue;
                var changeEnd   = 0;

                lock (this._regionsLock)
                {
                    // Remove affected regions and shift the remaining ones. Outlining
                    // regions are not sorted and can overlap. Hence linear search.

                    for (var i = 0; i < this.CurrentRegions.Count; i++)
                    {
                        var region = this.CurrentRegions[i];

                        if (region.End <= start)
                        {
                            continue;
                        }

                        if (region.Contains(start) && region.Contains(start + oldLength))
                        {
                            region.Expand(0, newLength - oldLength);
                        }
                        else if (region.Start >= start + oldLength)
                        {
                            region.Shift(newLength - oldLength);
                        }
                        else
                        {
                            this.CurrentRegions.RemoveAt(i);
                            i--;
                        }

                        changeStart = Math.Min(changeStart, region.Start);
                        changeEnd   = Math.Max(changeEnd, region.End);
                    }

                    if (changeStart < int.MaxValue)
                    {
                        this.CurrentRegions.TextBufferVersion = this.TextBuffer.CurrentSnapshot.Version.VersionNumber;
                    }
                }

                if (changeStart < int.MaxValue)
                {
                    if (this.RegionsChanged != null)
                    {
                        this.RegionsChanged(this, new OutlineRegionsChangedEventArgs(this.CurrentRegions, TextRange.FromBounds(changeStart, changeEnd)));
                    }
                }
            }
        }