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); }
/// <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); }
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); }
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; } }
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; } }
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; }
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); }
/// <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)); }
public CompletionList WithRules(CompletionRules rules) => With(rules: rules);