public ILightBulbSession GetLightBulbSession() { ILightBulbBroker broker = EditorShell.Current.ExportProvider.GetExportedValue <ILightBulbBroker>(); var session = broker.GetSession(EditorWindow.CoreEditor.View); int retries = 0; while (session == null && retries < 10) { this.DoIdle(1000); session = broker.GetSession(EditorWindow.CoreEditor.View); retries++; } return(session); }
private IEnumerable <ISuggestedAction> GetLightBulbActions(ILightBulbBroker broker, IWpfTextView view) { if (!broker.IsLightBulbSessionActive(view)) { var bufferType = view.TextBuffer.ContentType.DisplayName; throw new Exception(string.Format("No light bulb session in View! Buffer content type={0}", bufferType)); } var activeSession = broker.GetSession(view); if (activeSession == null || !activeSession.IsExpanded) { var bufferType = view.TextBuffer.ContentType.DisplayName; throw new InvalidOperationException(string.Format("No expanded light bulb session found after View.ShowSmartTag. Buffer content type={0}", bufferType)); } IEnumerable <SuggestedActionSet> actionSets; if (activeSession.TryGetSuggestedActionSets(out actionSets) != QuerySuggestedActionCompletionStatus.Completed) { actionSets = Array.Empty <SuggestedActionSet>(); } return(SelectActions(actionSets)); }
public static async Task <IEnumerable <SuggestedActionSet> > WaitForItemsAsync(ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken) { var activeSession = broker.GetSession(view); if (activeSession == null) { var bufferType = view.TextBuffer.ContentType.DisplayName; throw new InvalidOperationException($"No expanded light bulb session found after View.ShowSmartTag. Buffer content type={bufferType}"); } var asyncSession = (IAsyncLightBulbSession)activeSession; var tcs = new TaskCompletionSource <List <SuggestedActionSet> >(); EventHandler <SuggestedActionsUpdatedArgs>?handler = null; handler = (s, e) => { // ignore these. we care about when the lightbulb items are all completed. if (e.Status == QuerySuggestedActionCompletionStatus.InProgress) { return; } if (e.Status == QuerySuggestedActionCompletionStatus.Completed) { tcs.SetResult(e.ActionSets.ToList()); } else { tcs.SetException(new InvalidOperationException($"Light bulb transitioned to non-complete state: {e.Status}")); } asyncSession.SuggestedActionsUpdated -= handler; }; asyncSession.SuggestedActionsUpdated += handler; asyncSession.Dismissed += (_, _) => tcs.TrySetCanceled(new CancellationToken(true)); if (asyncSession.IsDismissed) { tcs.TrySetCanceled(new CancellationToken(true)); } // Calling PopulateWithData ensures the underlying session will call SuggestedActionsUpdated at least once // with the latest data computed. This is needed so that if the lightbulb computation is already complete // that we hear about the results. asyncSession.PopulateWithData(overrideRequestedActionCategories: null, operationContext: null); return(await tcs.Task.WithCancellation(cancellationToken)); }
public static async Task <bool> WaitForLightBulbSessionAsync(ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken) { var startTime = DateTimeOffset.Now; var active = await Helper.RetryAsync(async cancellationToken => { if (broker.IsLightBulbSessionActive(view)) { return(true); } if (cancellationToken.IsCancellationRequested) { throw new InvalidOperationException("Expected a light bulb session to appear."); } if (broker.IsLightBulbSessionActive(view)) { var session = broker.GetSession(view); var hasSuggestedActions = await broker.HasSuggestedActionsAsync(session.ActionCategories, view, cancellationToken); return(hasSuggestedActions); } return(false); }, TimeSpan.FromMilliseconds(1), cancellationToken); if (!active) { return(false); } await WaitForItemsAsync(broker, view, cancellationToken); return(true); }
private ClassifiedToken[] GetLightbulbPreviewClassifications( string menuText, ILightBulbBroker broker, IWpfTextView view, IViewClassifierAggregatorService viewClassifierAggregator, IEditorPrimitivesFactoryService editorPrimitives) { LightBulbHelper.WaitForLightBulbSession(broker, view); var bufferType = view.TextBuffer.ContentType.DisplayName; if (!broker.IsLightBulbSessionActive(view)) { throw new Exception(string.Format("No Active Smart Tags in View! Buffer content type={0}", bufferType)); } var activeSession = broker.GetSession(view); if (activeSession == null || !activeSession.IsExpanded) { throw new InvalidOperationException(string.Format("No expanded light bulb session found after View.ShowSmartTag. Buffer content type={0}", bufferType)); } if (!string.IsNullOrEmpty(menuText)) { IEnumerable <SuggestedActionSet> actionSets; if (activeSession.TryGetSuggestedActionSets(out actionSets) != QuerySuggestedActionCompletionStatus.Completed) { actionSets = Array.Empty <SuggestedActionSet>(); } var set = actionSets.SelectMany(s => s.Actions).FirstOrDefault(a => a.DisplayText == menuText); if (set == null) { throw new InvalidOperationException( string.Format("ISuggestionAction {0} not found. Buffer content type={1}", menuText, bufferType)); } IWpfTextView preview = null; object pane = HostWaitHelper.PumpingWaitResult(set.GetPreviewAsync(CancellationToken.None)); if (pane is System.Windows.Controls.UserControl) { var container = ((System.Windows.Controls.UserControl)pane).FindName("PreviewDockPanel") as DockPanel; var host = FindDescendants <UIElement>(container).OfType <IWpfTextViewHost>().LastOrDefault(); preview = (host == null) ? null : host.TextView; } if (preview == null) { throw new InvalidOperationException(string.Format("Could not find light bulb preview. Buffer content type={0}", bufferType)); } activeSession.Collapse(); var classifier = viewClassifierAggregator.GetClassifier(preview); var classifiedSpans = classifier.GetClassificationSpans(new SnapshotSpan(preview.TextBuffer.CurrentSnapshot, 0, preview.TextBuffer.CurrentSnapshot.Length)); return(classifiedSpans.Select(x => new ClassifiedToken(x.Span.GetText().ToString(), x.ClassificationType.Classification)).ToArray()); } activeSession.Collapse(); return(Array.Empty <ClassifiedToken>()); }