internal WordCompletionSession(ITrackingSpan wordTrackingSpan, IIntellisenseSessionStack intellisenseSessionStack, ICompletionSession completionSession, WordCompletionSet wordCompletionSet) { _textView = completionSession.TextView; _wordTrackingSpan = wordTrackingSpan; _wordCompletionSet = wordCompletionSet; _completionSession = completionSession; _completionSession.Dismissed += delegate { OnDismissed(); }; _intellisenseSessionStack = intellisenseSessionStack; }
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); } }
/// <summary> /// Augment the completion session with the provided set of words if this completion session is /// being created for a word completion session /// </summary> void ICompletionSource.AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets) { var textView = session.TextView; // Only provide completion information for the ITextBuffer directly associated with the // ITextView. In a projcetion secnario there will be several ITextBuffer instances associated // with a given ITextView and we provide ICompletionSource values for all of them. We want to // avoid creating duplicate completion information if (textView.TextBuffer != _textBuffer) { return; } // Get out the collection of words. If none is present then there is no information to // augment here CompletionData completionData; if (!textView.Properties.TryGetPropertySafe(_completionDataKey, out completionData) || completionData.WordCollection == null) { return; } var trackingSpan = completionData.WordSpan.Snapshot.CreateTrackingSpan( completionData.WordSpan.Span, SpanTrackingMode.EdgeInclusive); var completions = completionData.WordCollection.Select(word => new Completion(word)); var wordCompletionSet = new WordCompletionSet(trackingSpan, completions); completionSets.Add(wordCompletionSet); }