void RemoveLineSeparatorElements(NormalizedSnapshotSpanCollection spans) {
			if (adornmentLayer == null)
				return;
			for (int i = lineSeparatorElements.Count - 1; i >= 0; i--) {
				var lineSeparatorElement = lineSeparatorElements[i];
				if (spans.IntersectsWith(lineSeparatorElement.Span))
					adornmentLayer.RemoveAdornment(lineSeparatorElement);
			}
		}
        // Produces tags on the snapshot that this tagger is current with.
        private IEnumerable <TagSpan <IntraTextAdornmentTag> > GetAdornmentTagsOnSnapshot(NormalizedSnapshotSpanCollection spans)
        {
            if (spans.Count == 0)
            {
                yield break;
            }

            var snapshot = spans[0].Snapshot;

            System.Diagnostics.Debug.Assert(snapshot == this.snapshot);

            // Since WPF UI objects have state (like mouse hover or animation) and are relatively expensive to create and lay out,
            // this code tries to reuse controls as much as possible.
            // The controls are stored in this.adornmentCache between the calls.

            // Mark which adornments fall inside the requested spans with Keep=false
            // so that they can be removed from the cache if they no longer correspond to data tags.
            var toRemove = new HashSet <SnapshotSpan>();

            foreach (var ar in adornmentCache)
            {
                if (spans.IntersectsWith(new NormalizedSnapshotSpanCollection(ar.Key)))
                {
                    toRemove.Add(ar.Key);
                }
            }

            foreach (var spanDataPair in GetAdornmentData(spans).Distinct(new Comparer()))
            {
                // Look up the corresponding adornment or create one if it's new.
                TAdornment adornment;
                var        snapshotSpan  = spanDataPair.Item1;
                var        affinity      = spanDataPair.Item2;
                var        adornmentData = spanDataPair.Item3;
                if (adornmentCache.TryGetValue(snapshotSpan, out adornment))
                {
                    if (UpdateAdornment(adornment, adornmentData))
                    {
                        toRemove.Remove(snapshotSpan);
                    }
                }
                else
                {
                    adornment = CreateAdornment(adornmentData, snapshotSpan);

                    if (adornment == null)
                    {
                        continue;
                    }

                    // Get the adornment to measure itself. Its DesiredSize property is used to determine
                    // how much space to leave between text for this adornment.
                    // Note: If the size of the adornment changes, the line will be reformatted to accommodate it.
                    // Note: Some adornments may change size when added to the view's visual tree due to inherited
                    // dependency properties that affect layout. Such options can include SnapsToDevicePixels,
                    // UseLayoutRounding, TextRenderingMode, TextHintingMode, and TextFormattingMode. Making sure
                    // that these properties on the adornment match the view's values before calling Measure here
                    // can help avoid the size change and the resulting unnecessary re-format.
                    adornment.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

                    adornmentCache.Add(snapshotSpan, adornment);
                }

                yield return(new TagSpan <IntraTextAdornmentTag>(snapshotSpan, new IntraTextAdornmentTag(adornment, null, affinity)));
            }

            foreach (var snapshotSpan in toRemove)
            {
                adornmentCache.Remove(snapshotSpan);
            }
        }
Exemple #3
0
        public IEnumerable <ITagSpan <IntraTextAdornmentTag> > GetTags(
            NormalizedSnapshotSpanCollection spans
            )
        {
            if (spans.Count == 0)
            {
                return(Array.Empty <ITagSpan <IntraTextAdornmentTag> >());
            }

            var snapshot = spans[0].Snapshot;

            if (_cache.Count == 0 || snapshot != _cacheSnapshot)
            {
                // Calculate UI elements
                _cache.Clear();
                _cacheSnapshot = snapshot;

                var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
                var classify =
                    document?.Project.Solution.Workspace.Options.GetOption(
                        InlineHintsOptions.ColorHints,
                        document?.Project.Language
                        ) ?? false;

                // Calling into the InlineParameterNameHintsDataTaggerProvider which only responds with the current
                // active view and disregards and requests for tags not in that view
                var fullSpan = new SnapshotSpan(snapshot, 0, snapshot.Length);
                var tags     = _tagAggregator.GetTags(new NormalizedSnapshotSpanCollection(fullSpan));
                foreach (var tag in tags)
                {
                    // Gets the associated span from the snapshot span and creates the IntraTextAdornmentTag from the data
                    // tags. Only dealing with the dataTagSpans if the count is 1 because we do not see a multi-buffer case
                    // occuring
                    var dataTagSpans = tag.Span.GetSpans(snapshot);
                    if (dataTagSpans.Count == 1)
                    {
                        var dataTagSpan        = dataTagSpans[0];
                        var parameterHintUITag = InlineHintsTag.Create(
                            tag.Tag.Hint,
                            Format,
                            _textView,
                            dataTagSpan,
                            _taggerProvider,
                            _formatMap,
                            classify
                            );

                        _cache.Add(
                            new TagSpan <IntraTextAdornmentTag>(dataTagSpan, parameterHintUITag)
                            );
                    }
                }
            }

            var selectedSpans = new List <ITagSpan <IntraTextAdornmentTag> >();

            foreach (var tagSpan in _cache)
            {
                if (spans.IntersectsWith(tagSpan.Span))
                {
                    selectedSpans.Add(tagSpan);
                }
            }

            return(selectedSpans);
        }
Exemple #4
0
        private IEnumerable <IMappingTagSpan <T> > GetTagsForBuffer(KeyValuePair <ITextBuffer, IList <ITagger <T> > > bufferAndTaggers,
                                                                    NormalizedSnapshotSpanCollection snapshotSpans,
                                                                    ITextSnapshot root, CancellationToken?cancel)
        {
            ITextSnapshot snapshot = snapshotSpans[0].Snapshot;

            for (int t = 0; t < bufferAndTaggers.Value.Count; ++t)
            {
                ITagger <T> tagger = bufferAndTaggers.Value[t];
                IEnumerator <ITagSpan <T> > tags = null;
                try
                {
                    IEnumerable <ITagSpan <T> > tagEnumerable;

                    if (cancel.HasValue)
                    {
                        cancel.Value.ThrowIfCancellationRequested();

                        var tagger2 = tagger as IAccurateTagger <T>;
                        if (tagger2 != null)
                        {
                            tagEnumerable = tagger2.GetAllTags(snapshotSpans, cancel.Value);
                        }
                        else
                        {
                            tagEnumerable = tagger.GetTags(snapshotSpans);
                        }
                    }
                    else
                    {
                        tagEnumerable = tagger.GetTags(snapshotSpans);
                    }

                    if (tagEnumerable != null)
                    {
                        tags = tagEnumerable.GetEnumerator();
                    }
                }
                catch (OperationCanceledException)
                {
                    // Rethrow cancellation exceptions since we expect our callers to deal with it.
                    throw;
                }
                catch (Exception e)
                {
                    this.TagAggregatorFactoryService.GuardedOperations.HandleException(tagger, e);
                }

                if (tags != null)
                {
                    try
                    {
                        while (true)
                        {
                            ITagSpan <T> tagSpan = null;
                            try
                            {
                                if (tags.MoveNext())
                                {
                                    tagSpan = tags.Current;
                                }
                            }
                            catch (Exception e)
                            {
                                this.TagAggregatorFactoryService.GuardedOperations.HandleException(tagger, e);
                            }

                            if (tagSpan == null)
                            {
                                break;
                            }

                            var snapshotSpan = tagSpan.Span;

                            if (snapshotSpans.IntersectsWith(snapshotSpan.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive)))
                            {
                                yield return(new MappingTagSpan <T>(
                                                 (root == null)
                                    ? this.BufferGraph.CreateMappingSpan(snapshotSpan, SpanTrackingMode.EdgeExclusive)
                                    : MappingSpanSnapshot.Create(root, snapshotSpan, SpanTrackingMode.EdgeExclusive, this.BufferGraph),
                                                 tagSpan.Tag));
                            }
                            else
                            {
#if DEBUG
                                Debug.WriteLine("tagger provided an extra (non-intersecting) tag at " + snapshotSpan + " when queried for tags over " + snapshotSpans);
#endif
                            }
                        }
                    }
                    finally
                    {
                        try
                        {
                            tags.Dispose();
                        }
                        catch (Exception e)
                        {
                            this.TagAggregatorFactoryService.GuardedOperations.HandleException(tagger, e);
                        }
                    }
                }
            }
        }
Exemple #5
0
 private bool IsSuppressed(NormalizedSnapshotSpanCollection suppressedSpans, SnapshotSpan span)
 {
     return(suppressedSpans != null && suppressedSpans.IntersectsWith(span));
 }
		void RemoveMarkerElements(NormalizedSnapshotSpanCollection spans) {
			for (int i = markerElements.Count - 1; i >= 0; i--) {
				var markerElement = markerElements[i];
				if (spans.IntersectsWith(markerElement.Span))
					markerLayer.RemoveAdornment(markerElement);
			}
		}
Exemple #7
0
        public bool ExecuteCommand(InsertAllMatchingCaretsCommandArgs args, CommandExecutionContext executionContext)
        {
            var broker = args.TextView.GetMultiSelectionBroker();

            if (broker.PrimarySelection.IsEmpty)
            {
                broker.TryPerformActionOnSelection(broker.PrimarySelection, PredefinedSelectionTransformations.SelectCurrentWord, out _);
            }

            var navigator = TextSearchNavigatorFactoryService.CreateSearchNavigator(args.TextView.TextViewModel.EditBuffer);

            var    primaryRegion = broker.PrimarySelection;
            string searchString  = primaryRegion.Extent.GetText();

            // Intentionally look at all whitespace here
            if (!string.IsNullOrEmpty(searchString))
            {
                var snapshot     = args.TextView.TextViewModel.EditBuffer.CurrentSnapshot;
                var documentSpan = snapshot.CreateTrackingSpan(0, snapshot.Length, SpanTrackingMode.EdgeInclusive);

                navigator.SearchSpan    = documentSpan;
                navigator.SearchTerm    = searchString;
                navigator.StartPoint    = broker.PrimarySelection.Start.Position;
                navigator.SearchOptions = FindOptions.MatchCase | FindOptions.Multiline | FindOptions.Wrap;

                navigator.Find(); // Get and ignore the primary region

                var newlySelectedSpans = new List <SnapshotSpan>();
                var oldSelectedSpans   = broker.SelectedSpans;

                while (navigator.Find())
                {
                    var found = navigator.CurrentResult.Value;

                    // If we have found the primary region again, we've gone the whole way around the document.
                    if (found.OverlapsWith(primaryRegion.Extent.SnapshotSpan))
                    {
                        break;
                    }

                    if (!oldSelectedSpans.OverlapsWith(found))
                    {
                        newlySelectedSpans.Add(found);
                    }
                }

                // Make sure that none of the newly selected spans overlap
                for (int i = 0; i < (newlySelectedSpans.Count - 1); i++)
                {
                    if (newlySelectedSpans[i].OverlapsWith(newlySelectedSpans[i + 1]))
                    {
                        newlySelectedSpans.RemoveAt(i + 1);

                        // decrement 1 so we can compare i and what used to be i+2 next time
                        i--;
                    }
                }

                var newlySelectedSpanCollection = new NormalizedSnapshotSpanCollection(newlySelectedSpans);

                // Ok, we've figured out what selections we want to add. Now we need to expand any outlining regions before finally adding the selections
                var outliningManager = OutliningManagerService.GetOutliningManager(args.TextView);
                if (outliningManager != null)
                {
                    var extent = new SnapshotSpan(
                        newlySelectedSpanCollection[0].Start,
                        newlySelectedSpanCollection[newlySelectedSpanCollection.Count - 1].End);
                    outliningManager.ExpandAll(extent, collapsible =>
                    {
                        return(newlySelectedSpanCollection.IntersectsWith(collapsible.Extent.GetSpan(broker.CurrentSnapshot)));
                    });
                }

                // Yay, we can finally actually add the selections
                for (int i = 0; i < newlySelectedSpans.Count; i++)
                {
                    broker.AddSelectionRange(newlySelectedSpans.Select(span => new Selection(span, broker.PrimarySelection.IsReversed)));
                }

                return(true);
            }

            return(false);
        }
Exemple #8
0
 /// <summary>
 ///     Determines whether the specified a has intersection.
 /// </summary>
 public static bool HasIntersection(NormalizedSnapshotSpanCollection a, NormalizedSnapshotSpanCollection b)
 {
     return(SafeExecute(() => a.IntersectsWith(b)));
 }