提交 162e5659 编写于 作者: D David Poeschl

Handle completion items with leading/trailing decorative text

Leading/trailing decorative text can interfere with the pattern
matcher's ability to find/bold matching spans and add redundant items to
the MRU list.
上级 bb1113b2
using System.Collections.Generic;
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.CodeAnalysis.Completion;
......@@ -29,6 +33,8 @@ internal class RoslynCompletionSet : CompletionSet2
protected Dictionary<CompletionItem, VSCompletion> CompletionItemMap;
protected CompletionItem SuggestionModeItem;
private readonly Dictionary<string, string> _displayTextToBoldingTextMap = new Dictionary<string, string>();
protected string FilterText;
public RoslynCompletionSet(
......@@ -90,6 +96,14 @@ public override void Recalculate()
{
_foregroundThread.AssertIsForeground();
foreach (var item in completionItems)
{
if (!_displayTextToBoldingTextMap.ContainsKey(item.DisplayText))
{
_displayTextToBoldingTextMap.Add(item.DisplayText, CompletionHelper.GetDisplayTextForMatching(item));
}
}
// Initialize the completion map to a reasonable default initial size (+1 for the builder)
CompletionItemMap = CompletionItemMap ?? new Dictionary<CompletionItem, VSCompletion>(completionItems.Count + 1);
FilterText = filterText;
......@@ -215,6 +229,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp
return null;
}
var textForBolding = _displayTextToBoldingTextMap.TryGetValue(displayText, out var matchingText) ? matchingText : displayText;
Debug.Assert(displayText.Contains(textForBolding));
var pattern = this.FilterText;
if (_highlightMatchingPortions && !string.IsNullOrWhiteSpace(pattern))
{
......@@ -222,9 +239,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp
if (completionHelper != null)
{
var highlightedSpans = completionHelper.GetHighlightedSpans(
displayText, pattern, CultureInfo.CurrentCulture);
textForBolding, pattern, CultureInfo.CurrentCulture);
return highlightedSpans.SelectAsArray(s => s.ToSpan());
return highlightedSpans.SelectAsArray(s => new Span(s.Start + Math.Max(0, displayText.IndexOf(textForBolding)), s.Length));
}
}
......
......@@ -498,7 +498,7 @@ private bool IsBetterDeletionMatch(FilterResult result1, FilterResult result2)
private static int GetRecentItemIndex(ImmutableArray<string> recentItems, CompletionItem item)
{
var index = recentItems.IndexOf(item.DisplayText);
var index = recentItems.IndexOf(CompletionHelper.GetDisplayTextForMatching(item));
return -index;
}
......
......@@ -174,7 +174,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
}
// Let the completion rules know that this item was committed.
this.MakeMostRecentItem(item.DisplayText);
this.MakeMostRecentItem(CompletionHelper.GetDisplayTextForMatching(item));
}
private void SetCaretPosition(int desiredCaretPosition)
......
......@@ -19,6 +19,11 @@ internal sealed class CompletionHelper
private static readonly CultureInfo EnUSCultureInfo = new CultureInfo("en-US");
private readonly bool _isCaseSensitive;
// Support for completion items with extra decorative characters in their DisplayText.
// This allows bolding and MRU to operate on the "real" display text (without text
// decorations). This should be a substring of the corresponding DisplayText.
private static string DisplayTextForMatching = nameof(DisplayTextForMatching);
public CompletionHelper(bool isCaseSensitive)
{
_isCaseSensitive = isCaseSensitive;
......@@ -252,5 +257,8 @@ private int ComparePreselection(CompletionItem item1, CompletionItem item2)
return 0;
}
internal static string GetDisplayTextForMatching(CompletionItem item)
=> item.Properties.TryGetValue(DisplayTextForMatching, out var displayText) ? displayText : item.DisplayText;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册