未验证 提交 9e2a3769 编写于 作者: D David Poeschl 提交者: GitHub

Merge pull request #26341 from dpoeschl/CompletionBolding

Handle completion items with leading/trailing decorative text
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.Collections.Immutable;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
...@@ -29,6 +33,8 @@ internal class RoslynCompletionSet : CompletionSet2 ...@@ -29,6 +33,8 @@ internal class RoslynCompletionSet : CompletionSet2
protected Dictionary<CompletionItem, VSCompletion> CompletionItemMap; protected Dictionary<CompletionItem, VSCompletion> CompletionItemMap;
protected CompletionItem SuggestionModeItem; protected CompletionItem SuggestionModeItem;
private readonly Dictionary<string, string> _displayTextToBoldingTextMap = new Dictionary<string, string>();
protected string FilterText; protected string FilterText;
public RoslynCompletionSet( public RoslynCompletionSet(
...@@ -90,6 +96,14 @@ public override void Recalculate() ...@@ -90,6 +96,14 @@ public override void Recalculate()
{ {
_foregroundThread.AssertIsForeground(); _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) // Initialize the completion map to a reasonable default initial size (+1 for the builder)
CompletionItemMap = CompletionItemMap ?? new Dictionary<CompletionItem, VSCompletion>(completionItems.Count + 1); CompletionItemMap = CompletionItemMap ?? new Dictionary<CompletionItem, VSCompletion>(completionItems.Count + 1);
FilterText = filterText; FilterText = filterText;
...@@ -215,6 +229,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp ...@@ -215,6 +229,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp
return null; return null;
} }
var textForBolding = _displayTextToBoldingTextMap.TryGetValue(displayText, out var matchingText) ? matchingText : displayText;
Debug.Assert(displayText.Contains(textForBolding));
var pattern = this.FilterText; var pattern = this.FilterText;
if (_highlightMatchingPortions && !string.IsNullOrWhiteSpace(pattern)) if (_highlightMatchingPortions && !string.IsNullOrWhiteSpace(pattern))
{ {
...@@ -222,9 +239,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp ...@@ -222,9 +239,9 @@ public override IReadOnlyList<Span> GetHighlightedSpansInDisplayText(string disp
if (completionHelper != null) if (completionHelper != null)
{ {
var highlightedSpans = completionHelper.GetHighlightedSpans( 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) ...@@ -498,7 +498,7 @@ private bool IsBetterDeletionMatch(FilterResult result1, FilterResult result2)
private static int GetRecentItemIndex(ImmutableArray<string> recentItems, CompletionItem item) private static int GetRecentItemIndex(ImmutableArray<string> recentItems, CompletionItem item)
{ {
var index = recentItems.IndexOf(item.DisplayText); var index = recentItems.IndexOf(CompletionHelper.GetDisplayTextForMatching(item));
return -index; return -index;
} }
......
...@@ -174,7 +174,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item) ...@@ -174,7 +174,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
} }
// Let the completion rules know that this item was committed. // Let the completion rules know that this item was committed.
this.MakeMostRecentItem(item.DisplayText); this.MakeMostRecentItem(CompletionHelper.GetDisplayTextForMatching(item));
} }
private void SetCaretPosition(int desiredCaretPosition) private void SetCaretPosition(int desiredCaretPosition)
......
...@@ -19,6 +19,11 @@ internal sealed class CompletionHelper ...@@ -19,6 +19,11 @@ internal sealed class CompletionHelper
private static readonly CultureInfo EnUSCultureInfo = new CultureInfo("en-US"); private static readonly CultureInfo EnUSCultureInfo = new CultureInfo("en-US");
private readonly bool _isCaseSensitive; 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) public CompletionHelper(bool isCaseSensitive)
{ {
_isCaseSensitive = isCaseSensitive; _isCaseSensitive = isCaseSensitive;
...@@ -252,5 +257,8 @@ private int ComparePreselection(CompletionItem item1, CompletionItem item2) ...@@ -252,5 +257,8 @@ private int ComparePreselection(CompletionItem item1, CompletionItem item2)
return 0; 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.
先完成此消息的编辑!
想要评论请 注册