protected virtual bool DoesCompletionMatchApplicabilityTextDirect(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { string displayText = string.Empty; if (matchType == CompletionMatchType.MatchDisplayText) { displayText = completion.DisplayText; } else if (matchType == CompletionMatchType.MatchInsertionText) { displayText = completion.InsertionText; } if (PrefixMatch) { return displayText.StartsWith(filterText, !caseSensitive, CultureInfo.CurrentCulture); } StringComparison comparison = caseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; if (string.IsNullOrWhiteSpace(filterText)) return false; var words = filterText.Split(new[] {' ', '\t'}, StringSplitOptions.RemoveEmptyEntries); if (words.Length < 1) return false; // empty return words.All(word => WordPrefixContains(displayText, word, comparison)); // all words should match }
protected void CustomFilter(CompletionMatchType matchType, bool caseSensitive) { ITextSnapshot currentSnapshot = ApplicableTo.TextBuffer.CurrentSnapshot; var filterText = ApplicableTo.GetText(currentSnapshot).TrimEnd(); var predicate = GetFilterPredicate(filterText, matchType, caseSensitive); ((FilteredObservableCollection <Completion>)Completions).Filter(predicate); ((FilteredObservableCollection <Completion>)CompletionBuilders).Filter(predicate); }
protected override bool DoesCompletionMatchApplicabilityText(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { if (base.DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)) return true; object parentObject; completion.Properties.TryGetProperty("parentObject", out parentObject); IStepSuggestionGroup<Completion> parentObjectAsGroup = parentObject as IStepSuggestionGroup<Completion>; return parentObjectAsGroup != null && parentObjectAsGroup.Suggestions .Any(stepSuggestion => stepSuggestion.NativeSuggestionItem != null && DoesCompletionMatchApplicabilityText(stepSuggestion.NativeSuggestionItem, filterText, matchType, caseSensitive)); }
protected void CustomFilter(CompletionMatchType matchType, bool caseSensitive) { ITextSnapshot currentSnapshot = ApplicableTo.TextBuffer.CurrentSnapshot; var filterText = ApplicableTo.GetText(currentSnapshot).TrimEnd(); if (string.IsNullOrEmpty(filterText)) { ((FilteredObservableCollection<Completion>)Completions).StopFiltering(); ((FilteredObservableCollection<Completion>)CompletionBuilders).StopFiltering(); } else { ((FilteredObservableCollection<Completion>)Completions).Filter(completion => DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)); ((FilteredObservableCollection<Completion>)CompletionBuilders).Filter(completion => DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)); } }
protected void ExtendableFilter(CompletionMatchType matchType, bool caseSensitive) { if (string.IsNullOrEmpty(FilterBufferText)) { FilteredCompletions.StopFiltering(); FilteredCompletionBuilders.StopFiltering(); } else { _filterMatchType = matchType; _filterCaseSensitive = caseSensitive; FilteredCompletions.Filter(DoesCompletionMatchApplicabilityText); FilteredCompletionBuilders.Filter(DoesCompletionMatchApplicabilityText); } }
protected void CustomFilter(CompletionMatchType matchType, bool caseSensitive) { ITextSnapshot currentSnapshot = ApplicableTo.TextBuffer.CurrentSnapshot; var filterText = ApplicableTo.GetText(currentSnapshot).TrimEnd(); if (string.IsNullOrEmpty(filterText)) { ((FilteredObservableCollection <Completion>)Completions).StopFiltering(); ((FilteredObservableCollection <Completion>)CompletionBuilders).StopFiltering(); } else { ((FilteredObservableCollection <Completion>)Completions).Filter(completion => DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)); ((FilteredObservableCollection <Completion>)CompletionBuilders).Filter(completion => DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)); } }
internal static CompletionSelectionStatus SelectBestMatch(this CompletionSet set, CompletionMatchType matchType, bool caseSensitive) { CompletionMatchResult matchedCompletions = set.MatchCompletionList(set.Completions, matchType, caseSensitive); CompletionMatchResult matchedCompletionBuilders = set.MatchCompletionList(set.CompletionBuilders, matchType, caseSensitive); int completionBuilderCount = 0; if (matchedCompletionBuilders != null) { completionBuilderCount = (matchedCompletionBuilders.CharsMatchedCount + (matchedCompletionBuilders.SelectionStatus.IsSelected ? 1 : 0)) + (matchedCompletionBuilders.SelectionStatus.IsUnique ? 1 : 0); } int completionCount = 0; if (matchedCompletions != null) { completionCount = (matchedCompletions.CharsMatchedCount + (matchedCompletions.SelectionStatus.IsSelected ? 1 : 0)) + (matchedCompletions.SelectionStatus.IsUnique ? 1 : 0); } if ((completionBuilderCount > completionCount) && (matchedCompletionBuilders != null)) { set.SelectionStatus = matchedCompletionBuilders.SelectionStatus; } else if (matchedCompletions != null) { set.SelectionStatus = matchedCompletions.SelectionStatus; } else if (set.Completions.Count > 0) { if (!set.Completions.Contains(set.SelectionStatus.Completion)) { set.SelectionStatus = new CompletionSelectionStatus(set.Completions[0], false, false); } } else if (set.CompletionBuilders.Count > 0) { if (!set.CompletionBuilders.Contains(set.SelectionStatus.Completion)) { set.SelectionStatus = new CompletionSelectionStatus(set.CompletionBuilders[0], false, false); } } else { set.SelectionStatus = new CompletionSelectionStatus(null, false, false); } return set.SelectionStatus; }
/// <summary> /// Filters the set of completions to those that match the applicability text of the completion /// set and determines the best match. /// </summary> /// <param name="matchType">The <see cref="CompletionMatchType"/>.</param> /// <param name="caseSensitive"><c>true</c> if the match is case-sensitive, otherwise <c>false</c>.</param> /// <exception cref="InvalidOperationException">Both the completions and the completion builders have been overridden.</exception> protected void Filter(CompletionMatchType matchType, bool caseSensitive) { // Get the actual text from the buffer var filterBufferText = this.FilterBufferText; if (string.IsNullOrEmpty(filterBufferText)) { _filteredCompletions.StopFiltering(); _filteredCompletionBuilders.StopFiltering(); } else { _filterMatchType = matchType; _filterCaseSensitive = caseSensitive; _filteredCompletions.Filter(new Predicate <Completion>(this.DoesCompletionMatchApplicabilityText)); _filteredCompletionBuilders.Filter(new Predicate <Completion>(this.DoesCompletionMatchApplicabilityText)); } }
private static CompletionMatchResult MatchCompletionList(this CompletionSet set, IList<Completion> completionList, CompletionMatchType matchType, bool caseSensitive) { if (set.ApplicableTo == null) { throw new InvalidOperationException("Cannot match completion set with no applicability span."); } ITextSnapshot currentSnapshot = set.ApplicableTo.TextBuffer.CurrentSnapshot; string text = set.ApplicableTo.GetText(currentSnapshot); if (text.Length != 0) { Completion bestMatch = null; int maxMatchPosition = -1; bool isUnique = false; bool isSelected = false; foreach (Completion currentCompletion in completionList) { string displayText = string.Empty; if (matchType == CompletionMatchType.MatchDisplayText) { displayText = currentCompletion.DisplayText; } else if (matchType == CompletionMatchType.MatchInsertionText) { displayText = currentCompletion.InsertionText; } int matchPositionCount = 0; for (int i = 0; i < text.Length; i++) { if (i >= displayText.Length) { break; } char textChar = text[i]; char displayTextChar = displayText[i]; if (!caseSensitive) { textChar = char.ToLowerInvariant(textChar); displayTextChar = char.ToLowerInvariant(displayTextChar); } if (textChar != displayTextChar) { break; } matchPositionCount++; } if (matchPositionCount > maxMatchPosition) { maxMatchPosition = matchPositionCount; bestMatch = currentCompletion; isUnique = true; if ((matchPositionCount == text.Length) && (maxMatchPosition > 0)) { isSelected = true; } } else if (matchPositionCount == maxMatchPosition) { isUnique = false; if (isSelected) { break; } } } if (bestMatch != null) { CompletionMatchResult result = new CompletionMatchResult(); result.SelectionStatus = new CompletionSelectionStatus(bestMatch, isSelected, isUnique); result.CharsMatchedCount = (maxMatchPosition >= 0) ? maxMatchPosition : 0; return result; } } return null; }
internal static CompletionSelectionStatus SelectBestMatch(this CompletionSet set, CompletionMatchType matchType, bool caseSensitive) { CompletionMatchResult matchedCompletions = set.MatchCompletionList(set.Completions, matchType, caseSensitive); CompletionMatchResult matchedCompletionBuilders = set.MatchCompletionList(set.CompletionBuilders, matchType, caseSensitive); int completionBuilderCount = 0; if (matchedCompletionBuilders != null) { completionBuilderCount = (matchedCompletionBuilders.CharsMatchedCount + (matchedCompletionBuilders.SelectionStatus.IsSelected ? 1 : 0)) + (matchedCompletionBuilders.SelectionStatus.IsUnique ? 1 : 0); } int completionCount = 0; if (matchedCompletions != null) { completionCount = (matchedCompletions.CharsMatchedCount + (matchedCompletions.SelectionStatus.IsSelected ? 1 : 0)) + (matchedCompletions.SelectionStatus.IsUnique ? 1 : 0); } if ((completionBuilderCount > completionCount) && (matchedCompletionBuilders != null)) { set.SelectionStatus = matchedCompletionBuilders.SelectionStatus; } else if (matchedCompletions != null) { set.SelectionStatus = matchedCompletions.SelectionStatus; } else if (set.Completions.Count > 0) { if (!set.Completions.Contains(set.SelectionStatus.Completion)) { set.SelectionStatus = new CompletionSelectionStatus(set.Completions[0], false, false); } } else if (set.CompletionBuilders.Count > 0) { if (!set.CompletionBuilders.Contains(set.SelectionStatus.Completion)) { set.SelectionStatus = new CompletionSelectionStatus(set.CompletionBuilders[0], false, false); } } else { set.SelectionStatus = new CompletionSelectionStatus(null, false, false); } return(set.SelectionStatus); }
private static CompletionMatchResult MatchCompletionList(this CompletionSet set, IList <Completion> completionList, CompletionMatchType matchType, bool caseSensitive) { if (set.ApplicableTo == null) { throw new InvalidOperationException("Cannot match completion set with no applicability span."); } ITextSnapshot currentSnapshot = set.ApplicableTo.TextBuffer.CurrentSnapshot; string text = set.ApplicableTo.GetText(currentSnapshot); if (text.Length != 0) { Completion bestMatch = null; int maxMatchPosition = -1; bool isUnique = false; bool isSelected = false; foreach (Completion currentCompletion in completionList) { string displayText = string.Empty; if (matchType == CompletionMatchType.MatchDisplayText) { displayText = currentCompletion.DisplayText; } else if (matchType == CompletionMatchType.MatchInsertionText) { displayText = currentCompletion.InsertionText; } int matchPositionCount = 0; for (int i = 0; i < text.Length; i++) { if (i >= displayText.Length) { break; } char textChar = text[i]; char displayTextChar = displayText[i]; if (!caseSensitive) { textChar = char.ToLowerInvariant(textChar); displayTextChar = char.ToLowerInvariant(displayTextChar); } if (textChar != displayTextChar) { break; } matchPositionCount++; } if (matchPositionCount > maxMatchPosition) { maxMatchPosition = matchPositionCount; bestMatch = currentCompletion; isUnique = true; if ((matchPositionCount == text.Length) && (maxMatchPosition > 0)) { isSelected = true; } } else if (matchPositionCount == maxMatchPosition) { isUnique = false; if (isSelected) { break; } } } if (bestMatch != null) { CompletionMatchResult result = new CompletionMatchResult(); result.SelectionStatus = new CompletionSelectionStatus(bestMatch, isSelected, isUnique); result.CharsMatchedCount = (maxMatchPosition >= 0) ? maxMatchPosition : 0; return(result); } } return(null); }
/// <summary> /// Redetermines the best matching completion in the completion set. /// </summary> /// <param name="matchType">The <see cref="CompletionMatchType"/>.</param> /// <param name="caseSensitive"><c>true</c> if the match is case-sensitive, otherwise <c>false</c>.</param> protected void SelectBestMatch(CompletionMatchType matchType, bool caseSensitive) { CompletionMatchResult completionMatch = this.MatchCompletionList ( this.Completions, matchType, caseSensitive ); CompletionMatchResult builderMatch = this.MatchCompletionList ( this.CompletionBuilders, matchType, caseSensitive ); // Only select a builder if it's far-and-away better. Otherwise, select a completion int builderScore = 0; if (builderMatch != null) { builderScore = builderMatch.CharsMatchedCount + (builderMatch.SelectionStatus.IsSelected ? 1 : 0) + (builderMatch.SelectionStatus.IsUnique ? 1 : 0); } int completionScore = 0; if (completionMatch != null) { completionScore = completionMatch.CharsMatchedCount + (completionMatch.SelectionStatus.IsSelected ? 1 : 0) + (completionMatch.SelectionStatus.IsUnique ? 1 : 0); } if ((builderScore > completionScore) && (builderMatch != null)) { this.SelectionStatus = builderMatch.SelectionStatus; } else if (completionMatch != null) { this.SelectionStatus = completionMatch.SelectionStatus; } else if (this.Completions.Count > 0) { // If we've already got a pretty good selection, just leave it selected, but not fully-selected. if (this.Completions.Contains(this.SelectionStatus.Completion)) { this.SelectionStatus = new CompletionSelectionStatus(this.SelectionStatus.Completion, false, false); } else { this.SelectionStatus = new CompletionSelectionStatus(this.Completions[0], false, false); } } else if (this.CompletionBuilders.Count > 0) { // If we've already got a pretty good selection, just leave it selected, but not fully-selected. if (this.CompletionBuilders.Contains(this.SelectionStatus.Completion)) { this.SelectionStatus = new CompletionSelectionStatus(this.SelectionStatus.Completion, false, false); } else { this.SelectionStatus = new CompletionSelectionStatus(this.CompletionBuilders[0], false, false); } } else { this.SelectionStatus = new CompletionSelectionStatus(null, false, false); } }
protected virtual bool DoesCompletionMatchApplicabilityText(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { return(DoesCompletionMatchApplicabilityTextDirect(completion, filterText, matchType, caseSensitive)); }
protected virtual bool DoesCompletionMatchApplicabilityText(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { return DoesCompletionMatchApplicabilityTextDirect(completion, filterText, matchType, caseSensitive); }
/// <summary> /// Matches the completion list. /// </summary> /// <param name="completionList">The list of completions.</param> /// <param name="matchType">The <see cref="CompletionMatchType"/>.</param> /// <param name="caseSensitive"><c>true</c> if the match is case-sensitive, otherwise <c>false</c>.</param> /// <returns>A <see cref="CompletionMatchResult"/>.</returns> /// <exception cref="InvalidOperationException">The span to which this completion applies is null.</exception> protected CompletionMatchResult MatchCompletionList ( IList <Completion> completionList, CompletionMatchType matchType, bool caseSensitive ) { if (_applicableTo == null) { throw new InvalidOperationException("Cannot match completion set with no applicability span."); } // Get the actual text from the buffer ITextSnapshot snapshot = _applicableTo.TextBuffer.CurrentSnapshot; string bufferText = _applicableTo.GetText(snapshot); // Short-circuit if we detect that there's no text to match. if (bufferText.Length == 0) { return(null); } Completion bestMatch = null; int bestMatchNumCharsMatched = -1; bool uniqueMatch = false; bool fullMatch = false; foreach (Completion completion in completionList) { // Determine what text should be matched. string matchText = string.Empty; if (matchType == CompletionMatchType.MatchDisplayText) { matchText = completion.DisplayText; } else if (matchType == CompletionMatchType.MatchInsertionText) { matchText = completion.InsertionText; } // Count the number of characters that match. int numCharsMatched = 0; for (int i = 0; i < bufferText.Length; i++) { if (i >= matchText.Length) { break; } else { char b = bufferText[i]; char m = matchText[i]; if (!caseSensitive) { b = char.ToLowerInvariant(b); m = char.ToLowerInvariant(m); } if (b == m) { numCharsMatched++; } else { break; } } } // See if this completion is the best match. if (numCharsMatched > bestMatchNumCharsMatched) { bestMatchNumCharsMatched = numCharsMatched; bestMatch = completion; // Since we've found a completion with more characters matching than any before, this is now a unique // match uniqueMatch = true; // Let's see if this is also a full match. In order to be a full match, all of the characters in the buffer // must have matched. In addition, we must have at least one character matched. if ((numCharsMatched == bufferText.Length) && (bestMatchNumCharsMatched > 0)) { fullMatch = true; } } else if (numCharsMatched == bestMatchNumCharsMatched) { // We've come across a completion that matches exactly the same number of buffer characters as a previous // completion. We're going to take that to mean that we no longer have a unique match. uniqueMatch = false; // Now that we know we no longer have a unique match, we may be able to break out of the loop without looking at // any more completions. We can only do this if we've matched all of the characters in the applicable-to text, // however. If we've matched all of the text so far, there can't possibly be another completion that will match // more. if (fullMatch) { break; } } } // If there was a match, return it. if (bestMatch != null) { return(new CompletionMatchResult() { SelectionStatus = new CompletionSelectionStatus(bestMatch, fullMatch, uniqueMatch), CharsMatchedCount = bestMatchNumCharsMatched >= 0 ? bestMatchNumCharsMatched : 0 }); } // We didn't find anything. Return an "empty" match status. return(null); }
protected virtual Predicate <Completion> GetFilterPredicate(string filterText, CompletionMatchType matchType, bool caseSensitive) { bool isFilterTextEmpty = string.IsNullOrEmpty(filterText); return(completion => isFilterTextEmpty || DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)); }
protected override bool DoesCompletionMatchApplicabilityText(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { if (base.DoesCompletionMatchApplicabilityText(completion, filterText, matchType, caseSensitive)) { return(true); } object parentObject; completion.Properties.TryGetProperty("parentObject", out parentObject); IStepSuggestionGroup <Completion> parentObjectAsGroup = parentObject as IStepSuggestionGroup <Completion>; return (parentObjectAsGroup != null && parentObjectAsGroup.Suggestions .Any(stepSuggestion => stepSuggestion.NativeSuggestionItem != null && DoesCompletionMatchApplicabilityText(stepSuggestion.NativeSuggestionItem, filterText, matchType, caseSensitive))); }
protected virtual bool DoesCompletionMatchApplicabilityTextDirect(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive) { string displayText = string.Empty; if (matchType == CompletionMatchType.MatchDisplayText) { displayText = completion.DisplayText; } else if (matchType == CompletionMatchType.MatchInsertionText) { displayText = completion.InsertionText; } if (PrefixMatch) { return(displayText.StartsWith(filterText, !caseSensitive, CultureInfo.CurrentCulture)); } StringComparison comparison = caseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; if (string.IsNullOrWhiteSpace(filterText)) { return(false); } var words = filterText.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (words.Length < 1) { return(false); // empty } return(words.All(word => WordPrefixContains(displayText, word, comparison))); // all words should match }
protected override Predicate <Completion> GetFilterPredicate(string filterText, CompletionMatchType matchType, bool caseSensitive) { var basePredicate = base.GetFilterPredicate(filterText, matchType, caseSensitive); return(_limitStepInstances ? LimitStepInstances(_maxStepInstances, basePredicate) : basePredicate); }