예제 #1
0
        internal FSharpOption <IWordCompletionSession> CreateWordCompletionSession(ITextView textView, SnapshotSpan wordSpan, IEnumerable <string> wordCollection, bool isForward)
        {
            // Dismiss any active ICompletionSession instances.  It's possible and possibly common for
            // normal intellisense to be active when the user invokes word completion.  We want only word
            // completion displayed at this point
            _asyncCompletionBroker.GetSession(textView)?.Dismiss();

            // Store the WordCompletionData inside the ITextView. The IAsyncCompletionSource implementation will
            // asked to provide data for the creation of the IAsyncCompletionSession. Hence we must share through
            // ITextView
            var wordCompletionData = new VimWordCompletionData(
                wordSpan,
                new ReadOnlyCollection <string>(wordCollection.ToList()));

            textView.SetWordCompletionData(wordCompletionData);

            // Create a completion session at the start of the word.  The actual session information will
            // take care of mapping it to a specific span
            var completionTrigger      = new CompletionTrigger(CompletionTriggerReason.Insertion, wordSpan.Snapshot);
            var asyncCompletionSession = _asyncCompletionBroker.TriggerCompletion(
                textView,
                completionTrigger,
                wordSpan.Start,
                CancellationToken.None);

            // It's possible for the Start method to dismiss the ICompletionSession.  This happens when there
            // is an initialization error such as being unable to find a CompletionSet.  If this occurs we
            // just return the equivalent IWordCompletionSession (one which is dismissed)
            if (asyncCompletionSession.IsDismissed)
            {
                return(FSharpOption <IWordCompletionSession> .None);
            }

            asyncCompletionSession.OpenOrUpdate(completionTrigger, wordSpan.Start, CancellationToken.None);
#if VS_SPECIFIC_2019
            return(new WordAsyncCompletionSession(asyncCompletionSession, _vsEditorAdaptersFactoryService));
#elif VS_SPECIFIC_MAC
            return(new WordAsyncCompletionSession(asyncCompletionSession));
#endif
        }
예제 #2
0
        internal FSharpOption <IWordCompletionSession> CreateWordCompletionSession(ITextView textView, SnapshotSpan wordSpan, IEnumerable <string> wordCollection, bool isForward)
        {
            var completionData = new VimWordCompletionData(
                wordSpan,
                new ReadOnlyCollection <string>(wordCollection.ToList()));

            textView.SetWordCompletionData(completionData);

            // Dismiss any active ICompletionSession instances.  It's possible and possibly common for
            // normal intellisense to be active when the user invokes word completion.  We want only word
            // completion displayed at this point
            foreach (var existingCompletionSession in _completionBroker.GetSessions(textView))
            {
                existingCompletionSession.Dismiss();
            }

            // Create a completion session at the start of the word.  The actual session information will
            // take care of mapping it to a specific span
            var trackingPoint     = textView.TextSnapshot.CreateTrackingPoint(wordSpan.Start, PointTrackingMode.Positive);
            var completionSession = _completionBroker.CreateCompletionSession(textView, trackingPoint, true);

            completionSession.Properties[WordCompletionSessionKey] = WordCompletionSessionKey;

            // Start the completion.  This will cause it to get populated at which point we can go about
            // filtering the data
            completionSession.Start();

            // It's possible for the Start method to dismiss the ICompletionSession.  This happens when there
            // is an initialization error such as being unable to find a CompletionSet.  If this occurs we
            // just return the equivalent IWordCompletionSession (one which is dismissed)
            if (completionSession.IsDismissed)
            {
                return(FSharpOption <IWordCompletionSession> .None);
            }

            // Now move the word completion set to the fron
            var wordCompletionSet = completionSession.CompletionSets.OfType <WordLegacyCompletionSet>().FirstOrDefault();

            if (wordCompletionSet == null)
            {
                wordCompletionSet = new WordLegacyCompletionSet();
            }
            completionSession.SelectedCompletionSet = wordCompletionSet;

            var intellisenseSessionStack = _intellisenseSessionStackMapService.GetStackForTextView(textView);
            var wordTrackingSpan         = wordSpan.Snapshot.CreateTrackingSpan(wordSpan.Span, SpanTrackingMode.EdgeInclusive);
            var wordCompletionSession    = new WordLegacyCompletionSession(
                wordTrackingSpan,
                intellisenseSessionStack,
                completionSession,
                wordCompletionSet);

            // Ensure the correct item is selected and committed to the ITextBuffer.  If this is a forward completion
            // then we select the first item, else the last.  Sending the command will go ahead and insert the
            // completion in the given span
            var command = isForward ? IntellisenseKeyboardCommand.TopLine : IntellisenseKeyboardCommand.BottomLine;

            wordCompletionSession.SendCommand(command);

            // For reasons I don't understand, if the command is 'bottom
            // line', it doesn't seem to take effect on the first try.
            wordCompletionSession.SendCommand(command);

            return(FSharpOption <IWordCompletionSession> .Some(wordCompletionSession));
        }