IWordCompletionSession IWordCompletionSessionFactoryService.CreateWordCompletionSession(ITextView textView, SnapshotSpan wordSpan, IEnumerable <string> wordCollection, bool isForward) { var completionData = new CompletionData( wordSpan, new ReadOnlyCollection <string>(wordCollection.ToList())); textView.Properties[_completionDataKey] = completionData; try { // 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(new DismissedWordCompletionSession(textView)); } // Now move the word completion set to the fron var wordCompletionSet = completionSession.CompletionSets.OfType <WordCompletionSet>().FirstOrDefault(); if (wordCompletionSet == null) { wordCompletionSet = new WordCompletionSet(); } completionSession.SelectedCompletionSet = wordCompletionSet; var intellisenseSessionStack = _intellisenseSessionStackMapService.GetStackForTextView(textView); var wordTrackingSpan = wordSpan.Snapshot.CreateTrackingSpan(wordSpan.Span, SpanTrackingMode.EdgeInclusive); var wordCompletionSession = new WordCompletionSession( 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); RaiseCompleted(wordCompletionSession); return(wordCompletionSession); } finally { textView.Properties.RemoveProperty(_completionDataKey); } }
IWordCompletionSession IWordCompletionSessionFactoryService.CreateWordCompletionSession(ITextView textView, SnapshotSpan wordSpan, IEnumerable<string> wordCollection, bool isForward) { var completionData = new CompletionData( wordSpan, new ReadOnlyCollection<string>(wordCollection.ToList())); textView.Properties[_completionDataKey] = completionData; try { // 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 new DismissedWordCompletionSession(textView); } // Now move the word completion set to the fron var wordCompletionSet = completionSession.CompletionSets.OfType<WordCompletionSet>().FirstOrDefault(); if (wordCompletionSet == null) { wordCompletionSet = new WordCompletionSet(); } completionSession.SelectedCompletionSet = wordCompletionSet; var intellisenseSessionStack = _intellisenseSessionStackMapService.GetStackForTextView(textView); var wordTrackingSpan = wordSpan.Snapshot.CreateTrackingSpan(wordSpan.Span, SpanTrackingMode.EdgeInclusive); var wordCompletionSession = new WordCompletionSession( 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); return wordCompletionSession; } finally { textView.Properties.RemoveProperty(_completionDataKey); } }