From b7e39b624bc0c11ff65f48068bb16c0e2b399ed6 Mon Sep 17 00:00:00 2001 From: Ivan Basov Date: Tue, 5 Nov 2019 14:00:10 -0800 Subject: [PATCH] Completion: VSMac TypeScript completion doesn't commit with Enter --- .../AsyncCompletion/CommitManager.cs | 16 ++---------- .../IntelliSense/AsyncCompletion/Helpers.cs | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs index 81fa2b3aacc..9ba506055a3 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/CommitManager.cs @@ -114,8 +114,7 @@ internal CommitManager(ITextView textView, RecentItemsManager recentItemsManager // We can be called before for ShouldCommitCompletion. However, that call does not provide rules applied for the completion item. // Now we check for the commit charcter in the context of Rules that could change the list of commit characters. - // Tab, Enter and Null (call invoke commit) are always commit characters. - if (typeChar != '\t' && typeChar != '\n' && typeChar != '\0' && !IsCommitCharacter(serviceRules, roslynItem, typeChar, filterText)) + if (!Helpers.IsStandardCommitCharacter(typeChar) && !IsCommitCharacter(serviceRules, roslynItem, typeChar, filterText)) { // Returning None means we complete the current session with a void commit. // The Editor then will try to trigger a new completion session for the character. @@ -321,7 +320,7 @@ internal static bool IsCommitCharacter(CompletionRules completionRules, Completi } // general rule: if the filtering text exactly matches the start of the item then it must be a filter character - if (TextTypedSoFarMatchesItem(item, textTypedSoFar)) + if (Helpers.TextTypedSoFarMatchesItem(item, textTypedSoFar)) { return false; } @@ -330,17 +329,6 @@ internal static bool IsCommitCharacter(CompletionRules completionRules, Completi return completionRules.DefaultCommitCharacters.IndexOf(ch) >= 0; } - internal static bool TextTypedSoFarMatchesItem(CompletionItem item, string textTypedSoFar) - { - if (textTypedSoFar.Length > 0) - { - return item.DisplayText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase) || - item.FilterText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase); - } - - return false; - } - internal static bool SendEnterThroughToEditor(CompletionRules rules, RoslynCompletionItem item, string textTypedSoFar) { var rule = item.Rules.EnterKeyRule; diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/Helpers.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/Helpers.cs index b2893dcc389..326ab9aa9d0 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/Helpers.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/Helpers.cs @@ -1,5 +1,6 @@ // 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 Microsoft.CodeAnalysis.Completion; using Microsoft.VisualStudio.Text; using EditorAsyncCompletion = Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; @@ -81,6 +82,12 @@ internal static CompletionFilterReason GetFilterReason(EditorAsyncCompletionData internal static bool IsFilterCharacter(RoslynCompletionItem item, char ch, string textTypedSoFar) { + // Exclude standard commit character upfront because TextTypedSoFarMatchesItem can miss them on non-Windows platforms. + if (IsStandardCommitCharacter(ch)) + { + return false; + } + // First see if the item has any specific filter rules it wants followed. foreach (var rule in item.Rules.FilterCharacterRules) { @@ -106,7 +113,7 @@ internal static bool IsFilterCharacter(RoslynCompletionItem item, char ch, strin } // general rule: if the filtering text exactly matches the start of the item then it must be a filter character - if (CommitManager.TextTypedSoFarMatchesItem(item, textTypedSoFar)) + if (TextTypedSoFarMatchesItem(item, textTypedSoFar)) { return true; } @@ -114,6 +121,22 @@ internal static bool IsFilterCharacter(RoslynCompletionItem item, char ch, strin return false; } + internal static bool TextTypedSoFarMatchesItem(RoslynCompletionItem item, string textTypedSoFar) + { + if (textTypedSoFar.Length > 0) + { + // Note that StartsWith ignores \0 at the end of textTypedSoFar on VS Mac and Mono. + return item.DisplayText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase) || + item.FilterText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase); + } + + return false; + } + + // Tab, Enter and Null (call invoke commit) are always commit characters. + internal static bool IsStandardCommitCharacter(char c) + => c == '\t' || c == '\n' || c == '\0'; + internal static bool TryGetInitialTriggerLocation(EditorAsyncCompletion.IAsyncCompletionSession session, out SnapshotPoint initialTriggerLocation) { if (session is EditorAsyncCompletion.IAsyncCompletionSessionOperations sessionOperations) -- GitLab