Skip to content

Commit 5d06658

Browse files
authored
* Partial fix for dotnet/vscode-csharp#7678 * Fix C# commit characters In VSCode case they are returned by Roslyn via CompletionList.ItemDefaults.CommitCharacters rather than VSInternalCompletionList.CommitCharacters, so make sure we don't lose ItemDefaults.CommitCharacters. Also make sure not to merge unnecessarily when razorCompletionList is non-null but empty. * Remove unnecessary HashSet creation per CR * Fixing tests
1 parent d96ce21 commit 5d06658

File tree

3 files changed

+24
-17
lines changed

3 files changed

+24
-17
lines changed

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ internal static class CompletionListMerger
2222
[return: NotNullIfNotNull(nameof(delegatedCompletionList))]
2323
public static RazorVSInternalCompletionList? Merge(RazorVSInternalCompletionList? razorCompletionList, RazorVSInternalCompletionList? delegatedCompletionList)
2424
{
25-
if (razorCompletionList is null)
25+
// In VSCode case we always think completion was invoked explicitly and create empty Razor completion list,
26+
// so check for empty Items collection as well.
27+
if (razorCompletionList is null || razorCompletionList.Items.Length == 0)
2628
{
2729
return delegatedCompletionList;
2830
}
@@ -38,7 +40,8 @@ internal static class CompletionListMerger
3840
var mergedIsIncomplete = razorCompletionList.IsIncomplete || delegatedCompletionList.IsIncomplete;
3941
var mergedItems = razorCompletionList.Items.Concat(delegatedCompletionList.Items).ToArray();
4042
var mergedData = MergeData(razorCompletionList.Data, delegatedCompletionList.Data);
41-
var mergedCommitCharacters = razorCompletionList.CommitCharacters ?? delegatedCompletionList.CommitCharacters;
43+
var mergedCommitCharacters = razorCompletionList.CommitCharacters
44+
?? delegatedCompletionList.CommitCharacters;
4245
var mergedSuggestionMode = razorCompletionList.SuggestionMode || delegatedCompletionList.SuggestionMode;
4346

4447
// We don't fully support merging continue characters currently. Razor doesn't currently use them so delegated completion lists always win.
@@ -60,6 +63,8 @@ internal static class CompletionListMerger
6063
{
6164
Data = mergedItemDefaultsData,
6265
EditRange = mergedItemDefaultsEditRange,
66+
// VSCode won't use VSInternalCompletionList.CommitCharacters, make sure we don't lose item defaults
67+
CommitCharacters = razorCompletionList.ItemDefaults?.CommitCharacters ?? delegatedCompletionList.ItemDefaults?.CommitCharacters
6368
}
6469
};
6570

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionTriggerAndCommitCharacters.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal class CompletionTriggerAndCommitCharacters
1818
private static readonly char[] s_vsCodeHtmlTriggerCharacters = ['#', '.', '!', ',', '-', '<'];
1919
private static readonly char[] s_razorTriggerCharacters = ['<', ':', ' '];
2020
private static readonly char[] s_csharpTriggerCharacters = [' ', '(', '=', '#', '.', '<', '[', '{', '"', '/', ':', '~'];
21-
private static readonly char[] s_commitCharacters = [' ', '>', ';', '='];
21+
private static readonly ImmutableArray<string> s_commitCharacters = [" ", ">", ";", "="];
2222

2323
private readonly HashSet<char> _csharpTriggerCharacters;
2424
private readonly HashSet<char> _delegationTriggerCharacters;
@@ -67,15 +67,16 @@ public CompletionTriggerAndCommitCharacters(LanguageServerFeatureOptions languag
6767
allTriggerCharacters.UnionWith(razorTriggerCharacters);
6868
allTriggerCharacters.UnionWith(delegationTriggerCharacters);
6969

70-
var commitCharacters = new HashSet<char>();
71-
commitCharacters.UnionWith(s_commitCharacters);
72-
7370
_csharpTriggerCharacters = csharpTriggerCharacters;
7471
_htmlTriggerCharacters = htmlTriggerCharacters;
7572
_razorTriggerCharacters = razorTriggerCharacters;
7673
_delegationTriggerCharacters = delegationTriggerCharacters;
74+
75+
// We shouldn't specify commit characters for VSCode.
76+
// It doesn't appear to need them and they interfere with normal item commit.
77+
// E.g. see https://github.com/dotnet/vscode-csharp/issues/7678
78+
AllCommitCharacters = languageServerFeatureOptions.UseVsCodeCompletionTriggerCharacters ? [] : s_commitCharacters;
7779
AllTriggerCharacters = allTriggerCharacters.SelectAsArray(static c => c.ToString());
78-
AllCommitCharacters = commitCharacters.SelectAsArray(static c => c.ToString());
7980
}
8081

8182
public bool IsValidCSharpTrigger(CompletionContext completionContext)

src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/CompletionListProviderTest.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion;
2121

2222
public class CompletionListProviderTest : LanguageServerTestBase
2323
{
24-
private readonly RazorVSInternalCompletionList _completionList1;
25-
private readonly RazorVSInternalCompletionList _completionList2;
24+
private readonly RazorVSInternalCompletionList _razorCompletionList;
25+
private readonly RazorVSInternalCompletionList _delegatedCompletionList;
2626
private readonly RazorCompletionListProvider _razorCompletionProvider;
2727
private readonly DelegatedCompletionListProvider _delegatedCompletionProvider;
2828
private readonly VSInternalCompletionContext _completionContext;
@@ -34,10 +34,10 @@ public class CompletionListProviderTest : LanguageServerTestBase
3434
public CompletionListProviderTest(ITestOutputHelper testOutput)
3535
: base(testOutput)
3636
{
37-
_completionList1 = new RazorVSInternalCompletionList() { Items = [] };
38-
_completionList2 = new RazorVSInternalCompletionList() { Items = [] };
39-
_razorCompletionProvider = new TestRazorCompletionListProvider(_completionList1, LoggerFactory);
40-
_delegatedCompletionProvider = new TestDelegatedCompletionListProvider(_completionList2);
37+
_razorCompletionList = new RazorVSInternalCompletionList() { Items = [] };
38+
_delegatedCompletionList = new RazorVSInternalCompletionList() { Items = [] };
39+
_razorCompletionProvider = new TestRazorCompletionListProvider(_razorCompletionList, LoggerFactory);
40+
_delegatedCompletionProvider = new TestDelegatedCompletionListProvider(_delegatedCompletionList);
4141
_completionContext = new VSInternalCompletionContext();
4242
_documentContext = TestDocumentContext.Create("C:/path/to/file.cshtml");
4343
_clientCapabilities = new VSInternalClientCapabilities();
@@ -52,12 +52,13 @@ public async Task MultipleCompletionLists_Merges()
5252
var provider = new CompletionListProvider(_razorCompletionProvider, _delegatedCompletionProvider, _triggerAndCommitCharacters);
5353

5454
// Act
55-
var completionList = await provider.GetCompletionListAsync(
55+
var mergedCompletionList = await provider.GetCompletionListAsync(
5656
absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, _razorCompletionOptions, correlationId: Guid.Empty, cancellationToken: DisposalToken);
5757

5858
// Assert
59-
Assert.NotSame(_completionList1, completionList);
60-
Assert.NotSame(_completionList2, completionList);
59+
Assert.Empty(mergedCompletionList.Items);
60+
Assert.NotSame(_razorCompletionList, mergedCompletionList);
61+
Assert.Same(_delegatedCompletionList, mergedCompletionList);
6162
}
6263

6364
[Fact]
@@ -75,7 +76,7 @@ public async Task MultipleCompletionLists_DifferentCommitCharacters_OnlyCallsApp
7576
absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, _razorCompletionOptions, correlationId: Guid.Empty, cancellationToken: DisposalToken);
7677

7778
// Assert
78-
Assert.Same(_completionList2, completionList);
79+
Assert.Same(_delegatedCompletionList, completionList);
7980
}
8081

8182
private class TestDelegatedCompletionListProvider : DelegatedCompletionListProvider

0 commit comments

Comments
 (0)