Exemplo n.º 1
0
        /// <summary>
        /// This handler gets called whenever there is a visual change in the view.
        /// Example: edit or a scroll.
        /// </summary>
        private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
        {
            using (Logger.LogBlock(FunctionId.Tagger_AdornmentManager_OnLayoutChanged, CancellationToken.None))
                using (_asyncListener.BeginAsyncOperation(GetType() + ".OnLayoutChanged"))
                {
                    // Make sure we're on the UI thread.
                    Contract.ThrowIfFalse(_textView.VisualElement.Dispatcher.CheckAccess());

                    var reformattedSpans = e.NewOrReformattedSpans;
                    var viewSnapshot     = _textView.TextSnapshot;

                    // No need to remove tags as these spans are reformatted anyways.
                    UpdateSpans_CallOnlyOnUIThread(reformattedSpans, removeOldTags: false);

                    // Compute any spans that had been invalidated but were not affected by layout.
                    List <IMappingSpan> invalidated;
                    lock (_invalidatedSpansLock)
                    {
                        invalidated       = _invalidatedSpans;
                        _invalidatedSpans = null;
                    }

                    if (invalidated != null)
                    {
                        var invalidatedAndNormalized     = TranslateAndNormalize(invalidated, viewSnapshot);
                        var invalidatedButNotReformatted = NormalizedSnapshotSpanCollection.Difference(
                            invalidatedAndNormalized,
                            e.NewOrReformattedSpans);

                        UpdateSpans_CallOnlyOnUIThread(invalidatedButNotReformatted, removeOldTags: true);
                    }
                }
        }
Exemplo n.º 2
0
        public IEnumerable <ITagSpan <NaturalTextTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            NormalizedSnapshotSpanCollection classifiedSpans = new NormalizedSnapshotSpanCollection(
                spans.SelectMany(span => _aggregator.GetClassificationSpans(span))
                .Select(c => c.Span));

            NormalizedSnapshotSpanCollection plainSpans = NormalizedSnapshotSpanCollection.Difference(spans, classifiedSpans);

            foreach (var span in plainSpans)
            {
                yield return(new TagSpan <NaturalTextTag>(span, new NaturalTextTag()));
            }
        }
            private void UpdateReadOnlyRegions(bool removeOnly = false)
            {
                AssertIsForeground();
                if (!removeOnly && _session.ReplacementText == string.Empty)
                {
                    return;
                }

                using (var readOnlyEdit = _subjectBuffer.CreateReadOnlyRegionEdit())
                {
                    foreach (var oldReadOnlyRegion in _readOnlyRegions)
                    {
                        readOnlyEdit.RemoveReadOnlyRegion(oldReadOnlyRegion);
                    }

                    _readOnlyRegions.Clear();

                    if (!removeOnly)
                    {
                        // We will compute the new read only regions to be all spans that are not currently in an editable span
                        var editableSpans    = GetEditableSpansForSnapshot(_subjectBuffer.CurrentSnapshot);
                        var entireBufferSpan = _subjectBuffer.CurrentSnapshot.GetSnapshotSpanCollection();
                        var newReadOnlySpans = NormalizedSnapshotSpanCollection.Difference(entireBufferSpan, new NormalizedSnapshotSpanCollection(editableSpans));

                        foreach (var newReadOnlySpan in newReadOnlySpans)
                        {
                            _readOnlyRegions.Add(readOnlyEdit.CreateDynamicReadOnlyRegion(newReadOnlySpan, SpanTrackingMode.EdgeExclusive, EdgeInsertionMode.Allow, _isBufferReadOnly));
                        }

                        // The spans we added allow typing at the start and end.  We'll add extra
                        // zero-width read-only regions at the start and end of the file to fix this,
                        // but only if we don't have an identifier at the start or end that _would_ let
                        // them type there.
                        if (editableSpans.All(s => s.Start > 0))
                        {
                            _readOnlyRegions.Add(readOnlyEdit.CreateDynamicReadOnlyRegion(new Span(0, 0), SpanTrackingMode.EdgeExclusive, EdgeInsertionMode.Deny, _isBufferReadOnly));
                        }

                        if (editableSpans.All(s => s.End < _subjectBuffer.CurrentSnapshot.Length))
                        {
                            _readOnlyRegions.Add(readOnlyEdit.CreateDynamicReadOnlyRegion(new Span(_subjectBuffer.CurrentSnapshot.Length, 0), SpanTrackingMode.EdgeExclusive, EdgeInsertionMode.Deny, _isBufferReadOnly));
                        }
                    }

                    readOnlyEdit.Apply();
                }
            }
Exemplo n.º 4
0
        //=====================================================================

        /// <summary>
        /// Get natural language spans for the given dirty span
        /// </summary>
        /// <param name="dirtySpan">The dirty span for which to get natural language spans</param>
        /// <returns>A normalized snapshot span collection containing natural language spans</returns>
        private NormalizedSnapshotSpanCollection GetNaturalLanguageSpansForDirtySpan(SnapshotSpan dirtySpan)
        {
            if (_isClosed || dirtySpan.IsEmpty)
            {
                return(new NormalizedSnapshotSpanCollection());
            }

            ITextSnapshot snapshot = dirtySpan.Snapshot;

            var spans = new NormalizedSnapshotSpanCollection(
                _naturalTextAggregator.GetTags(dirtySpan)
                .SelectMany(tag => tag.Span.GetSpans(snapshot))
                .Select(s => s.Intersection(dirtySpan))
                .Where(s => s.HasValue && !s.Value.IsEmpty)
                .Select(s => s.Value));

            // Now, subtract out IUrlTag spans, since we never want to spell check URLs
            var urlSpans = new NormalizedSnapshotSpanCollection(_urlAggregator.GetTags(spans).SelectMany(
                                                                    tagSpan => tagSpan.Span.GetSpans(snapshot)));

            return(NormalizedSnapshotSpanCollection.Difference(spans, urlSpans));
        }
Exemplo n.º 5
0
 static NormalizedSnapshotSpanCollection SymmetricDifference(NormalizedSnapshotSpanCollection first, NormalizedSnapshotSpanCollection second)
 {
     return(NormalizedSnapshotSpanCollection.Union(
                NormalizedSnapshotSpanCollection.Difference(first, second),
                NormalizedSnapshotSpanCollection.Difference(second, first)));
 }
Exemplo n.º 6
0
        internal IEnumerable <ICollapsible> InternalGetAllRegions(NormalizedSnapshotSpanCollection spans, bool exposedRegionsOnly, CancellationToken?cancel = null)
        {
            EnsureValid(spans);

            // No collapsibles if disabled
            if (!isEnabled || spans.Count == 0)
            {
                return(new List <Collapsible>());
            }

            ITextSnapshot snapshot = spans[0].Snapshot;

            IList <Collapsed> currentCollapsed = GetCollapsedRegionsInternal(spans, exposedRegionsOnly);

            IEnumerable <ICollapsible> newCollapsibles;

            if (!exposedRegionsOnly || currentCollapsed.Count == 0)
            {
                newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(spans, cancel)).Keys;
            }
            else
            {
                NormalizedSnapshotSpanCollection collapsedRegions = new NormalizedSnapshotSpanCollection(currentCollapsed.Select(c => c.Extent.GetSpan(snapshot)));
                NormalizedSnapshotSpanCollection exposed          = NormalizedSnapshotSpanCollection.Difference(spans, collapsedRegions);

                // Ensure there is an empty region on each end
                SnapshotSpan first = spans[0];
                SnapshotSpan last  = spans[spans.Count - 1];
                NormalizedSnapshotSpanCollection ends = new NormalizedSnapshotSpanCollection(new SnapshotSpan[] { new SnapshotSpan(first.Start, 0), new SnapshotSpan(last.End, 0) });
                exposed = NormalizedSnapshotSpanCollection.Union(exposed, ends);

                newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(exposed, cancel)).Keys.Where(c => IsRegionExposed(c, snapshot));
            }

            IEnumerable <ICollapsed> removed;

            var merged = MergeRegions(currentCollapsed, newCollapsibles, out removed);

            // NOTE: IF we have misbehaved taggers, it is possible that we'll see invalid
            // changes here in removed regions that are currently collapsed.  We can deal
            // with this by expanding as needed, but it will cause an event to be sent out, which will
            // likely be unexpected and cause bugs in our clients.

            // There are a few ways we can deal with this:

            // #1: Expand/collapse regions and event
            foreach (var removedRegion in removed)
            {
                Debug.Fail("Removing a region here means a tagger has misbehaved.");
                if (removedRegion.IsCollapsed)
                {
                    Expand(removedRegion);
                }
            }

            // Other options:
            // #2: Return the new regions without doing anything special
            // #3: Return the current collapsed + uncollapsed added regions

            return(merged);
        }