Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.Razor.Logging;
using Microsoft.CodeAnalysis.Razor.Settings;
using Microsoft.CodeAnalysis.Razor.Telemetry;
using Microsoft.Internal.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Razor.Settings;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.Settings;
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.Utilities.UnifiedSettings;

Expand All @@ -23,24 +26,91 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Options;
[Export(typeof(IAdvancedSettingsStorage))]
internal class OptionsStorage : IAdvancedSettingsStorage, IDisposable
{
private readonly WritableSettingsStore _writableSettingsStore;
private readonly Lazy<ITelemetryReporter> _telemetryReporter;
private readonly JoinableTask _initializeTask;
private ImmutableArray<string> _taskListDescriptors = [];
private ISettingsReader? _unifiedSettingsReader;
private IDisposable? _unifiedSettingsSubscription;
private bool _changedBeforeSubscription;

public bool FormatOnType
{
get => GetBool(SettingsNames.FormatOnType.LegacyName, defaultValue: true);
set => SetBool(SettingsNames.FormatOnType.LegacyName, value);
}

public bool AutoClosingTags
{
get => GetBool(SettingsNames.AutoClosingTags.LegacyName, defaultValue: true);
set => SetBool(SettingsNames.AutoClosingTags.LegacyName, value);
}

public bool AutoInsertAttributeQuotes
{
get => GetBool(SettingsNames.AutoInsertAttributeQuotes.LegacyName, defaultValue: true);
set => SetBool(SettingsNames.AutoInsertAttributeQuotes.LegacyName, value);
}

public bool ColorBackground
{
get => GetBool(SettingsNames.ColorBackground.LegacyName, defaultValue: false);
set => SetBool(SettingsNames.ColorBackground.LegacyName, value);
}

public bool CodeBlockBraceOnNextLine
{
get => GetBool(SettingsNames.CodeBlockBraceOnNextLine.LegacyName, defaultValue: false);
set => SetBool(SettingsNames.CodeBlockBraceOnNextLine.LegacyName, value);
}

public bool CommitElementsWithSpace
{
get => GetBool(SettingsNames.CommitElementsWithSpace.LegacyName, defaultValue: true);
set => SetBool(SettingsNames.CommitElementsWithSpace.LegacyName, value);
}

public SnippetSetting Snippets
{
get => (SnippetSetting)GetInt(SettingsNames.Snippets.LegacyName, (int)SnippetSetting.All);
set => SetInt(SettingsNames.Snippets.LegacyName, (int)value);
}

public LogLevel LogLevel
{
get => (LogLevel)GetInt(SettingsNames.LogLevel.LegacyName, (int)LogLevel.Warning);
set => SetInt(SettingsNames.LogLevel.LegacyName, (int)value);
}

public bool FormatOnPaste
{
get => GetBool(SettingsNames.FormatOnPaste.LegacyName, defaultValue: true);
set => SetBool(SettingsNames.FormatOnPaste.LegacyName, value);
}

public ImmutableArray<string> TaskListDescriptors
{
get { return _taskListDescriptors; }
}

[ImportingConstructor]
public OptionsStorage(
SVsServiceProvider synchronousServiceProvider,
[Import(typeof(SAsyncServiceProvider))] IAsyncServiceProvider serviceProvider,
Lazy<ITelemetryReporter> telemetryReporter,
JoinableTaskContext joinableTaskContext)
{
var shellSettingsManager = new ShellSettingsManager(synchronousServiceProvider);
_writableSettingsStore = shellSettingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);

_writableSettingsStore.CreateCollection(SettingsNames.LegacyCollection);
_telemetryReporter = telemetryReporter;

_initializeTask = joinableTaskContext.Factory.RunAsync(async () =>
{
var unifiedSettingsManager = await serviceProvider.GetServiceAsync<SVsUnifiedSettingsManager, ISettingsManager>();
var unifiedSettingsManager = await serviceProvider.GetServiceAsync<SVsUnifiedSettingsManager, Utilities.UnifiedSettings.ISettingsManager>();
_unifiedSettingsReader = unifiedSettingsManager.GetReader();
_unifiedSettingsSubscription = _unifiedSettingsReader.SubscribeToChanges(OnUnifiedSettingsChanged, SettingsNames.AllSettings);
_unifiedSettingsSubscription = _unifiedSettingsReader.SubscribeToChanges(OnUnifiedSettingsChanged, SettingsNames.AllSettings.Select(s => s.UnifiedName).ToArray());

await GetTaskListDescriptorsAsync(joinableTaskContext.Factory, serviceProvider);
});
Expand Down Expand Up @@ -98,41 +168,44 @@ public async Task OnChangedAsync(Action<ClientAdvancedSettings> changed)
private EventHandler<ClientAdvancedSettingsChangedEventArgs>? _changed;

public ClientAdvancedSettings GetAdvancedSettings()
=> new(
GetBool(SettingsNames.FormatOnType, defaultValue: true),
GetBool(SettingsNames.AutoClosingTags, defaultValue: true),
GetBool(SettingsNames.AutoInsertAttributeQuotes, defaultValue: true),
GetBool(SettingsNames.ColorBackground, defaultValue: false),
GetBool(SettingsNames.CodeBlockBraceOnNextLine, defaultValue: false),
GetBool(SettingsNames.CommitElementsWithSpace, defaultValue: true),
GetEnum(SettingsNames.Snippets, SnippetSetting.All),
GetEnum(SettingsNames.LogLevel, LogLevel.Warning),
GetBool(SettingsNames.FormatOnPaste, defaultValue: true),
_taskListDescriptors);
=> new(FormatOnType, AutoClosingTags, AutoInsertAttributeQuotes, ColorBackground, CodeBlockBraceOnNextLine, CommitElementsWithSpace, Snippets, LogLevel, FormatOnPaste, TaskListDescriptors);

public bool GetBool(string name, bool defaultValue)
{
if (_unifiedSettingsReader.AssumeNotNull().GetValue<bool>(name) is { Outcome: SettingRetrievalOutcome.Success, Value: { } unifiedValue })
if (_writableSettingsStore.PropertyExists(SettingsNames.LegacyCollection, name))
{
return unifiedValue;
return _writableSettingsStore.GetBoolean(SettingsNames.LegacyCollection, name);
}

return defaultValue;
}

public T GetEnum<T>(string name, T defaultValue) where T : struct, Enum
public void SetBool(string name, bool value)
{
if (_unifiedSettingsReader.AssumeNotNull().GetValue<string>(name) is { Outcome: SettingRetrievalOutcome.Success, Value: { } unifiedValue })
_writableSettingsStore.SetBoolean(SettingsNames.LegacyCollection, name, value);
_telemetryReporter.Value.ReportEvent("OptionChanged", Severity.Normal, new Property(name, value));

NotifyChange();
}

public int GetInt(string name, int defaultValue)
{
if (_writableSettingsStore.PropertyExists(SettingsNames.LegacyCollection, name))
{
if (Enum.TryParse<T>(unifiedValue, ignoreCase: true, out var parsed))
{
return parsed;
}
return _writableSettingsStore.GetInt32(SettingsNames.LegacyCollection, name);
}

return defaultValue;
}

public void SetInt(string name, int value)
{
_writableSettingsStore.SetInt32(SettingsNames.LegacyCollection, name, value);
_telemetryReporter.Value.ReportEvent("OptionChanged", Severity.Normal, new Property(name, value));

NotifyChange();
}

private void NotifyChange()
{
_initializeTask.Join();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Options;

internal static class SettingsNames
{
public const string UnifiedCollection = "languages.razor.advanced";
public record Setting(string LegacyName, string UnifiedName);

public static readonly string FormatOnType = UnifiedCollection + ".formatOnType";
public static readonly string AutoClosingTags = UnifiedCollection + ".autoClosingTags";
public static readonly string AutoInsertAttributeQuotes = UnifiedCollection + ".autoInsertAttributeQuotes";
public static readonly string ColorBackground = UnifiedCollection + ".colorBackground";
public static readonly string CodeBlockBraceOnNextLine = UnifiedCollection + ".codeBlockBraceOnNextLine";
public static readonly string CommitElementsWithSpace = UnifiedCollection + ".commitCharactersWithSpace";
public static readonly string Snippets = UnifiedCollection + ".snippets";
public static readonly string LogLevel = UnifiedCollection + ".logLevel";
public static readonly string FormatOnPaste = UnifiedCollection + ".formatOnPaste";
public const string LegacyCollection = "Razor";
public const string UnifiedCollection = "textEditor.razor.advanced";

public static readonly string[] AllSettings =
public static readonly Setting FormatOnType = new("FormatOnType", UnifiedCollection + ".formatOnType");
public static readonly Setting AutoClosingTags = new("AutoClosingTags", UnifiedCollection + ".autoClosingTags");
public static readonly Setting AutoInsertAttributeQuotes = new("AutoInsertAttributeQuotes", UnifiedCollection + ".autoInsertAttributeQuotes");
public static readonly Setting ColorBackground = new("ColorBackground", UnifiedCollection + ".colorBackground");
public static readonly Setting CodeBlockBraceOnNextLine = new("CodeBlockBraceOnNextLine", UnifiedCollection + ".codeBlockBraceOnNextLine");
public static readonly Setting CommitElementsWithSpace = new("CommitElementsWithSpace", UnifiedCollection + ".commitCharactersWithSpace");
public static readonly Setting Snippets = new("Snippets", UnifiedCollection + ".snippets");
public static readonly Setting LogLevel = new("LogLevel", UnifiedCollection + ".logLevel");
public static readonly Setting FormatOnPaste = new("FormatOnPaste", UnifiedCollection + ".formatOnPaste");

public static readonly Setting[] AllSettings =
[
FormatOnType,
AutoClosingTags,
Expand Down