Example #1
0
        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));
        }
Example #4
0
 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;
        }
Example #8
0
        /// <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;
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        /// <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));
 }
Example #14
0
 protected virtual bool DoesCompletionMatchApplicabilityText(Completion completion, string filterText, CompletionMatchType matchType, bool caseSensitive)
 {
     return DoesCompletionMatchApplicabilityTextDirect(completion, filterText, matchType, caseSensitive);
 }
Example #15
0
        /// <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));
        }
Example #17
0
        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
        }
Example #19
0
        protected override Predicate <Completion> GetFilterPredicate(string filterText, CompletionMatchType matchType, bool caseSensitive)
        {
            var basePredicate = base.GetFilterPredicate(filterText, matchType, caseSensitive);

            return(_limitStepInstances
                ? LimitStepInstances(_maxStepInstances, basePredicate)
                : basePredicate);
        }