private CompletionList(TextSpan defaultSpan, ImmutableArray<CompletionItem> items, CompletionRules rules, CompletionItem suggestionModeItem)
 {
     this.DefaultSpan = defaultSpan;
     this.Items = items.IsDefault ? ImmutableArray<CompletionItem>.Empty : items;
     this.Rules = rules ?? CompletionRules.Default;
     this.SuggestionModeItem = suggestionModeItem;
 }
 /// <summary>
 /// Creates a new <see cref="CompletionList"/> instance.
 /// </summary>
 /// <param name="defaultSpan">The span of the syntax element at the caret position when the <see cref="CompletionList"/> was created.</param>
 /// <param name="items">The completion items to present to the user.</param>
 /// <param name="rules">The rules used to control behavior of the completion list shown to the user during typing.</param>
 /// <param name="suggestionModeItem">An optional <see cref="CompletionItem"/> that appears selected in the list presented to the user during suggestion mode.</param>
 /// <returns></returns>
 public static CompletionList Create(
     TextSpan defaultSpan,
     ImmutableArray<CompletionItem> items,
     CompletionRules rules = null,
     CompletionItem suggestionModeItem = null)
 {
     return new CompletionList(defaultSpan, FixItemSpans(items, defaultSpan), rules, suggestionModeItem);
 }
Beispiel #3
0
 /// <summary>
 /// Creates a new <see cref="CompletionList"/> instance.
 /// </summary>
 /// <param name="defaultSpan">The span of the syntax element at the caret position when the <see cref="CompletionList"/> was created.</param>
 /// <param name="items">The completion items to present to the user.</param>
 /// <param name="rules">The rules used to control behavior of the completion list shown to the user during typing.</param>
 /// <param name="suggestionModeItem">An optional <see cref="CompletionItem"/> that appears selected in the list presented to the user during suggestion mode.</param>
 /// <returns></returns>
 public static CompletionList Create(
     TextSpan defaultSpan,
     ImmutableArray<CompletionItem> items,
     CompletionRules rules = null,
     CompletionItem suggestionModeItem = null)
 {
     return Create(defaultSpan, items, rules, suggestionModeItem, isExclusive: false);
 }
Beispiel #4
0
 internal static CompletionList Create(
     TextSpan defaultSpan,
     ImmutableArray<CompletionItem> items,
     CompletionRules rules,
     CompletionItem suggestionModeItem,
     bool isExclusive)
 {
     return new CompletionList(
         defaultSpan, FixItemSpans(items, defaultSpan), rules, suggestionModeItem, isExclusive);
 }
Beispiel #5
0
        private CompletionList(
            TextSpan defaultSpan,
            ImmutableArray<CompletionItem> items,
            CompletionRules rules,
            CompletionItem suggestionModeItem,
            bool isExclusive)
        {
            Span = defaultSpan;

            Items = items.NullToEmpty();
            Rules = rules ?? CompletionRules.Default;
            SuggestionModeItem = suggestionModeItem;
            IsExclusive = isExclusive;

            foreach (var item in Items)
            {
                item.Span = defaultSpan;
            }
        }
Beispiel #6
0
        private CompletionList(
            TextSpan defaultSpan,
            ImmutableArray<CompletionItem> items,
            CompletionRules rules,
            CompletionItem suggestionModeItem,
            bool isExclusive)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            DefaultSpan = defaultSpan;
#pragma warning restore CS0618 // Type or member is obsolete
            Span = defaultSpan;

            Items = items.IsDefault ? ImmutableArray<CompletionItem>.Empty : items;
            Rules = rules ?? CompletionRules.Default;
            SuggestionModeItem = suggestionModeItem;
            IsExclusive = isExclusive;

            foreach (var item in Items)
            {
                item.Span = defaultSpan;
            }
        }
Beispiel #7
0
 protected CompletionHelper(CompletionService completionService)
 {
     CompletionService = completionService;
     _language = CompletionService.Language;
     _rules = CompletionService.GetRules();
 }
 /// <summary>
 /// Creates a copy of this <see cref="CompletionList"/> with the <see cref="Rules"/> property changed.
 /// </summary>
 public CompletionList WithRules(CompletionRules rules)
 {
     return With(rules: rules);
 }
            private bool IsHardSelection(
                Model model,
                CompletionItem bestFilterMatch,
                ITextSnapshot textSnapshot,
                CompletionRules completionRules,
                CompletionTriggerInfo triggerInfo,
                CompletionFilterReason reason)
            {
                if (model.Builder != null)
                {
                    return bestFilterMatch != null && bestFilterMatch.DisplayText == model.Builder.DisplayText;
                }

                if (bestFilterMatch == null || model.UseSuggestionCompletionMode)
                {
                    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.GetSubjectBufferFilterSpanInViewBuffer(bestFilterMatch.FilterSpan);
                var fullFilterText = model.GetCurrentTextInSnapshot(viewSpan, textSnapshot, endPoint: null);

                var shouldSoftSelect = completionRules.ShouldSoftSelectItem(GetExternallyUsableCompletionItem(bestFilterMatch), fullFilterText, triggerInfo);
                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, fullFilterText, triggerInfo, reason))
                {
                    return false;
                }

                // There was either filter text, or this was a preselect match.  In either case, we
                // can hard select this.
                return true;
            }
Beispiel #10
0
        private CompletionRules GetCompletionRules()
        {
            _foregroundObject.AssertIsForeground();
            if (_completionRules == null)
            {
                var document = _subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
                if (document != null)
                {
                    var service = document.Project.LanguageServices.GetService<ICompletionService>();
                    if (service != null)
                    {
                        _completionRules = service.GetCompletionRules();
                    }
                }
            }

            return _completionRules;
        }
        private static void ReplaceExistingItem(
            CompletionItem item,
            Dictionary<string, List<CompletionItem>> displayNameToItemsMap,
            CompletionRules completionRules)
        {
            // See if we have an item with 
            var sameNamedItems = displayNameToItemsMap.GetOrAdd(item.DisplayText, s_createList);
            for (int i = 0; i < sameNamedItems.Count; i++)
            {
                var existingItem = sameNamedItems[i];

                Contract.Assert(item.DisplayText == existingItem.DisplayText);

                if (completionRules.ItemsMatch(item, existingItem))
                {
                    sameNamedItems[i] = Disambiguate(item, existingItem);
                    return;
                }
            }

            sameNamedItems.Add(item);
        }
        private static CompletionList MergeAndPruneCompletionLists(IEnumerable<CompletionList> completionLists, CompletionRules completionRules)
        {
            var displayNameToItemsMap = new Dictionary<string, List<CompletionItem>>();
            CompletionItem builder = null;

            foreach (var completionList in completionLists)
            {
                Contract.Assert(completionList != null);

                foreach (var item in completionList.Items)
                {
                    Contract.Assert(item != null);

                    // New items that match an existing item will replace it.
                    ReplaceExistingItem(item, displayNameToItemsMap, completionRules);
                }

                builder = builder ?? completionList.Builder;
            }

            if (displayNameToItemsMap.Count == 0)
            {
                return null;
            }

            // TODO(DustinCa): Revisit performance of this.
            var totalItems = displayNameToItemsMap.Values.Flatten().ToList();
            totalItems.Sort();

            // TODO(DustinCa): This is lossy -- we lose the IsExclusive field. Fix that.

            return new CompletionList(totalItems.ToImmutableArray(), builder);
        }
Beispiel #13
0
 /// <summary>
 /// Creates a copy of this <see cref="CompletionList"/> with the <see cref="Rules"/> property changed.
 /// </summary>
 public CompletionList WithRules(CompletionRules rules)
 {
     return(With(rules: rules));
 }
        private static CompletionList MergeAndPruneCompletionLists(IEnumerable <CompletionList> completionLists, CompletionRules completionRules)
        {
            var            displayNameToItemsMap = new Dictionary <string, List <CompletionItem> >();
            CompletionItem builder = null;

            foreach (var completionList in completionLists)
            {
                Contract.Assert(completionList != null);

                foreach (var item in completionList.Items)
                {
                    Contract.Assert(item != null);

                    // New items that match an existing item will replace it.
                    ReplaceExistingItem(item, displayNameToItemsMap, completionRules);
                }

                builder = builder ?? completionList.Builder;
            }

            if (displayNameToItemsMap.Count == 0)
            {
                return(null);
            }

            // TODO(DustinCa): Revisit performance of this.
            var totalItems = displayNameToItemsMap.Values.Flatten().ToList();

            totalItems.Sort();

            // TODO(DustinCa): This is lossy -- we lose the IsExclusive field. Fix that.

            return(new CompletionList(totalItems.ToImmutableArray(), builder));
        }
Beispiel #15
0
 public CompletionList WithRules(CompletionRules rules) => With(rules: rules);