protected virtual void ExpandSmartTagUnderCaret()
        {
            ITextView     textView       = Controller.TextView;
            SnapshotPoint?insertionPoint = textView.Caret.Position.Point.GetInsertionPoint(buffer => buffer == textView.TextBuffer);

            if (!insertionPoint.HasValue)
            {
                throw new InvalidOperationException();
            }

            ITextSnapshot snapshot  = insertionPoint.Value.Snapshot;
            SnapshotSpan  caretSpan = new SnapshotSpan(insertionPoint.Value, 0);
            IEnumerable <ISmartTagSession> sessions = Controller.Provider.SmartTagBroker.GetSessions(textView);
            ISmartTagSession        session         = sessions.FirstOrDefault(i => i.ApplicableToSpan.GetSpan(snapshot).IntersectsWith(caretSpan) && i.Type == SmartTagType.Factoid);
            List <ISmartTagSession> source          = sessions.Where(i => i.Type == SmartTagType.Ephemeral).ToList();

            if (session == null)
            {
                session = source.FirstOrDefault(i => i.ApplicableToSpan.GetSpan(snapshot).IntersectsWith(caretSpan));
            }

            if (session == null && source.Count == 1)
            {
                session = source[0];
            }

            if (session != null)
            {
                session.State = SmartTagState.Expanded;
            }
        }
        private void AddImportTags(ISmartTagSession session, IList <SmartTagActionSet> smartTagActionSets)
        {
            var textBuffer = _textBuffer;
            var span       = session.CreateTrackingSpan(textBuffer);
            var imports    = textBuffer.CurrentSnapshot.GetMissingImports(_serviceProvider, span);

            if (imports == MissingImportAnalysis.Empty)
            {
                return;
            }

            SmartTagController controller;

            session.Properties.TryGetProperty <SmartTagController>(typeof(SmartTagController), out controller);

            var task     = Volatile.Read(ref controller._curTask);
            var origTask = task;

            var snapshot = textBuffer.CurrentSnapshot;

            if (task != null &&
                task.ApplicableToSpan.GetSpan(snapshot) != imports.ApplicableToSpan.GetSpan(snapshot))
            {
                // Previous task is invalid, so abort it and we'll start a
                // new one.
                task.Abort();
                session.Properties.RemoveProperty(typeof(SmartTagAugmentTask));
                task = null;
            }

            if (task == null)
            {
                task = new SmartTagAugmentTask(
                    _serviceProvider,
                    textBuffer,
                    session.TextView,
                    imports
                    );
                if (Interlocked.CompareExchange(ref controller._curTask, task, origTask) != origTask)
                {
                    // Item has been changed by someone else, so abort
                    // Except we should always be on the UI thread here, so
                    // there should be no races.
                    Debug.Fail("Race in AugmentSmartTagSession");
                    return;
                }
            }

            session.ApplicableToSpan = imports.ApplicableToSpan;

            var result = task.GetResultIfComplete();

            if (result != null && Interlocked.CompareExchange(ref controller._curTask, null, task) == task)
            {
                // Provide results if we were the current task and we are
                // now complete
                smartTagActionSets.Add(result);
            }
        }
Exemplo n.º 3
0
        public virtual void DismissSmartTag()
        {
            ISmartTagSession session = SmartTagSession;

            SmartTagSession = null;
            if (session != null && !session.IsDismissed)
            {
                session.Dismiss();
            }
        }
Exemplo n.º 4
0
        public virtual void TriggerSmartTag(ITrackingPoint triggerPoint, SmartTagType type, SmartTagState state)
        {
            DismissSmartTag();
            ISmartTagSession session = Provider.SmartTagBroker.CreateSmartTagSession(TextView, type, triggerPoint, state);

            if (session != null)
            {
                session.Dismissed += HandleSmartTagDismissed;
                SmartTagSession    = session;
            }
        }
Exemplo n.º 5
0
        private bool ExpandSmartTagUnderCaret()
        {
            var insertionPoint = wpfTextView.Caret.Position.Point.GetInsertionPoint(b => b == wpfTextView.TextBuffer);
            var snapshot       = insertionPoint.Value.Snapshot;
            var caretSpan      = new SnapshotSpan(insertionPoint.Value, 0);
            ReadOnlyCollection <ISmartTagSession> sessions = smartTagBroker.GetSessions(wpfTextView);
            ISmartTagSession session =
                sessions.FirstOrDefault(s => s.ApplicableToSpan.GetSpan(snapshot).IntersectsWith(caretSpan) && s.Type == SmartTagType.Factoid)
                ?? sessions.FirstOrDefault(s => s.ApplicableToSpan.GetSpan(snapshot).IntersectsWith(caretSpan) && s.Type == SmartTagType.Ephemeral)
                ?? sessions.FirstOrDefault(s => s.Type == SmartTagType.Ephemeral);

            // VS will only ignore the caret if there is exactly one ephemeral session, but I'm lazy
            if (session == null)
            {
                return(false);
            }
            session.State = SmartTagState.Expanded;
            return(true);
        }
Exemplo n.º 6
0
#pragma warning disable 0618

        // TODO: Switch from smart tags to Light Bulb: http://go.microsoft.com/fwlink/?LinkId=394601
        internal static ITrackingSpan CreateTrackingSpan(this ISmartTagSession session, ITextBuffer buffer)
        {
            var triggerPoint = session.GetTriggerPoint(buffer);
            var position     = triggerPoint.GetPosition(buffer.CurrentSnapshot);

            if (position == buffer.CurrentSnapshot.Length)
            {
                return(((IIntellisenseSession)session).GetApplicableSpan(buffer));
            }

            var triggerChar = triggerPoint.GetCharacter(buffer.CurrentSnapshot);

            if (position != 0 && !char.IsLetterOrDigit(triggerChar))
            {
                // end of line, back up one char as we may have an identifier
                return(buffer.CurrentSnapshot.CreateTrackingSpan(position - 1, 1, SpanTrackingMode.EdgeInclusive));
            }

            return(buffer.CurrentSnapshot.CreateTrackingSpan(position, 1, SpanTrackingMode.EdgeInclusive));
        }
Exemplo n.º 7
0
 public void AugmentSmartTagSession(ISmartTagSession session, IList <SmartTagActionSet> smartTagActionSets)
 {
     AddImportTags(session, smartTagActionSets);
 }
Exemplo n.º 8
0
        private void AddImportTags(ISmartTagSession session, IList<SmartTagActionSet> smartTagActionSets) {
            var textBuffer = _textBuffer;
            var span = session.CreateTrackingSpan(textBuffer);
            var imports = textBuffer.CurrentSnapshot.GetMissingImports(_serviceProvider, span);

            if (imports == MissingImportAnalysis.Empty) {
                return;
            }

            SmartTagController controller;
            session.Properties.TryGetProperty<SmartTagController>(typeof(SmartTagController), out controller);
            if (controller == null) {
                return;
            }

            var task = Volatile.Read(ref controller._curTask);
            var origTask = task;

            var snapshot = textBuffer.CurrentSnapshot;
            if (task != null &&
                task.ApplicableToSpan.GetSpan(snapshot) != imports.ApplicableToSpan.GetSpan(snapshot)) {
                // Previous task is invalid, so abort it and we'll start a
                // new one.
                task.Abort();
                session.Properties.RemoveProperty(typeof(SmartTagAugmentTask));
                task = null;
            }
                
            if (task == null) {
                task = new SmartTagAugmentTask(
                    _serviceProvider,
                    textBuffer,
                    session.TextView,
                    imports
                );
                if (Interlocked.CompareExchange(ref controller._curTask, task, origTask) != origTask) {
                    // Item has been changed by someone else, so abort
                    // Except we should always be on the UI thread here, so
                    // there should be no races.
                    Debug.Fail("Race in AugmentSmartTagSession");
                    return;
                }
            }
                
            session.ApplicableToSpan = imports.ApplicableToSpan;

            var result = task.GetResultIfComplete();
            if (result != null && Interlocked.CompareExchange(ref controller._curTask, null, task) == task) {
                // Provide results if we were the current task and we are
                // now complete
                smartTagActionSets.Add(result);
            }
        }
Exemplo n.º 9
0
 public void AugmentSmartTagSession(ISmartTagSession session, IList<SmartTagActionSet> smartTagActionSets) {
     AddImportTags(session, smartTagActionSets);
 }
Exemplo n.º 10
0
        private void AddImportTags(ISmartTagSession session, IList<SmartTagActionSet> smartTagActionSets)
        {
            var textBuffer = _textBuffer;
            var span = session.CreateTrackingSpan(textBuffer);
            var imports = textBuffer.CurrentSnapshot.GetMissingImports(span);
            IOleComponentManager compMgr;
            SmartTagController controller;

            session.Properties.TryGetProperty<IOleComponentManager>(typeof(SmartTagController), out compMgr);
            session.Properties.TryGetProperty<SmartTagController>(typeof(SmartTagSource.AbortedAugmentInfo), out controller);

            if (imports != MissingImportAnalysis.Empty) {
                session.ApplicableToSpan = imports.ApplicableToSpan;

                // When doing idle processing we can keep getting kicked out and come back.  The whole process
                // of getting the import smart tags is done lazily through iterators.  If we keep trying again
                // and not getting enough idle time we'll never work away through the full list when it's large
                // (for example 'sys' in a large distro which is imported and exported everywhere).  So as long
                // as we're working on the same location (our SmartTagController tracks this) then we'll keep working
                // through the same enumerator so we make progress over time.   So we'll read the AbortedAugment
                // here and continue working, and if we run out of idletime we'll add or update the aborted augment.
                List<ISmartTagAction> actions;
                IEnumerator<ExportedMemberInfo> importsEnum;

                if (controller == null || controller._abortedAugment == null) {
                    actions = new List<ISmartTagAction>();
                    importsEnum = imports.AvailableImports.GetEnumerator();
                } else {
                    // continue processing of the old imports
                    importsEnum = controller._abortedAugment.Imports;
                    actions = controller._abortedAugment.Actions;
                }

                bool aborted = false;
                while (importsEnum.MoveNext()) {
                    var import = importsEnum.Current;

                    if (import.IsDefinedInModule) {
                        int lastDot;

                        if ((lastDot = import.Name.LastIndexOf('.')) == -1) {
                            // simple import
                            actions.Add(new ImportSmartTagAction(import.Name, _textBuffer, session.TextView));
                        } else {
                            // importing a package or member of a module
                            actions.Add(new ImportSmartTagAction(import.Name.Substring(0, lastDot), import.Name.Substring(lastDot + 1), _textBuffer, session.TextView));
                        }
                    }

                    if (compMgr != null && compMgr.FContinueIdle() == 0) {
                        // we've run out of time, save our progress...
                        if (controller != null) {
                            controller._sessionIsInvalid = true;
                            controller._abortedAugment = new AbortedAugmentInfo(importsEnum, actions);
                        }
                        aborted = true;
                        break;
                    }
                }

                if (!aborted && controller != null) {
                    controller._abortedAugment = null;
                }

                if (actions.Count > 0) {
                    smartTagActionSets.Add(new SmartTagActionSet(new ReadOnlyCollection<ISmartTagAction>(actions.ToArray())));
                }
            }
        }
Exemplo n.º 11
0
        internal void ShowSmartTag(IOleComponentManager compMgr = null)
        {
            if (!_sessionIsInvalid) {
                // caret / text hasn't changed since we last computed the smart tag, don't bother computing again.
                return;
            }

            ITextSnapshot snapshot = _textView.TextViewModel.DataBuffer.CurrentSnapshot;
            SnapshotPoint? caretPoint = _textView.Caret.Position.Point.GetPoint(snapshot, PositionAffinity.Successor);
            if (caretPoint != null &&
                _curSession != null &&
                !_curSession.IsDismissed &&
                _curSession.ApplicableToSpan != null &&
                _curSession.ApplicableToSpan.GetSpan(_textView.TextBuffer.CurrentSnapshot).Contains(caretPoint.Value.Position)) {
                    return;
            }

            _sessionIsInvalid = false;

            // Figure out the point in the buffer where we are triggering.
            // We need to use the view's data buffer as the source location
            if (_curSession != null && !_curSession.IsDismissed) {
                _curSession.Dismiss();
            }

            if (!caretPoint.HasValue) {
                return;
            }

            ITrackingPoint triggerPoint = snapshot.CreateTrackingPoint(caretPoint.Value, PointTrackingMode.Positive);
            ISmartTagSession newSession = _curSession = _broker.CreateSmartTagSession(_textView, SmartTagType.Factoid, triggerPoint, SmartTagState.Collapsed);
            newSession.Properties.AddProperty(typeof(SmartTagController), compMgr);
            newSession.Properties.AddProperty(typeof(SmartTagSource.AbortedAugmentInfo), this);

            newSession.Start();
        }