public EditorCommandHandlerServiceFactory( [ImportMany] IEnumerable <Lazy <ICommandHandler, ICommandHandlerMetadata> > commandHandlers, [ImportMany] IEnumerable <Lazy <ICommandingTextBufferResolverProvider, IContentTypeMetadata> > bufferResolvers, IUIThreadOperationExecutor uiThreadOperationExecutor, JoinableTaskContext joinableTaskContext, IStatusBarService statusBar, IContentTypeRegistryService contentTypeRegistryService, IGuardedOperations guardedOperations, [Import(AllowDefault = true)] ILoggingServiceInternal loggingService) { UIThreadOperationExecutor = uiThreadOperationExecutor; JoinableTaskContext = joinableTaskContext; StatusBar = statusBar; GuardedOperations = guardedOperations; LoggingService = loggingService; _contentTypeRegistryService = contentTypeRegistryService; ContentTypeComparer = new StableContentTypeComparer(_contentTypeRegistryService); _commandHandlers = OrderCommandHandlers(commandHandlers); if (!bufferResolvers.Any()) { throw new ImportCardinalityMismatchException($"Expected to import at least one {typeof(ICommandingTextBufferResolver).Name}"); } _bufferResolverProviders = bufferResolvers.ToList(); }
public IAsyncCompletionSession TriggerCompletion(ITextView textView, CompletionTrigger trigger, SnapshotPoint triggerLocation, CancellationToken token) { var session = GetSession(textView); if (session != null) { return(session); } // This is a simple check that only queries the feature service. // If it succeeds, we will map triggerLocation to available buffers to discover MEF parts. // This is expensive but projected languages require it to discover parts in all available buffers. // To avoid doing this work, call IsCompletionSupported with appropriate IContentType prior to calling TriggerCompletion if (!CompletionAvailability.IsCurrentlyAvailable(textView)) { return(null); } if (textView.IsClosed) { return(null); } if (!JoinableTaskContext.IsOnMainThread) { throw new InvalidOperationException($"This method must be callled on the UI thread."); } var telemetryHost = GetOrCreateTelemetry(textView); var telemetry = new CompletionSessionTelemetry(telemetryHost); var rootSnapshot = GetRootSnapshot(textView); if (token.IsCancellationRequested || textView.IsClosed) { return(null); } // See if we can use more aggressive cancellation token for typing scenarios if (trigger.Reason == CompletionTriggerReason.Insertion) { token = CompletionUtilities.GetResponsiveToken(textView, token); } GetCompletionSources(triggerLocation, GetItemSourceProviders, rootSnapshot, textView, textView.BufferGraph, trigger, telemetry, token, out var sourcesWithLocations, out var applicableToSpan); if (token.IsCancellationRequested || textView.IsClosed) { return(null); } // No source declared an appropriate ApplicableToSpan if (applicableToSpan == default) { return(null); } // No source wishes to participate if (!sourcesWithLocations.Any()) { return(null); } // Some of our extensions need to initialize the source providers before they initialize commit manager providers. // Therefore, it is important to invoke GetCommitManagerProviders after invoking GetItemSourceProviders. GetCommitManagersAndChars(triggerLocation, GetCommitManagerProviders, rootSnapshot, textView, telemetry, out var managersWithBuffers, out var potentialCommitChars); if (_contentTypeComparer == null) { _contentTypeComparer = new StableContentTypeComparer(ContentTypeRegistryService); } var itemManager = GetItemManager(triggerLocation, GetItemManagerProviders, rootSnapshot, textView, _contentTypeComparer); var presenterProvider = GetPresenterProvider(triggerLocation, GetPresenters, rootSnapshot, textView.Roles, _contentTypeComparer); if (token.IsCancellationRequested || textView.IsClosed) { return(null); } session = new AsyncCompletionSession(applicableToSpan, potentialCommitChars, JoinableTaskContext, presenterProvider, sourcesWithLocations, managersWithBuffers, itemManager, this, textView, telemetry, GuardedOperations); textView.Properties.AddProperty(typeof(IAsyncCompletionSession), session); textView.Closed += DismissSessionOnViewClosed; EmulateLegacyCompletionTelemetry(textView); GuardedOperations.RaiseEvent(this, CompletionTriggered, new CompletionTriggeredEventArgs(session, textView)); return(session); }