From a83f63420b3d61cf934cd1a4bcf3923c0559524d Mon Sep 17 00:00:00 2001 From: Julien Date: Fri, 10 Jun 2016 16:37:51 -0700 Subject: [PATCH] Adding enter-key behavior options for VB and C# (#11769) --- .../AbstractCSharpCompletionProviderTests.cs | 6 ++- ...teNamedParameterCompletionProviderTests.cs | 5 +- .../KeywordCompletionProviderTests.cs | 5 +- .../NamedParameterCompletionProviderTests.cs | 5 +- .../ObjectCreationCompletionProviderTests.cs | 5 +- .../SnippetCompletionProviderTests.cs | 11 +++-- .../SpeculativeTCompletionProviderTests.cs | 5 +- ...olCompletionProviderTests_NoInteractive.cs | 5 +- ...ferenceDirectiveCompletionProviderTests.cs | 5 +- .../Completion/CSharpCompletionOptions.cs | 2 + .../CSharpCompletionOptionsProvider.cs | 1 - .../Completion/CSharpCompletionService.cs | 11 +++-- .../Portable/Completion/CompletionOptions.cs | 3 ++ .../Completion/CompletionOptionsProvider.cs | 3 +- .../CompletionServiceWithProviders.cs | 1 - .../VisualBasicCompletionService.vb | 28 ++++++++--- .../CSharp/Impl/CSharpVSResources.Designer.cs | 33 +++++++++++-- .../CSharp/Impl/CSharpVSResources.resx | 15 ++++-- .../CSharp/Impl/Options/AutomationObject.cs | 16 +++++-- .../CSharpSettingsManagerOptionSerializer.cs | 48 ++++++++++++++++++- .../IntelliSenseOptionPageControl.xaml | 19 ++++++-- .../IntelliSenseOptionPageControl.xaml.cs | 5 +- .../Options/IntelliSenseOptionPageStrings.cs | 17 +++++-- .../Impl/Options/AbstractOptionPageControl.cs | 35 ++++++++++++++ .../Impl/BasicVSResources.Designer.vb | 36 ++++++++++++++ .../VisualBasic/Impl/BasicVSResources.resx | 12 +++++ .../IntelliSenseOptionPageControl.xaml | 18 +++++-- .../IntelliSenseOptionPageControl.xaml.vb | 6 ++- .../Options/IntelliSenseOptionPageStrings.vb | 12 +++++ ...ualBasicSettingsManagerOptionSerializer.vb | 22 ++++++++- 30 files changed, 334 insertions(+), 61 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AbstractCSharpCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AbstractCSharpCompletionProviderTests.cs index ef96e08df84..08ff717742a 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AbstractCSharpCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AbstractCSharpCompletionProviderTests.cs @@ -136,7 +136,7 @@ protected string AddUsingDirectives(string usingDirectives, string text) text; } - protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, string textTypedSoFar, bool sendThroughEnterEnabled, bool expected) + protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, string textTypedSoFar, EnterKeyRule sendThroughEnterOption, bool expected) { using (var workspace = await TestWorkspace.CreateCSharpAsync(initialMarkup)) { @@ -146,7 +146,9 @@ protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, st var position = hostDocument.CursorPosition.Value; workspace.Options = workspace.Options.WithChangedOption( - CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord, sendThroughEnterEnabled); + CompletionOptions.EnterKeyBehavior, + LanguageNames.CSharp, + sendThroughEnterOption); var service = GetCompletionService(workspace); var completionList = await GetCompletionListAsync(service, document, position, CompletionTrigger.Default); diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AttributeNamedParameterCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AttributeNamedParameterCompletionProviderTests.cs index 94e1e9e444f..0a11b09a7c5 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AttributeNamedParameterCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AttributeNamedParameterCompletionProviderTests.cs @@ -39,8 +39,9 @@ public class TestAttribute : Attribute public ConsoleColor Color { get; set; } }"; - await VerifySendEnterThroughToEnterAsync(markup, "Color =", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync(markup, "Color =", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "Color =", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync(markup, "Color =", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "Color =", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs index b3b840e9e26..0665acaab8a 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs @@ -36,8 +36,9 @@ public async Task IsTextualTriggerCharacterTest() [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] public async Task SendEnterThroughToEditorTest() { - await VerifySendEnterThroughToEnterAsync("$$", "class", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync("$$", "class", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync("$$", "class", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync("$$", "class", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync("$$", "class", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/NamedParameterCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/NamedParameterCompletionProviderTests.cs index 74f4cbb5c64..bd5d2eeed16 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/NamedParameterCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/NamedParameterCompletionProviderTests.cs @@ -36,8 +36,9 @@ void Bar() } }"; - await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectCreationCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectCreationCompletionProviderTests.cs index f32a6052987..b405e16785e 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectCreationCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectCreationCompletionProviderTests.cs @@ -143,8 +143,9 @@ static void Main(string[] args) } }"; - await VerifySendEnterThroughToEnterAsync(markup, "D", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync(markup, "D", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "D", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync(markup, "D", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "D", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [WorkItem(828196, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/828196")] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs index 580619e6581..8228c4eae1b 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs @@ -125,11 +125,14 @@ class C [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task CommitWithEnterObeysOption() { - await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcu", sendThroughEnterEnabled: true, expected: false); - await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcut", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcu", sendThroughEnterOption: EnterKeyRule.Always, expected: true); + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcut", sendThroughEnterOption: EnterKeyRule.Always, expected: true); - await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcu", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcut", sendThroughEnterEnabled: false, expected: false); + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcu", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: false); + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcut", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcu", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync("$$", "SnippetShortcut", sendThroughEnterOption: EnterKeyRule.Never, expected: false); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SpeculativeTCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SpeculativeTCompletionProviderTests.cs index 04530a2673e..1f158ef5a01 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SpeculativeTCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SpeculativeTCompletionProviderTests.cs @@ -47,8 +47,9 @@ class C $$ }"; - await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests_NoInteractive.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests_NoInteractive.cs index 814cda914ad..6eec2787ebd 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests_NoInteractive.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests_NoInteractive.cs @@ -44,8 +44,9 @@ public async Task IsTextualTriggerCharacterTest() [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task SendEnterThroughToEditorTest() { - await VerifySendEnterThroughToEnterAsync("class C { void M() { System.Console.$$", "Beep", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync("class C { void M() { System.Console.$$", "Beep", sendThroughEnterEnabled: true, expected: true); + await VerifySendEnterThroughToEnterAsync("class C { void M() { System.Console.$$", "Beep", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync("class C { void M() { System.Console.$$", "Beep", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true); + await VerifySendEnterThroughToEnterAsync("class C { void M() { System.Console.$$", "Beep", sendThroughEnterOption: EnterKeyRule.Always, expected: true); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/EditorFeatures/CSharpTest/Completion/ReferenceDirectiveCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/ReferenceDirectiveCompletionProviderTests.cs index 7888891d6b4..25b6e622043 100644 --- a/src/EditorFeatures/CSharpTest/Completion/ReferenceDirectiveCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/ReferenceDirectiveCompletionProviderTests.cs @@ -87,8 +87,9 @@ public async Task IsTextualTriggerCharacterTest() [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task SendEnterThroughToEditorTest() { - await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", sendThroughEnterEnabled: false, expected: false); - await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", sendThroughEnterEnabled: true, expected: false); + await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", sendThroughEnterOption: EnterKeyRule.Never, expected: false); + await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: false); + await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", sendThroughEnterOption: EnterKeyRule.Always, expected: false); // note: GAC completion helper uses its own EnterKeyRule } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] diff --git a/src/Features/CSharp/Portable/Completion/CSharpCompletionOptions.cs b/src/Features/CSharp/Portable/Completion/CSharpCompletionOptions.cs index 815b5fcb18f..07e95bf3feb 100644 --- a/src/Features/CSharp/Portable/Completion/CSharpCompletionOptions.cs +++ b/src/Features/CSharp/Portable/Completion/CSharpCompletionOptions.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.Options; namespace Microsoft.CodeAnalysis.CSharp.Completion @@ -8,6 +9,7 @@ internal static class CSharpCompletionOptions { public const string FeatureName = "C# Completion"; + [Obsolete("This option is superceded by CompletionOptions.EnterKeyBehavior")] public static readonly Option AddNewLineOnEnterAfterFullyTypedWord = new Option(FeatureName, "Add New Line On Enter After Fully Typed Word", defaultValue: false); public static readonly Option IncludeSnippets = new Option(FeatureName, "Include Code Snippets", defaultValue: true); diff --git a/src/Features/CSharp/Portable/Completion/CSharpCompletionOptionsProvider.cs b/src/Features/CSharp/Portable/Completion/CSharpCompletionOptionsProvider.cs index f0eb2444aaf..73864cdeb61 100644 --- a/src/Features/CSharp/Portable/Completion/CSharpCompletionOptionsProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CSharpCompletionOptionsProvider.cs @@ -13,7 +13,6 @@ internal class CSharpCompletionOptionsProvider : IOptionProvider { private readonly IEnumerable _options = new List { - CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord, CSharpCompletionOptions.IncludeSnippets, }.ToImmutableArray(); diff --git a/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs b/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs index 7db3c864ebb..2844ef145b3 100644 --- a/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs +++ b/src/Features/CSharp/Portable/Completion/CSharpCompletionService.cs @@ -78,9 +78,14 @@ public override CompletionRules GetRules() { var options = _workspace.Options; - var rule = options.GetOption(CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord) - ? EnterKeyRule.AfterFullyTypedWord - : EnterKeyRule.Never; + var rule = options.GetOption(CompletionOptions.EnterKeyBehavior, LanguageNames.CSharp); + + // Although EnterKeyBehavior is a per-language setting, the meaning of an unset setting (Default) differs between C# and VB + // In C# the default means Never to maintain previous behavior + if (rule == EnterKeyRule.Default) + { + rule = EnterKeyRule.Never; + } // use interlocked + stored rules to reduce # of times this gets created when option is different than default var newRules = _latestRules.WithDefaultEnterKeyRule(rule); diff --git a/src/Features/Core/Portable/Completion/CompletionOptions.cs b/src/Features/Core/Portable/Completion/CompletionOptions.cs index 01de449fced..907da69a691 100644 --- a/src/Features/Core/Portable/Completion/CompletionOptions.cs +++ b/src/Features/Core/Portable/Completion/CompletionOptions.cs @@ -14,6 +14,9 @@ internal static class CompletionOptions public static readonly PerLanguageOption TriggerOnTyping = new PerLanguageOption(FeatureName, "TriggerOnTyping", defaultValue: true); public static readonly PerLanguageOption TriggerOnTypingLetters = new PerLanguageOption(FeatureName, "TriggerOnTypingLetters", defaultValue: true); + public static readonly PerLanguageOption EnterKeyBehavior = + new PerLanguageOption(FeatureName, nameof(EnterKeyBehavior), defaultValue: EnterKeyRule.Default); + // Dev15 options public static readonly PerLanguageOption ShowCompletionItemFilters = new PerLanguageOption(FeatureName, nameof(ShowCompletionItemFilters), defaultValue: false); public static readonly PerLanguageOption HighlightMatchingPortionsOfCompletionListItems = new PerLanguageOption(FeatureName, nameof(HighlightMatchingPortionsOfCompletionListItems), defaultValue: false); diff --git a/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs b/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs index a0d45ecfd1c..7a084879499 100644 --- a/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs +++ b/src/Features/Core/Portable/Completion/CompletionOptionsProvider.cs @@ -17,7 +17,8 @@ internal class CompletionOptionsProvider : IOptionProvider CompletionOptions.TriggerOnTyping, CompletionOptions.TriggerOnTypingLetters, CompletionOptions.ShowCompletionItemFilters, - CompletionOptions.HighlightMatchingPortionsOfCompletionListItems); + CompletionOptions.HighlightMatchingPortionsOfCompletionListItems, + CompletionOptions.EnterKeyBehavior); public IEnumerable GetOptions() => _options; } diff --git a/src/Features/Core/Portable/Completion/CompletionServiceWithProviders.cs b/src/Features/Core/Portable/Completion/CompletionServiceWithProviders.cs index 131818843e8..8f02612b213 100644 --- a/src/Features/Core/Portable/Completion/CompletionServiceWithProviders.cs +++ b/src/Features/Core/Portable/Completion/CompletionServiceWithProviders.cs @@ -180,7 +180,6 @@ internal protected CompletionProvider GetProvider(CompletionItem item) var providers = GetProviders(roles, trigger); var completionProviderToIndex = GetCompletionProviderToIndex(providers); - var completionRules = this.GetRules(); var triggeredProviders = ImmutableArray.Empty; switch (trigger.Kind) diff --git a/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb b/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb index 54620ed7486..1fa284df949 100644 --- a/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb +++ b/src/Features/VisualBasic/Portable/Completion/VisualBasicCompletionService.vb @@ -57,17 +57,31 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion End Get End Property - Private Shared s_defaultCompletionRules As CompletionRules = - CompletionRules.Create( - dismissIfEmpty:=True, - dismissIfLastCharacterDeleted:=True, - defaultCommitCharacters:=CompletionRules.Default.DefaultCommitCharacters, - defaultEnterKeyRule:=EnterKeyRule.Always) + Private _latestRules As CompletionRules = CompletionRules.Create( + dismissIfEmpty:=True, + dismissIfLastCharacterDeleted:=True, + defaultCommitCharacters:=CompletionRules.Default.DefaultCommitCharacters, + defaultEnterKeyRule:=EnterKeyRule.Always) Public Overrides Function GetRules() As CompletionRules - Return s_defaultCompletionRules + Dim options = _workspace.Options + + ' Although EnterKeyBehavior is a per-language setting, the meaning of an unset setting (Default) differs between C# And VB + ' In VB the default means Always to maintain previous behavior + Dim rule = options.GetOption(CompletionOptions.EnterKeyBehavior, LanguageNames.VisualBasic) + + If rule = EnterKeyRule.Default Then + rule = EnterKeyRule.Always + End If + + Dim newRules = _latestRules.WithDefaultEnterKeyRule(rule) + + Interlocked.Exchange(_latestRules, newRules) + + Return newRules End Function + Protected Overrides Function GetBuiltInProviders() As ImmutableArray(Of CompletionProvider) Return _completionProviders End Function diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs index c1012dfdabb..e124ac3be1a 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs @@ -123,6 +123,15 @@ internal class CSharpVSResources { } } + /// + /// Looks up a localized string similar to Enter key behavior:. + /// + internal static string Enter_key_behavior_Title { + get { + return ResourceManager.GetString("Enter_key_behavior_Title", resourceCulture); + } + } + /// /// Looks up a localized string similar to Place "finally" on new line. /// @@ -384,6 +393,15 @@ internal class CSharpVSResources { } } + /// + /// Looks up a localized string similar to _Always add new line on enter. + /// + internal static string Option_Always_add_new_line_on_enter { + get { + return ResourceManager.GetString("Option_Always_add_new_line_on_enter", resourceCulture); + } + } + /// /// Looks up a localized string similar to _Show completion list after a character is typed. /// @@ -511,11 +529,20 @@ internal class CSharpVSResources { } /// - /// Looks up a localized string similar to _Add new line on enter after end of fully typed word. + /// Looks up a localized string similar to _Never add new line on enter. + /// + internal static string Option_Never_add_new_line_on_enter { + get { + return ResourceManager.GetString("Option_Never_add_new_line_on_enter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to _Only add new line on enter after end of fully typed word. /// - internal static string Option_InsertNewlineOnEnterWithWholeWord { + internal static string Option_Only_add_new_line_on_enter_with_whole_word { get { - return ResourceManager.GetString("Option_InsertNewlineOnEnterWithWholeWord", resourceCulture); + return ResourceManager.GetString("Option_Only_add_new_line_on_enter_with_whole_word", resourceCulture); } } diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx index 3f0e39478ee..2886264b8e5 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx @@ -381,9 +381,6 @@ _Show completion list after a character is typed - - _Add new line on enter after end of fully typed word - Place _keywords in completion lists @@ -465,4 +462,16 @@ Show completion item _filters + + Enter key behavior: + + + _Only add new line on enter after end of fully typed word + + + _Always add new line on enter + + + _Never add new line on enter + \ No newline at end of file diff --git a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs index ac3be1b5c68..96ee955b752 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs @@ -183,10 +183,10 @@ public int Indent_UnindentLabels } } - public int InsertNewlineOnEnterWithWholeWord + public EnterKeyRule InsertNewlineOnEnterWithWholeWord { - get { return GetBooleanOption(CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord); } - set { SetBooleanOption(CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord, value); } + get { return GetOption(CompletionOptions.EnterKeyBehavior); } + set { SetOption(CompletionOptions.EnterKeyBehavior, value); } } public int NewLines_AnonymousTypeInitializer_EachMember @@ -588,6 +588,11 @@ private int GetBooleanOption(PerLanguageOption key) return _workspace.Options.GetOption(key, LanguageNames.CSharp) ? 1 : 0; } + private T GetOption(PerLanguageOption key) + { + return _workspace.Options.GetOption(key, LanguageNames.CSharp); + } + private void SetBooleanOption(Option key, int value) { _workspace.Options = _workspace.Options.WithChangedOption(key, value != 0); @@ -598,6 +603,11 @@ private void SetBooleanOption(PerLanguageOption key, int value) _workspace.Options = _workspace.Options.WithChangedOption(key, LanguageNames.CSharp, value != 0); } + private void SetOption(PerLanguageOption key, T value) + { + _workspace.Options = _workspace.Options.WithChangedOption(key, LanguageNames.CSharp, value); + } + private int GetBooleanOption(PerLanguageOption key) { var option = _workspace.Options.GetOption(key, LanguageNames.CSharp); diff --git a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs index dbeefb8d510..72ed0fac23c 100644 --- a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs +++ b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs @@ -132,7 +132,6 @@ protected override bool SupportsOption(IOption option, string languageName) if (option == OrganizerOptions.PlaceSystemNamespaceFirst || option == AddImportOptions.SuggestForTypesInReferenceAssemblies || option == AddImportOptions.SuggestForTypesInNuGetPackages || - option == CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord || option == CSharpCompletionOptions.IncludeSnippets || option.Feature == CodeStyleOptions.PerLanguageCodeStyleOption || option.Feature == CSharpCodeStyleOptions.FeatureName || @@ -149,6 +148,7 @@ protected override bool SupportsOption(IOption option, string languageName) option == CompletionOptions.TriggerOnTypingLetters || option == CompletionOptions.ShowCompletionItemFilters || option == CompletionOptions.HighlightMatchingPortionsOfCompletionListItems || + option == CompletionOptions.EnterKeyBehavior || option.Feature == SimplificationOptions.PerLanguageFeatureName || option.Feature == ExtractMethodOptions.FeatureName || option.Feature == ServiceFeatureOnOffOptions.OptionName || @@ -267,6 +267,11 @@ public override bool TryFetch(OptionKey optionKey, out object value) return FetchStyleBool(Style_UseImplicitTypeWherePossible, out value); } + if (optionKey.Option == CompletionOptions.EnterKeyBehavior) + { + return FetchEnterKeyBehavior(optionKey, out value); + } + return base.TryFetch(optionKey, out value); } @@ -276,6 +281,47 @@ private bool FetchStyleBool(string settingName, out object value) return FetchStyleOption(typeStyleValue, out value); } + /// + /// The EnterKeyBehavior option (formerly AddNewLineOnEnterAfterFullyTypedWord) used to only exist in C# and as a boolean. + /// We need to maintain the meaning of the serialized legacy setting. + /// + private bool FetchEnterKeyBehavior(OptionKey optionKey, out object value) + { + if (!base.TryFetch(optionKey, out value)) + { + return false; + } + + if (!value.Equals(EnterKeyRule.Default)) + { + return true; + } + + // if the EnterKeyBehavior setting cannot be loaded, then attempt to load and upgrade the legacy AddNewLineOnEnterAfterFullyTypedWord setting + +#pragma warning disable CS0618 // AddNewLineOnEnterAfterFullyTypedWord is obsolete + if (base.TryFetch(CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord, out value)) +#pragma warning restore CS0618 + { + int intValue = (int)value; + switch (intValue) + { + case 1: + value = EnterKeyRule.AfterFullyTypedWord; + break; + case 0: + default: + value = EnterKeyRule.Never; + break; + } + + return true; + } + + value = EnterKeyRule.Never; + return true; + } + public override bool TryPersist(OptionKey optionKey, object value) { if (this.Manager == null) diff --git a/src/VisualStudio/CSharp/Impl/Options/IntelliSenseOptionPageControl.xaml b/src/VisualStudio/CSharp/Impl/Options/IntelliSenseOptionPageControl.xaml index 33ae8b5f123..fef4bfc5e01 100644 --- a/src/VisualStudio/CSharp/Impl/Options/IntelliSenseOptionPageControl.xaml +++ b/src/VisualStudio/CSharp/Impl/Options/IntelliSenseOptionPageControl.xaml @@ -4,8 +4,8 @@ x:Uid="CSharpOptionsIntelliSenseOptionPageControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:options="clr-namespace:Microsoft.VisualStudio.LanguageServices.Implementation.Options;assembly=Microsoft.VisualStudio.LanguageServices.Implementation" xmlns:local="clr-namespace:Microsoft.VisualStudio.LanguageServices.CSharp.Options" mc:Ignorable="d" d:DesignHeight="350" d:DesignWidth="460"> @@ -29,9 +29,6 @@ Content="{x:Static local:IntelliSenseOptionPageStrings.Option_ShowSnippets}" /> - @@ -39,6 +36,18 @@ x:Name="Show_completion_item_filters" Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Show_completion_item_filters}" /> +