提交 a83f6342 编写于 作者: J Julien 提交者: GitHub

Adding enter-key behavior options for VB and C# (#11769)

上级 65e71cf9
......@@ -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);
......
......@@ -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)]
......
......@@ -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)]
......
......@@ -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)]
......
......@@ -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")]
......
......@@ -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)]
......
......@@ -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)]
......
......@@ -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)]
......
......@@ -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)]
......
// 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<bool> AddNewLineOnEnterAfterFullyTypedWord = new Option<bool>(FeatureName, "Add New Line On Enter After Fully Typed Word", defaultValue: false);
public static readonly Option<bool> IncludeSnippets = new Option<bool>(FeatureName, "Include Code Snippets", defaultValue: true);
......
......@@ -13,7 +13,6 @@ internal class CSharpCompletionOptionsProvider : IOptionProvider
{
private readonly IEnumerable<IOption> _options = new List<IOption>
{
CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord,
CSharpCompletionOptions.IncludeSnippets,
}.ToImmutableArray();
......
......@@ -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);
......
......@@ -14,6 +14,9 @@ internal static class CompletionOptions
public static readonly PerLanguageOption<bool> TriggerOnTyping = new PerLanguageOption<bool>(FeatureName, "TriggerOnTyping", defaultValue: true);
public static readonly PerLanguageOption<bool> TriggerOnTypingLetters = new PerLanguageOption<bool>(FeatureName, "TriggerOnTypingLetters", defaultValue: true);
public static readonly PerLanguageOption<EnterKeyRule> EnterKeyBehavior =
new PerLanguageOption<EnterKeyRule>(FeatureName, nameof(EnterKeyBehavior), defaultValue: EnterKeyRule.Default);
// Dev15 options
public static readonly PerLanguageOption<bool> ShowCompletionItemFilters = new PerLanguageOption<bool>(FeatureName, nameof(ShowCompletionItemFilters), defaultValue: false);
public static readonly PerLanguageOption<bool> HighlightMatchingPortionsOfCompletionListItems = new PerLanguageOption<bool>(FeatureName, nameof(HighlightMatchingPortionsOfCompletionListItems), defaultValue: false);
......
......@@ -17,7 +17,8 @@ internal class CompletionOptionsProvider : IOptionProvider
CompletionOptions.TriggerOnTyping,
CompletionOptions.TriggerOnTypingLetters,
CompletionOptions.ShowCompletionItemFilters,
CompletionOptions.HighlightMatchingPortionsOfCompletionListItems);
CompletionOptions.HighlightMatchingPortionsOfCompletionListItems,
CompletionOptions.EnterKeyBehavior);
public IEnumerable<IOption> GetOptions() => _options;
}
......
......@@ -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<CompletionProvider>.Empty;
switch (trigger.Kind)
......
......@@ -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
......
......@@ -123,6 +123,15 @@ internal class CSharpVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Enter key behavior:.
/// </summary>
internal static string Enter_key_behavior_Title {
get {
return ResourceManager.GetString("Enter_key_behavior_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Place &quot;finally&quot; on new line.
/// </summary>
......@@ -384,6 +393,15 @@ internal class CSharpVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to _Always add new line on enter.
/// </summary>
internal static string Option_Always_add_new_line_on_enter {
get {
return ResourceManager.GetString("Option_Always_add_new_line_on_enter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Show completion list after a character is typed.
/// </summary>
......@@ -511,11 +529,20 @@ internal class CSharpVSResources {
}
/// <summary>
/// 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.
/// </summary>
internal static string Option_Never_add_new_line_on_enter {
get {
return ResourceManager.GetString("Option_Never_add_new_line_on_enter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Only add new line on enter after end of fully typed word.
/// </summary>
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);
}
}
......
......@@ -381,9 +381,6 @@
<data name="Option_BringUpOnIdentifier" xml:space="preserve">
<value>_Show completion list after a character is typed</value>
</data>
<data name="Option_InsertNewlineOnEnterWithWholeWord" xml:space="preserve">
<value>_Add new line on enter after end of fully typed word</value>
</data>
<data name="Option_ShowKeywords" xml:space="preserve">
<value>Place _keywords in completion lists</value>
</data>
......@@ -465,4 +462,16 @@
<data name="Option_Show_completion_item_filters" xml:space="preserve">
<value>Show completion item _filters</value>
</data>
<data name="Enter_key_behavior_Title" xml:space="preserve">
<value>Enter key behavior:</value>
</data>
<data name="Option_Only_add_new_line_on_enter_with_whole_word" xml:space="preserve">
<value>_Only add new line on enter after end of fully typed word</value>
</data>
<data name="Option_Always_add_new_line_on_enter" xml:space="preserve">
<value>_Always add new line on enter</value>
</data>
<data name="Option_Never_add_new_line_on_enter" xml:space="preserve">
<value>_Never add new line on enter</value>
</data>
</root>
\ No newline at end of file
......@@ -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<bool> key)
return _workspace.Options.GetOption(key, LanguageNames.CSharp) ? 1 : 0;
}
private T GetOption<T>(PerLanguageOption<T> key)
{
return _workspace.Options.GetOption(key, LanguageNames.CSharp);
}
private void SetBooleanOption(Option<bool> key, int value)
{
_workspace.Options = _workspace.Options.WithChangedOption(key, value != 0);
......@@ -598,6 +603,11 @@ private void SetBooleanOption(PerLanguageOption<bool> key, int value)
_workspace.Options = _workspace.Options.WithChangedOption(key, LanguageNames.CSharp, value != 0);
}
private void SetOption<T>(PerLanguageOption<T> key, T value)
{
_workspace.Options = _workspace.Options.WithChangedOption(key, LanguageNames.CSharp, value);
}
private int GetBooleanOption(PerLanguageOption<bool?> key)
{
var option = _workspace.Options.GetOption(key, LanguageNames.CSharp);
......
......@@ -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<bool>(typeStyleValue, out value);
}
/// <summary>
/// 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.
/// </summary>
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)
......
......@@ -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}" />
</StackPanel>
<CheckBox x:Uid="InsertNewlineOnEnterWithWholeWord"
x:Name="InsertNewlineOnEnterWithWholeWord"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_InsertNewlineOnEnterWithWholeWord}" />
<CheckBox x:Uid="Highlight_matching_portions_of_completion_list_items"
x:Name="Highlight_matching_portions_of_completion_list_items"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Highlight_matching_portions_of_completion_list_items}" />
......@@ -39,6 +36,18 @@
x:Name="Show_completion_item_filters"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Show_completion_item_filters}" />
<Label Content="{x:Static local:IntelliSenseOptionPageStrings.Enter_key_behavior_Title}"/>
<StackPanel Margin="15, 0, 0, 0">
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Never_add_new_line_on_enter"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Never_add_new_line_on_enter}"/>
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Only_add_new_line_on_enter_with_whole_word"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Only_add_new_line_on_enter_with_whole_word}"/>
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Always_add_new_line_on_enter"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Always_add_new_line_on_enter}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
......
......@@ -16,10 +16,13 @@ public IntelliSenseOptionPageControl(IServiceProvider serviceProvider) : base(se
BindToOption(Show_completion_item_filters, CompletionOptions.ShowCompletionItemFilters, LanguageNames.CSharp);
BindToOption(Highlight_matching_portions_of_completion_list_items, CompletionOptions.HighlightMatchingPortionsOfCompletionListItems, LanguageNames.CSharp);
BindToOption(InsertNewlineOnEnterWithWholeWord, CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord);
BindToOption(ShowSnippets, CSharpCompletionOptions.IncludeSnippets);
BindToOption(ShowKeywords, CompletionOptions.IncludeKeywords, LanguageNames.CSharp);
BindToOption(BringUpOnIdentifier, CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp);
BindToOption(Never_add_new_line_on_enter, CompletionOptions.EnterKeyBehavior, EnterKeyRule.Never, LanguageNames.CSharp);
BindToOption(Only_add_new_line_on_enter_with_whole_word, CompletionOptions.EnterKeyBehavior, EnterKeyRule.AfterFullyTypedWord, LanguageNames.CSharp);
BindToOption(Always_add_new_line_on_enter, CompletionOptions.EnterKeyBehavior, EnterKeyRule.Always, LanguageNames.CSharp);
}
private void BringUpOnIdentifier_Checked(object sender, System.Windows.RoutedEventArgs e)
......
......@@ -14,11 +14,6 @@ public static string Option_CompletionLists
get { return CSharpVSResources.Option_CompletionLists; }
}
public static string Option_InsertNewlineOnEnterWithWholeWord
{
get { return CSharpVSResources.Option_InsertNewlineOnEnterWithWholeWord; }
}
public static string Option_SelectionInCompletionList
{
get { return CSharpVSResources.Option_SelectionInCompletionList; }
......@@ -39,5 +34,17 @@ public static string Option_ShowSnippets
public static string Option_Show_completion_item_filters =>
CSharpVSResources.Option_Show_completion_item_filters;
public static string Enter_key_behavior_Title =>
CSharpVSResources.Enter_key_behavior_Title;
public static string Option_Never_add_new_line_on_enter =>
CSharpVSResources.Option_Never_add_new_line_on_enter;
public static string Option_Only_add_new_line_on_enter_with_whole_word =>
CSharpVSResources.Option_Only_add_new_line_on_enter_with_whole_word;
public static string Option_Always_add_new_line_on_enter =>
CSharpVSResources.Option_Always_add_new_line_on_enter;
}
}
......@@ -39,6 +39,11 @@ public AbstractOptionPageControl(IServiceProvider serviceProvider)
textBoxStyle.Setters.Add(new Setter(TextBox.MarginProperty, new Thickness() { Left = 7, Right = 7 }));
textBoxStyle.Setters.Add(new Setter(TextBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey)));
Resources.Add(typeof(TextBox), textBoxStyle);
var radioButtonStyle = new System.Windows.Style(typeof(RadioButton));
radioButtonStyle.Setters.Add(new Setter(RadioButton.MarginProperty, new Thickness() { Bottom = 7 }));
radioButtonStyle.Setters.Add(new Setter(RadioButton.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey)));
Resources.Add(typeof(RadioButton), radioButtonStyle);
}
protected void AddBinding(BindingExpressionBase bindingExpression)
......@@ -98,6 +103,21 @@ protected void BindToOption(TextBox textBox, PerLanguageOption<int> optionKey, s
_bindingExpressions.Add(bindingExpression);
}
protected void BindToOption<T>(RadioButton radiobutton, PerLanguageOption<T> optionKey, T optionValue, string languageName)
{
var binding = new Binding()
{
Source = new PerLanguageOptionBinding<T>(OptionService, optionKey, languageName),
Path = new PropertyPath("Value"),
UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
Converter = new RadioButtonCheckedConverter(),
ConverterParameter = optionValue
};
var bindingExpression = radiobutton.SetBinding(RadioButton.IsCheckedProperty, binding);
_bindingExpressions.Add(bindingExpression);
}
protected void BindToFullSolutionAnalysisOption(CheckBox checkbox, string languageName)
{
// Full solution analysis option has been moved to error list from Dev14 Update3.
......@@ -146,4 +166,19 @@ internal virtual void Close()
{
}
}
public class RadioButtonCheckedConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}
}
......@@ -73,6 +73,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Enter key behavior:.
'''</summary>
Friend Shared ReadOnly Property Enter_key_behavior_Title() As String
Get
Return ResourceManager.GetString("Enter_key_behavior_Title", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Insert Snippet.
'''</summary>
......@@ -109,6 +118,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to _Always add new line on enter.
'''</summary>
Friend Shared ReadOnly Property Option_Always_add_new_line_on_enter() As String
Get
Return ResourceManager.GetString("Option_Always_add_new_line_on_enter", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Automatic _insertion of Interface and MustOverride members.
'''</summary>
......@@ -271,6 +289,24 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to _Never add new line on enter.
'''</summary>
Friend Shared ReadOnly Property Option_Never_add_new_line_on_enter() As String
Get
Return ResourceManager.GetString("Option_Never_add_new_line_on_enter", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to _Only add new line on enter after end of fully typed word.
'''</summary>
Friend Shared ReadOnly Property Option_Only_add_new_line_on_enter_with_whole_word() As String
Get
Return ResourceManager.GetString("Option_Only_add_new_line_on_enter_with_whole_word", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Optimize for solution size.
'''</summary>
......
......@@ -246,4 +246,16 @@
<data name="Option_CompletionLists" xml:space="preserve">
<value>Completion Lists</value>
</data>
<data name="Enter_key_behavior_Title" xml:space="preserve">
<value>Enter key behavior:</value>
</data>
<data name="Option_Only_add_new_line_on_enter_with_whole_word" xml:space="preserve">
<value>_Only add new line on enter after end of fully typed word</value>
</data>
<data name="Option_Always_add_new_line_on_enter" xml:space="preserve">
<value>_Always add new line on enter</value>
</data>
<data name="Option_Never_add_new_line_on_enter" xml:space="preserve">
<value>_Never add new line on enter</value>
</data>
</root>
\ No newline at end of file
......@@ -4,8 +4,8 @@
x:Uid="VisualBasicIntelliSenseOptionPageControl"
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.VisualBasic.Options"
mc:Ignorable="d" d:DesignHeight="350" d:DesignWidth="460">
......@@ -15,14 +15,24 @@
<GroupBox x:Uid="CompletionListsGroupBox"
Header="{x:Static local:IntelliSenseOptionPageStrings.Option_CompletionLists}">
<StackPanel>
<CheckBox x:Uid="Highlight_matching_portions_of_completion_list_items"
x:Name="Highlight_matching_portions_of_completion_list_items"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Highlight_matching_portions_of_completion_list_items}" />
<CheckBox x:Uid="Show_completion_item_filters"
x:Name="Show_completion_item_filters"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Show_completion_item_filters}" />
<Label Content="{x:Static local:IntelliSenseOptionPageStrings.Enter_key_behavior_Title}"/>
<StackPanel Margin="15, 0, 0, 0">
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Never_add_new_line_on_enter"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Never_add_new_line_on_enter}"/>
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Only_add_new_line_on_enter_with_whole_word"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Only_add_new_line_on_enter_with_whole_word}"/>
<RadioButton GroupName="InsertNewlineOnEnterRadio"
x:Name="Always_add_new_line_on_enter"
Content="{x:Static local:IntelliSenseOptionPageStrings.Option_Always_add_new_line_on_enter}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Completion
Imports Microsoft.CodeAnalysis.VisualBasic.Completion
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Options
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
......@@ -16,6 +14,10 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
BindToOption(Show_completion_item_filters, CompletionOptions.ShowCompletionItemFilters, LanguageNames.VisualBasic)
BindToOption(Highlight_matching_portions_of_completion_list_items, CompletionOptions.HighlightMatchingPortionsOfCompletionListItems, LanguageNames.VisualBasic)
BindToOption(Never_add_new_line_on_enter, CompletionOptions.EnterKeyBehavior, EnterKeyRule.Never, LanguageNames.VisualBasic)
BindToOption(Only_add_new_line_on_enter_with_whole_word, CompletionOptions.EnterKeyBehavior, EnterKeyRule.AfterFullyTypedWord, LanguageNames.VisualBasic)
BindToOption(Always_add_new_line_on_enter, CompletionOptions.EnterKeyBehavior, EnterKeyRule.Always, LanguageNames.VisualBasic)
End Sub
End Class
End Namespace
\ No newline at end of file
......@@ -10,5 +10,17 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
Public ReadOnly Property Option_Show_completion_item_filters As String =
BasicVSResources.Option_Show_completion_item_filters
Public ReadOnly Property Option_Only_add_new_line_on_enter_with_whole_word As String =
BasicVSResources.Option_Only_add_new_line_on_enter_with_whole_word
Public ReadOnly Property Option_Always_add_new_line_on_enter As String =
BasicVSResources.Option_Always_add_new_line_on_enter
Public ReadOnly Property Option_Never_add_new_line_on_enter As String =
BasicVSResources.Option_Never_add_new_line_on_enter
Public ReadOnly Property Enter_key_behavior_Title As String =
BasicVSResources.Enter_key_behavior_Title
End Module
End Namespace
\ No newline at end of file
......@@ -13,6 +13,7 @@ Imports Microsoft.CodeAnalysis.Formatting
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Shared.Options
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic.Completion
Imports Microsoft.VisualStudio.LanguageServices.Implementation
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Options
Imports Microsoft.VisualStudio.Shell
......@@ -85,7 +86,10 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
End Property
Protected Overrides Function SupportsOption([option] As IOption, languageName As String) As Boolean
If languageName = LanguageNames.VisualBasic Then
If [option].Name = CompletionOptions.EnterKeyBehavior.Name Then
Return True
ElseIf languageName = LanguageNames.VisualBasic Then
If [option].Feature = FeatureOnOffOptions.OptionName Then
Return [option].Name = FeatureOnOffOptions.PrettyListing.Name OrElse
[option].Name = FeatureOnOffOptions.LineSeparator.Name OrElse
......@@ -157,9 +161,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
Return FetchStyleBool(Style_QualifyEventAccess, value)
End If
If optionKey.Option Is CompletionOptions.EnterKeyBehavior Then
Return FetchEnterKeyBehavior(optionKey, value)
End If
Return MyBase.TryFetch(optionKey, value)
End Function
Private Function FetchEnterKeyBehavior(optionKey As OptionKey, ByRef value As Object) As Boolean
If MyBase.TryFetch(optionKey, value) Then
If value.Equals(EnterKeyRule.Default) Then
value = EnterKeyRule.Always
End If
Return True
End If
Return False
End Function
Public Overrides Function TryPersist(optionKey As OptionKey, value As Object) As Boolean
If Me.Manager Is Nothing Then
Debug.Fail("Manager is unexpectedly Nothing")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册