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();
        }
Beispiel #2
0
        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);
        }