public void PresentItem(ITrackingSpan triggerSpan, QuickInfoItem item, bool trackMouse) { AssertIsForeground(); _triggerSpan = triggerSpan; _item = item; // It's a new list of items. Either create the editor session if this is the first time, or ask the // editor session that we already have to recalculate. if (_editorSessionOpt == null || _editorSessionOpt.IsDismissed) { // We're tracking the caret. Don't have the editor do it. var triggerPoint = triggerSpan.GetStartTrackingPoint(PointTrackingMode.Negative); _editorSessionOpt = _quickInfoBroker.CreateQuickInfoSession(_textView, triggerPoint, trackMouse: trackMouse); _editorSessionOpt.Dismissed += (s, e) => OnEditorSessionDismissed(); } // So here's the deal. We cannot create the editor session and give it the right // signatures (even though we know what they are). Instead, the session with // call back into the ISignatureHelpSourceProvider (which is us) to get those // values. It will pass itself along with the calls back into // ISignatureHelpSourceProvider. So, in order to make that connection work, we // add properties to the session so that we can call back into ourselves, get // the signatures and add it to the session. if (!_editorSessionOpt.Properties.ContainsProperty(s_augmentSessionKey)) { _editorSessionOpt.Properties.AddProperty(s_augmentSessionKey, this); } _editorSessionOpt.Recalculate(); }
async Task StartAsync() { if (isDisposed || cancellationToken.IsCancellationRequested) { Dispose(); return; } Item = await State.QuickInfoService.GetItemAsync(State.Document, triggerPoint.Position, cancellationToken); if (isDisposed || cancellationToken.IsCancellationRequested || Item == null) { Dispose(); return; } DisposeCancellationToken(); var trackingPoint = triggerPoint.Snapshot.CreateTrackingPoint(triggerPoint.Position, PointTrackingMode.Negative); var session = quickInfoBroker.CreateQuickInfoSession(textView, trackingPoint, trackMouse); session.Properties.AddProperty(thisInstanceKey, this); session.Dismissed += Session_Dismissed; session.Start(); }
internal void EventHookupFoundInSession(EventHookupSession analyzedSession) { AssertIsForeground(); var caretPoint = analyzedSession.TextView.GetCaretPoint(analyzedSession.SubjectBuffer); // Ensure the analyzed session matches the current session and that the caret is still // in the session's tracking span. if (CurrentSession == analyzedSession && QuickInfoSession == null && caretPoint.HasValue && analyzedSession.TrackingSpan.GetSpan(CurrentSession.TextView.TextSnapshot).Contains(caretPoint.Value)) { QuickInfoSession = _quickInfoBroker.CreateQuickInfoSession(analyzedSession.TextView, analyzedSession.TrackingPoint, trackMouse: false); // Special indicator that this quick info session was created by event hookup, // which is used when deciding whether and how to display the session QuickInfoSession.Properties.AddProperty(typeof(EventHookupSessionManager), this); QuickInfoSession.Properties.AddProperty(QuickInfoUtilities.EventHookupKey, "EventHookup"); // Watch all text buffer changes & caret moves while this quick info session is // active analyzedSession.TextView.TextSnapshot.TextBuffer.Changed += TextBuffer_Changed; CurrentSession.Dismissed += () => { analyzedSession.TextView.TextSnapshot.TextBuffer.Changed -= TextBuffer_Changed; }; analyzedSession.TextView.Caret.PositionChanged += Caret_PositionChanged; CurrentSession.Dismissed += () => { analyzedSession.TextView.Caret.PositionChanged -= Caret_PositionChanged; }; QuickInfoSession.Start(); // HACK! Workaround for VS dismissing quick info sessions on buffer changed events. // This must happen after the QuickInfoSession is started. if (_prematureDismissalPreventer != null) { _prematureDismissalPreventer.HACK_EnsureQuickInfoSessionNotDismissedPrematurely(analyzedSession.TextView); QuickInfoSession.Dismissed += (s, e) => { _prematureDismissalPreventer.HACK_OnQuickInfoSessionDismissed(analyzedSession.TextView); }; } } }