private static bool MatchesFilterText(
                CompletionHelper helper, CompletionItem item,
                string filterText, CompletionTrigger trigger,
                CompletionFilterReason filterReason, ImmutableArray <string> recentItems)
            {
                // For the deletion we bake in the core logic for how matching should work.
                // This way deletion feels the same across all languages that opt into deletion
                // as a completion trigger.

                // Specifically, to avoid being too aggressive when matching an item during
                // completion, we require that the current filter text be a prefix of the
                // item in the list.
                if (filterReason == CompletionFilterReason.Deletion &&
                    trigger.Kind == CompletionTriggerKind.Deletion)
                {
                    return(item.FilterText.GetCaseInsensitivePrefixLength(filterText) > 0);
                }

                // If the user hasn't typed anything, and this item was preselected, or was in the
                // MRU list, then we definitely want to include it.
                if (filterText.Length == 0)
                {
                    if (item.Rules.MatchPriority > MatchPriority.Default)
                    {
                        return(true);
                    }

                    if (!recentItems.IsDefault && GetRecentItemIndex(recentItems, item) <= 0)
                    {
                        return(true);
                    }
                }

                return(helper.MatchesFilterText(item, filterText, CultureInfo.CurrentCulture));
            }
        private static bool MatchesFilterText(CompletionHelper helper, CompletionItem item, SourceText text, Dictionary <TextSpan, string> textSpanToText, CompletionTrigger completionTrigger)
        {
            var filterText = GetFilterText(item, text, textSpanToText);

            if (string.IsNullOrEmpty(filterText))
            {
                return(true);
            }
            return(helper.MatchesFilterText(item, filterText, completionTrigger));
        }
Example #3
0
            private bool IsHardSelection(
                Model model,
                PresentationItem bestFilterMatch,
                ITextSnapshot textSnapshot,
                CompletionHelper completionRules,
                CompletionTrigger trigger,
                CompletionFilterReason reason)
            {
                if (model.SuggestionModeItem != null)
                {
                    return(bestFilterMatch != null && bestFilterMatch.Item.DisplayText == model.SuggestionModeItem.Item.DisplayText);
                }

                if (bestFilterMatch == null || model.UseSuggestionMode)
                {
                    return(false);
                }

                // We don't have a builder and we have a best match.  Normally this will be hard
                // selected, except for a few cases.  Specifically, if no filter text has been
                // provided, and this is not a preselect match then we will soft select it.  This
                // happens when the completion list comes up implicitly and there is something in
                // the MRU list.  In this case we do want to select it, but not with a hard
                // selection.  Otherwise you can end up with the following problem:
                //
                //  dim i as integer =<space>
                //
                // Completion will comes up after = with 'integer' selected (Because of MRU).  We do
                // not want 'space' to commit this.
                var viewSpan       = model.GetViewBufferSpan(bestFilterMatch.Item.Span);
                var fullFilterText = model.GetCurrentTextInSnapshot(viewSpan, textSnapshot, endPoint: null);

                var shouldSoftSelect = completionRules.ShouldSoftSelectItem(bestFilterMatch.Item, fullFilterText, trigger);

                if (shouldSoftSelect)
                {
                    return(false);
                }

                // If the user moved the caret left after they started typing, the 'best' match may not match at all
                // against the full text span that this item would be replacing.
                if (!completionRules.MatchesFilterText(bestFilterMatch.Item, fullFilterText, trigger, reason, this.Controller.GetRecentItems()))
                {
                    return(false);
                }

                // There was either filter text, or this was a preselect match.  In either case, we
                // can hard select this.
                return(true);
            }
            private static bool MatchesFilterText(
                CompletionHelper helper, CompletionItem item,
                string filterText, CompletionTrigger trigger,
                CompletionFilterReason filterReason, ImmutableArray <string> recentItems)
            {
                // For the deletion we bake in the core logic for how matching should work.
                // This way deletion feels the same across all languages that opt into deletion
                // as a completion trigger.

                // Specifically, to avoid being too aggressive when matching an item during
                // completion, we require that the current filter text be a prefix of the
                // item in the list.
                if (filterReason == CompletionFilterReason.BackspaceOrDelete &&
                    trigger.Kind == CompletionTriggerKind.Deletion)
                {
                    return(item.FilterText.GetCaseInsensitivePrefixLength(filterText) > 0);
                }

                return(helper.MatchesFilterText(item, filterText, trigger, recentItems));
            }