Пример #1
0
        private void SourceBuffersChanged(object sender, ProjectionSourceBuffersChangedEventArgs e)
        {
            IProjectionBufferBase    projBuffer              = (IProjectionBufferBase)sender;
            FrugalList <ITextBuffer> addedToGraphBuffers     = new FrugalList <ITextBuffer>();
            FrugalList <ITextBuffer> removedFromGraphBuffers = new FrugalList <ITextBuffer>();

            foreach (ITextBuffer addedBuffer in e.AddedBuffers)
            {
                AddSourceBuffer(projBuffer, addedBuffer, addedToGraphBuffers);
            }

            foreach (ITextBuffer removedBuffer in e.RemovedBuffers)
            {
                RemoveSourceBuffer(projBuffer, removedBuffer, removedFromGraphBuffers);
            }

            if (addedToGraphBuffers.Count > 0 || removedFromGraphBuffers.Count > 0)
            {
                var listeners = GraphBuffersChanged;
                if (listeners != null)
                {
                    ((BaseBuffer)projBuffer).group.EnqueueEvents
                        (new GraphEventRaiser(this, new GraphBuffersChangedEventArgs(addedToGraphBuffers, removedFromGraphBuffers)), null);
                }
            }
        }
Пример #2
0
        public ElisionMap EditSpans(ITextSnapshot sourceSnapshot,
                                    NormalizedSpanCollection spansToElide,
                                    NormalizedSpanCollection spansToExpand,
                                    out FrugalList <TextChange> textChanges)
        {
            textChanges = new FrugalList <TextChange>();
            NormalizedSpanCollection beforeSourceSpans = new NormalizedSnapshotSpanCollection(GetSourceSpans(sourceSnapshot, 0, this.spanCount));

            NormalizedSpanCollection afterElisionSourceSpans = NormalizedSpanCollection.Difference(beforeSourceSpans, spansToElide);
            NormalizedSpanCollection elisionChangeSpans      = NormalizedSpanCollection.Difference(beforeSourceSpans, afterElisionSourceSpans);

            foreach (Span s in elisionChangeSpans)
            {
                textChanges.Add(new TextChange(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                               new ReferenceChangeString(new SnapshotSpan(sourceSnapshot, s)),
                                               ChangeString.EmptyChangeString,
                                               sourceSnapshot));
            }

            NormalizedSpanCollection afterExpansionSourceSpans = NormalizedSpanCollection.Union(afterElisionSourceSpans, spansToExpand);
            NormalizedSpanCollection expansionChangeSpans      = NormalizedSpanCollection.Difference(afterExpansionSourceSpans, afterElisionSourceSpans);

            foreach (Span s in expansionChangeSpans)
            {
                textChanges.Add(new TextChange(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                               ChangeString.EmptyChangeString,
                                               new ReferenceChangeString(new SnapshotSpan(sourceSnapshot, s)),
                                               sourceSnapshot));
            }

            return(textChanges.Count > 0 ? new ElisionMap(sourceSnapshot, afterExpansionSourceSpans) : this);
        }
Пример #3
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;
        }
Пример #4
0
        public BufferGraph(ITextBuffer topBuffer, GuardedOperations guardedOperations)
        {
            if (topBuffer == null)
            {
                throw new ArgumentNullException("topBuffer");
            }
            if (guardedOperations == null)
            {
                throw new ArgumentNullException("guardedOperations");
            }

            this.topBuffer         = topBuffer;
            this.guardedOperations = guardedOperations;

            this.importingProjectionBufferMap.Add(topBuffer, null);
            // The top buffer has no targets, but it is put here so membership in this map can be used uniformly
            // to determine whether a buffer is in the buffer graph

            // Subscribe to content type changed events on the toplevel buffer
            this.eventHooks.Add(new WeakEventHookForBufferGraph(this, topBuffer));

            IProjectionBufferBase projectionBufferBase = topBuffer as IProjectionBufferBase;

            if (projectionBufferBase != null)
            {
                IList <ITextBuffer>      sourceBuffers = projectionBufferBase.SourceBuffers;
                FrugalList <ITextBuffer> dontCare      = new FrugalList <ITextBuffer>();
                foreach (ITextBuffer sourceBuffer in sourceBuffers)
                {
                    AddSourceBuffer(projectionBufferBase, sourceBuffer, dontCare);
                }
            }
        }
Пример #5
0
        private async Task <(IList <object> items, IList <ITrackingSpan> applicableToSpans)> ComputeContentAsync(
            IEnumerable <OrderedSource> unorderedSources,
            IList <Exception> failures,
            CancellationToken cancellationToken)
        {
            // Ensure we're off the UI thread.
            await TaskScheduler.Default;

            cancellationToken.ThrowIfCancellationRequested();

            var items             = new FrugalList <object>();
            var applicableToSpans = new FrugalList <ITrackingSpan>();

            // Sources from the cache are from the flattened projection buffer graph
            // so they're initially out of order. We recorded their MEF ordering in
            // a property though so we can reorder them now.
            foreach (var source in unorderedSources.OrderBy(source => source.Order))
            {
                // This code is sequential to enable back-compat with the IQuickInfo* APIs,
                // but when the shims are removed, consider parallelizing as a potential optimization.
                await this.ComputeSourceContentAsync(
                    source.Source,
                    items,
                    applicableToSpans,
                    failures,
                    cancellationToken).ConfigureAwait(false);
            }

            return(items, applicableToSpans);
        }
Пример #6
0
        public FrugalList <SnapshotPoint> MapInsertionPointToSourceSnapshots(IElisionSnapshot elisionSnapshot, int exposedPosition)
        {
            FrugalList <SnapshotPoint> points = new FrugalList <SnapshotPoint>();

            this.root.MapInsertionPointToSourceSnapshots(elisionSnapshot, exposedPosition, 0, points);
            return(points);
        }
            public IEnumerable <TSource> GetSources(IEnumerable <ITextBuffer> buffers)
            {
                if (_textView.IsClosed)
                {
                    Debug.Fail("Intellisense is trying to operate after its view has been closed.");
                    return(Enumerable.Empty <TSource>());
                }

                // For each buffer that should be involved, either return the cached source for that buffer, or create a source and
                // cache it for later use.
                IList <TSource> sources = new FrugalList <TSource>();

                foreach (var buffer in buffers)
                {
                    var bufferSources = (IReadOnlyCollection <TSource>)_bufferCache[buffer];

                    if (bufferSources == null)
                    {
                        bufferSources = _sourceCreator(buffer);
                        _bufferCache.Add(buffer, bufferSources);

                        buffer.ContentTypeChanged += OnContentTypeChanged;
                    }

                    foreach (var source in bufferSources)
                    {
                        sources.Add(source);
                    }
                }

                return(sources);
            }
Пример #8
0
        private async Task <IList <Exception> > ComputeContentAndUpdateAsync(QuickInfoSessionState initialState, bool allowUpdate, CancellationToken cancellationToken)
        {
            IntellisenseUtilities.ThrowIfNotOnMainThread(this.JoinableTaskContext);

            // Alert subscribers on the UI thread.
            this.TransitionTo(QuickInfoSessionState.Calculating, allowUpdate);

            cancellationToken.ThrowIfCancellationRequested();

            var failures = new FrugalList <Exception>();

            // Find and create the sources. Sources cache is smart enough to
            // invalidate on content-type changed and free on view close.
            var sources = this.GetOrCreateSources(failures);

            // Compute quick info items. This method switches off the UI thread.
            // From here on out we're on an arbitrary thread.
            (IList <object> items, IList <ITrackingSpan> applicableToSpans)? results
                = await ComputeContentAsync(sources, failures, cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();

            // Update our content, or put the empty list if there is none.
            Volatile.Write(
                ref this.content,
                results != null ? ImmutableList.CreateRange(results.Value.items) : ImmutableList <object> .Empty);

            await StartUIThreadEpilogueAsync(initialState, results?.applicableToSpans, cancellationToken).ConfigureAwait(false);

            return(failures);
        }
Пример #9
0
        public ElisionMap EditSpans(ITextSnapshot sourceSnapshot,
                                    NormalizedSpanCollection spansToElide,
                                    NormalizedSpanCollection spansToExpand,
                                    out FrugalList <TextChange> textChanges)
        {
            textChanges = new FrugalList <TextChange>();
            NormalizedSpanCollection beforeSourceSpans = new NormalizedSnapshotSpanCollection(GetSourceSpans(sourceSnapshot, 0, this.spanCount));

            NormalizedSpanCollection afterElisionSourceSpans = NormalizedSpanCollection.Difference(beforeSourceSpans, spansToElide);
            NormalizedSpanCollection elisionChangeSpans      = NormalizedSpanCollection.Difference(beforeSourceSpans, afterElisionSourceSpans);

            foreach (Span s in elisionChangeSpans)
            {
                textChanges.Add(TextChange.Create(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                                  BufferFactoryService.StringRebuilderFromSnapshotAndSpan(sourceSnapshot, s),
                                                  StringRebuilder.Empty,
                                                  sourceSnapshot));
            }

            NormalizedSpanCollection afterExpansionSourceSpans = NormalizedSpanCollection.Union(afterElisionSourceSpans, spansToExpand);
            NormalizedSpanCollection expansionChangeSpans      = NormalizedSpanCollection.Difference(afterExpansionSourceSpans, afterElisionSourceSpans);

            foreach (Span s in expansionChangeSpans)
            {
                textChanges.Add(TextChange.Create(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                                  StringRebuilder.Empty,
                                                  BufferFactoryService.StringRebuilderFromSnapshotAndSpan(sourceSnapshot, s),
                                                  sourceSnapshot));
            }

            return(textChanges.Count > 0 ? new ElisionMap(sourceSnapshot, afterExpansionSourceSpans) : this);
        }
Пример #10
0
        private SnapshotPoint?MapUpToBufferGuts(SnapshotPoint currentPoint, PositionAffinity affinity, Predicate <ITextSnapshot> match)
        {
            if (match(currentPoint.Snapshot))
            {
                return(currentPoint);
            }
            FrugalList <IProjectionBufferBase> targetBuffers = this.importingProjectionBufferMap[currentPoint.Snapshot.TextBuffer];

            if (targetBuffers != null)  // targetBuffers will be null if we fell off the top
            {
                foreach (IProjectionBufferBase projBuffer in targetBuffers)
                {
                    SnapshotPoint?position = projBuffer.CurrentSnapshot.MapFromSourceSnapshot(currentPoint, affinity);
                    if (position.HasValue)
                    {
                        position = MapUpToBufferGuts(position.Value, affinity, match);
                        if (position.HasValue)
                        {
                            return(position);
                        }
                    }
                }
            }
            return(null);
        }
Пример #11
0
        private IEnumerable <IMappingTagSpan <T> > InternalGetTags(NormalizedSnapshotSpanCollection snapshotSpans, CancellationToken?cancel)
        {
            ITextSnapshot targetSnapshot = snapshotSpans[0].Snapshot;

            bool mapByContentType = (options & TagAggregatorOptions.MapByContentType) != 0;

            foreach (var bufferAndTaggers in taggers)
            {
                if (bufferAndTaggers.Value.Count > 0)
                {
                    FrugalList <SnapshotSpan> targetSpans = new FrugalList <SnapshotSpan>();
                    for (int s = 0; s < snapshotSpans.Count; ++s)
                    {
                        MappingHelper.MapDownToBufferNoTrack(snapshotSpans[s], bufferAndTaggers.Key, targetSpans, mapByContentType);
                    }

                    if (targetSpans.Count > 0)
                    {
                        NormalizedSnapshotSpanCollection targetSpanCollection =
                            new NormalizedSnapshotSpanCollection(targetSpans);

                        foreach (var tagSpan in this.GetTagsForBuffer(bufferAndTaggers, targetSpanCollection, targetSnapshot, cancel))
                        {
                            yield return(tagSpan);
                        }
                    }
                }
            }
        }
Пример #12
0
        private void AddSourceBuffer(IProjectionBufferBase projBuffer, ITextBuffer sourceBuffer, FrugalList <ITextBuffer> addedToGraphBuffers)
        {
            bool firstEncounter = false;
            FrugalList <IProjectionBufferBase> importingProjectionBuffers;

            if (!this.importingProjectionBufferMap.TryGetValue(sourceBuffer, out importingProjectionBuffers))
            {
                // sourceBuffer is new to this buffer graph
                addedToGraphBuffers.Add(sourceBuffer);
                firstEncounter = true;

                importingProjectionBuffers = new FrugalList <IProjectionBufferBase>();
                this.importingProjectionBufferMap.Add(sourceBuffer, importingProjectionBuffers);

                this.eventHooks.Add(new WeakEventHookForBufferGraph(this, sourceBuffer));
            }
            importingProjectionBuffers.Add(projBuffer);

            if (firstEncounter)
            {
                IProjectionBufferBase addedProjBufferBase = sourceBuffer as IProjectionBufferBase;
                if (addedProjBufferBase != null)
                {
                    foreach (ITextBuffer furtherSourceBuffer in addedProjBufferBase.SourceBuffers)
                    {
                        AddSourceBuffer(addedProjBufferBase, furtherSourceBuffer, addedToGraphBuffers);
                    }
                }
            }
        }
Пример #13
0
        public void AddOne()
        {
            var list = new FrugalList <int>();

            list.Add(42);
            AssertList(list, 42);
        }
Пример #14
0
        public void AddTwo()
        {
            var list = new FrugalList <int>();

            list.Add(1);
            list.Add(2);
            AssertList(list, 1, 2);
        }
        internal void AddBaseType(IClassificationType baseType)
        {
            if (this.baseTypes == null)
            {
                this.baseTypes = new FrugalList <IClassificationType>();
            }

            this.baseTypes.Add(baseType);
        }
Пример #16
0
        public IList <SnapshotSpan> GetSourceSpans(ITextSnapshot sourceSnapshot, int startSpanIndex, int count)
        {
            FrugalList <SnapshotSpan> result = new FrugalList <SnapshotSpan>();
            int rank             = -1;
            int sourcePrefixSize = 0;

            this.root.GetSourceSpans(sourceSnapshot, ref rank, ref sourcePrefixSize, startSpanIndex, startSpanIndex + count, result);
            return(result);
        }
Пример #17
0
        public static bool CanMapDownToBuffer(ITextView textView, ITextBuffer textBuffer, ITrackingPoint triggerPoint)
        {
            SnapshotPoint triggerSnapshotPoint = triggerPoint.GetPoint(textView.TextSnapshot);
            var           triggerSpan          = new SnapshotSpan(triggerSnapshotPoint, 0);

            var mappedSpans = new FrugalList <SnapshotSpan>();

            MappingHelper.MapDownToBufferNoTrack(triggerSpan, textBuffer, mappedSpans);
            return(mappedSpans.Count > 0);
        }
Пример #18
0
        public override ReadOnlyCollection <Span> MapFromSourceSnapshot(SnapshotSpan span)
        {
            if (span.Snapshot != this.sourceSnapshot)
            {
                throw new ArgumentException("The span does not belong to a source snapshot of the projection snapshot");
            }
            FrugalList <Span> result = new FrugalList <Span>();

            this.content.MapFromSourceSnapshot(span, result);
            return(new ReadOnlyCollection <Span>(result));
        }
Пример #19
0
 public void MapFromSourceSnapshot(Span span, FrugalList <Span> result)
 {
     if (span.Length == 0)
     {
         this.root.MapNullSpanFromSourceSnapshot(span, 0, result);
     }
     else
     {
         this.root.MapFromSourceSnapshot(span, 0, result);
     }
 }
Пример #20
0
 protected Edit(BaseBuffer baseBuffer, ITextSnapshot originSnapshot, EditOptions options, int?reiteratedVersionNumber, Object editTag)
     : base(baseBuffer, originSnapshot, editTag)
 {
     this.bufferLength            = originSnapshot.Length;
     this.changes                 = new FrugalList <TextChange>();
     this.options                 = options;
     this.reiteratedVersionNumber = reiteratedVersionNumber;
     this.raisedChangingEventArgs = null;
     this.cancelAction            = null;
     this.hasFailedChanges        = false;
 }
Пример #21
0
        public void AddMany()
        {
            var list  = new FrugalList <int>();
            var range = Enumerable.Range(0, 5);

            foreach (var cur in range)
            {
                list.Add(cur);
            }
            AssertList(list, range.ToArray());
        }
Пример #22
0
        private ITextEventRaiser ApplyChangesAndSetSnapshot(FrugalList <TextChange> changes, EditOptions options, int?reiteratedVersionNumber, object editTag)
        {
            INormalizedTextChangeCollection normalizedChanges = NormalizedTextChangeCollection.Create(changes,
                                                                                                      options.ComputeMinimalChange ? (StringDifferenceOptions?)options.DifferenceOptions : null,
                                                                                                      this.textDifferencingService);
            ITextSnapshot originSnapshot = base.CurrentSnapshot;

            base.SetCurrentVersionAndSnapshot(normalizedChanges, reiteratedVersionNumber ?? -1);

            return(new TextContentChangedEventRaiser(originSnapshot, this.CurrentSnapshot, options, editTag));
        }
Пример #23
0
        // Add the range of line numbers on snapshot whose leading whitespace might be affected by a change to span.
        private static void AddWhitespaceLines(ref FrugalList <Span> whitespaceLines, ITextSnapshot snapshot, Span span)
        {
            var startLine = snapshot.GetLineFromPosition(span.Start);
            var endLine   = (span.End < startLine.EndIncludingLineBreak) ? startLine : snapshot.GetLineFromPosition(span.End);

            // Changes that don't start at the beginning of a line can't affect the starting character of that line.
            int startLineNumber = (span.Start == startLine.Start) ? startLine.LineNumber : (startLine.LineNumber + 1);
            int endLineNumber   = endLine.LineNumber + 1;

            AddSpanToLines(ref whitespaceLines, startLineNumber, endLineNumber);
        }
Пример #24
0
        private static void AddSpanToLines(ref FrugalList <Span> lines, int startLineNumber, int endLineNumber)
        {
            if (startLineNumber != endLineNumber)
            {
                if (lines == null)
                {
                    lines = new FrugalList <Span>();
                }

                lines.Add(Span.FromBounds(startLineNumber, endLineNumber));
            }
        }
Пример #25
0
        public void AddExhaustive()
        {
            const int count = 20;
            var       list  = new FrugalList <int>();
            var       range = Enumerable.Range(0, count).ToArray();

            for (int i = 0; i < range.Length; i++)
            {
                list.Add(range[i]);
                AssertList(list, Enumerable.Range(0, i + 1).ToArray());
            }
        }
Пример #26
0
        // Add the range of line numbers on snapshot whose line endings might be affected by a change to span.
        private static void AddLineBreakLines(ref FrugalList <Span> lineBreakLines, ITextSnapshot snapshot, Span span)
        {
            var startLine = snapshot.GetLineFromPosition(span.Start);
            var endLine   = (span.End < startLine.EndIncludingLineBreak) ? startLine : snapshot.GetLineFromPosition(span.End);

            // Extend the range if the span starts at the start of a line (since it could affect the line break of the previous line)
            // or touches the line break at the end of the line).
            int startLineNumber = ((span.Start == startLine.Start) && (span.Start != 0)) ? (startLine.LineNumber - 1) : startLine.LineNumber;
            int endLineNumber   = (span.End < endLine.End) ? endLine.LineNumber : (endLine.LineNumber + 1);

            AddSpanToLines(ref lineBreakLines, startLineNumber, endLineNumber);
        }
Пример #27
0
        public ElisionMap IncorporateChanges(INormalizedTextChangeCollection sourceChanges,
                                             FrugalList <TextChange> projectedChanges,
                                             ITextSnapshot beforeSourceSnapshot,
                                             ITextSnapshot sourceSnapshot,
                                             ITextSnapshot beforeElisionSnapshot)
        {
            ElisionMapNode newRoot = this.root;
            int            accumulatedProjectedDelta = 0;

            foreach (ITextChange sourceChange in sourceChanges)
            {
                int          accumulatedDelete = 0;
                int          incrementalAccumulatedProjectedDelta = 0;
                ChangeString newText;
                TextChange   concreteSourceChange = sourceChange as TextChange;
                if (concreteSourceChange != null)
                {
                    newText = concreteSourceChange._newText;
                }
                else
                {
                    // handle mocks in tests
                    newText = new LiteralChangeString(sourceChange.NewText);
                }
                newRoot = newRoot.IncorporateChange(beforeSourceSnapshot: beforeSourceSnapshot,
                                                    afterSourceSnapshot: sourceSnapshot,
                                                    beforeElisionSnapshot: beforeElisionSnapshot,
                                                    sourceInsertionPosition: sourceChange.NewLength > 0 ? sourceChange.NewPosition : (int?)null,
                                                    newText: newText,
                                                    sourceDeletionSpan: new Span(sourceChange.NewPosition, sourceChange.OldLength),
                                                    absoluteSourceOldPosition: sourceChange.OldPosition,
                                                    absoluteSourceNewPosition: sourceChange.NewPosition,
                                                    projectedPrefixSize: 0,
                                                    projectedChanges: projectedChanges,
                                                    incomingAccumulatedDelta: accumulatedProjectedDelta,
                                                    outgoingAccumulatedDelta: ref incrementalAccumulatedProjectedDelta,
                                                    accumulatedDelete: ref accumulatedDelete);
                accumulatedProjectedDelta += incrementalAccumulatedProjectedDelta;
            }
            if (newRoot.TotalSourceSize != sourceSnapshot.Length)
            {
                Debug.Fail(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                         "Change incorporation length inconsistency. Elision:{0} Source:{1}", newRoot.TotalSourceSize, sourceSnapshot.Length));
                throw new InvalidOperationException(Strings.InvalidLengthCalculation);
            }
            if (newRoot.TotalSourceLineBreakCount + 1 != sourceSnapshot.LineCount)
            {
                Debug.Fail(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                         "Change incorporation line count inconsistency. Elision:{0} Source:{1}", newRoot.TotalSourceLineBreakCount + 1, sourceSnapshot.LineCount));
                throw new InvalidOperationException(Strings.InvalidLineCountCalculation);
            }
            return(new ElisionMap(newRoot, this.spanCount));
        }
Пример #28
0
        public void SubjectBuffersConnected(
            ITextView textView,
            ConnectionReason reason,
            IReadOnlyCollection <ITextBuffer> subjectBuffers)
        {
            IntellisenseManager manager = textView.Properties.GetOrCreateSingletonProperty(
                delegate { return(new IntellisenseManager(this, textView)); });

            // Create the appropriate Intellisense controllers for the content types in the buffer graph. It's important that we do
            // this after creating the brokers, as the controllers will most likely start using the brokers immediately.

            for (int f = 0; f < this.IntellisenseControllerFactories.Count; ++f)
            {
                var factory = this.IntellisenseControllerFactories[f];

                // filter subject buffers to get the ones that match the factory content types
                FrugalList <ITextBuffer> matchingSubjectBuffers = new FrugalList <ITextBuffer>();
                foreach (string factoryContentType in factory.Metadata.ContentTypes)
                {
                    foreach (ITextBuffer subjectBuffer in subjectBuffers)
                    {
                        if (subjectBuffer.ContentType.IsOfType(factoryContentType) &&
                            !matchingSubjectBuffers.Contains(subjectBuffer))
                        {
                            matchingSubjectBuffers.Add(subjectBuffer);
                        }
                    }
                }

                if (matchingSubjectBuffers.Count > 0)
                {
                    // This controller factory is registered for the content type we understand.  Go ahead and create
                    // one.  Note that this won't give us a handle to a controller object.  We wouldn't be able to do anything
                    // with such a reference anyway.

                    if (manager.Controllers[f] == null)
                    {
                        manager.Controllers[f] = this.GuardedOperations.InstantiateExtension
                                                     (factory, factory,
                                                     provider => provider.TryCreateIntellisenseController(textView, matchingSubjectBuffers));
                    }
                    else
                    {
                        foreach (ITextBuffer matchingSubjectBuffer in matchingSubjectBuffers)
                        {
                            manager.Controllers[f].ConnectSubjectBuffer(matchingSubjectBuffer);
                        }
                    }
                }
            }
        }
        }                                                                       //For unit tests

        private void AddSpan(object key, PersistentSpan persistentSpan)
        {
            lock (_spansOnDocuments)
            {
                FrugalList <PersistentSpan> spans;
                if (!_spansOnDocuments.TryGetValue(key, out spans))
                {
                    this.EnsureEventsHooked();

                    spans = new FrugalList <PersistentSpan>();
                    _spansOnDocuments.Add(key, spans);
                }

                spans.Add(persistentSpan);
            }
        }
Пример #30
0
        private Span MapNullSpansToSourceSnapshots(IElisionSnapshot elisionSnapshot, Span span, FrugalList <SnapshotSpan> result)
        {
            // TODO: this is identical to projection snapshot; can it be shared?
            FrugalList <SnapshotPoint> points = MapInsertionPointToSourceSnapshots(elisionSnapshot, span.Start);

            for (int p = 0; p < points.Count; ++p)
            {
                SnapshotPoint point      = points[p];
                SnapshotSpan  mappedSpan = new SnapshotSpan(point.Snapshot, point.Position, 0);
                if (result.Count == 0 || mappedSpan != result[result.Count - 1])
                {
                    result.Add(mappedSpan);
                }
            }
            return(span);
        }
Пример #31
0
        private void AddMapping(KeyState keyState, KeyInput keyInput, string text)
        {
            _keyStateToVimKeyDataMap[keyState] = new VimKeyData(keyInput, text);

            FrugalList<KeyState> list;
            if (!_keyInputToWpfKeyDataMap.TryGetValue(keyInput, out list))
            {
                _keyInputToWpfKeyDataMap[keyInput] = new FrugalList<KeyState>(keyState);
            }
            else
            {
                list.Add(keyState);
            }
        }