22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System ;
5+ using System . Collections . Generic ;
56using System . Collections . Immutable ;
67using System . ComponentModel . Composition ;
8+ using System . Linq ;
79using System . Threading . Tasks ;
8- using Microsoft . AspNetCore . Razor ;
910using Microsoft . AspNetCore . Razor . PooledObjects ;
1011using Microsoft . CodeAnalysis . Razor . Logging ;
1112using Microsoft . CodeAnalysis . Razor . Settings ;
1213using Microsoft . CodeAnalysis . Razor . Telemetry ;
1314using Microsoft . Internal . VisualStudio . Shell . Interop ;
1415using Microsoft . VisualStudio . Razor . Settings ;
16+ using Microsoft . VisualStudio . Settings ;
1517using Microsoft . VisualStudio . Shell ;
1618using Microsoft . VisualStudio . Shell . Interop ;
19+ using Microsoft . VisualStudio . Shell . Settings ;
1720using Microsoft . VisualStudio . Threading ;
1821using Microsoft . VisualStudio . Utilities . UnifiedSettings ;
1922
@@ -23,24 +26,91 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Options;
2326[ Export ( typeof ( IAdvancedSettingsStorage ) ) ]
2427internal class OptionsStorage : IAdvancedSettingsStorage , IDisposable
2528{
29+ private readonly WritableSettingsStore _writableSettingsStore ;
30+ private readonly Lazy < ITelemetryReporter > _telemetryReporter ;
2631 private readonly JoinableTask _initializeTask ;
2732 private ImmutableArray < string > _taskListDescriptors = [ ] ;
2833 private ISettingsReader ? _unifiedSettingsReader ;
2934 private IDisposable ? _unifiedSettingsSubscription ;
3035 private bool _changedBeforeSubscription ;
3136
37+ public bool FormatOnType
38+ {
39+ get => GetBool ( SettingsNames . FormatOnType . LegacyName , defaultValue : true ) ;
40+ set => SetBool ( SettingsNames . FormatOnType . LegacyName , value ) ;
41+ }
42+
43+ public bool AutoClosingTags
44+ {
45+ get => GetBool ( SettingsNames . AutoClosingTags . LegacyName , defaultValue : true ) ;
46+ set => SetBool ( SettingsNames . AutoClosingTags . LegacyName , value ) ;
47+ }
48+
49+ public bool AutoInsertAttributeQuotes
50+ {
51+ get => GetBool ( SettingsNames . AutoInsertAttributeQuotes . LegacyName , defaultValue : true ) ;
52+ set => SetBool ( SettingsNames . AutoInsertAttributeQuotes . LegacyName , value ) ;
53+ }
54+
55+ public bool ColorBackground
56+ {
57+ get => GetBool ( SettingsNames . ColorBackground . LegacyName , defaultValue : false ) ;
58+ set => SetBool ( SettingsNames . ColorBackground . LegacyName , value ) ;
59+ }
60+
61+ public bool CodeBlockBraceOnNextLine
62+ {
63+ get => GetBool ( SettingsNames . CodeBlockBraceOnNextLine . LegacyName , defaultValue : false ) ;
64+ set => SetBool ( SettingsNames . CodeBlockBraceOnNextLine . LegacyName , value ) ;
65+ }
66+
67+ public bool CommitElementsWithSpace
68+ {
69+ get => GetBool ( SettingsNames . CommitElementsWithSpace . LegacyName , defaultValue : true ) ;
70+ set => SetBool ( SettingsNames . CommitElementsWithSpace . LegacyName , value ) ;
71+ }
72+
73+ public SnippetSetting Snippets
74+ {
75+ get => ( SnippetSetting ) GetInt ( SettingsNames . Snippets . LegacyName , ( int ) SnippetSetting . All ) ;
76+ set => SetInt ( SettingsNames . Snippets . LegacyName , ( int ) value ) ;
77+ }
78+
79+ public LogLevel LogLevel
80+ {
81+ get => ( LogLevel ) GetInt ( SettingsNames . LogLevel . LegacyName , ( int ) LogLevel . Warning ) ;
82+ set => SetInt ( SettingsNames . LogLevel . LegacyName , ( int ) value ) ;
83+ }
84+
85+ public bool FormatOnPaste
86+ {
87+ get => GetBool ( SettingsNames . FormatOnPaste . LegacyName , defaultValue : true ) ;
88+ set => SetBool ( SettingsNames . FormatOnPaste . LegacyName , value ) ;
89+ }
90+
91+ public ImmutableArray < string > TaskListDescriptors
92+ {
93+ get { return _taskListDescriptors ; }
94+ }
95+
3296 [ ImportingConstructor ]
3397 public OptionsStorage (
3498 SVsServiceProvider synchronousServiceProvider ,
3599 [ Import ( typeof ( SAsyncServiceProvider ) ) ] IAsyncServiceProvider serviceProvider ,
36100 Lazy < ITelemetryReporter > telemetryReporter ,
37101 JoinableTaskContext joinableTaskContext )
38102 {
103+ var shellSettingsManager = new ShellSettingsManager ( synchronousServiceProvider ) ;
104+ _writableSettingsStore = shellSettingsManager . GetWritableSettingsStore ( SettingsScope . UserSettings ) ;
105+
106+ _writableSettingsStore . CreateCollection ( SettingsNames . LegacyCollection ) ;
107+ _telemetryReporter = telemetryReporter ;
108+
39109 _initializeTask = joinableTaskContext . Factory . RunAsync ( async ( ) =>
40110 {
41- var unifiedSettingsManager = await serviceProvider . GetServiceAsync < SVsUnifiedSettingsManager , ISettingsManager > ( ) ;
111+ var unifiedSettingsManager = await serviceProvider . GetServiceAsync < SVsUnifiedSettingsManager , Utilities . UnifiedSettings . ISettingsManager > ( ) ;
42112 _unifiedSettingsReader = unifiedSettingsManager . GetReader ( ) ;
43- _unifiedSettingsSubscription = _unifiedSettingsReader . SubscribeToChanges ( OnUnifiedSettingsChanged , SettingsNames . AllSettings ) ;
113+ _unifiedSettingsSubscription = _unifiedSettingsReader . SubscribeToChanges ( OnUnifiedSettingsChanged , SettingsNames . AllSettings . Select ( s => s . UnifiedName ) . ToArray ( ) ) ;
44114
45115 await GetTaskListDescriptorsAsync ( joinableTaskContext . Factory , serviceProvider ) ;
46116 } ) ;
@@ -98,41 +168,44 @@ public async Task OnChangedAsync(Action<ClientAdvancedSettings> changed)
98168 private EventHandler < ClientAdvancedSettingsChangedEventArgs > ? _changed ;
99169
100170 public ClientAdvancedSettings GetAdvancedSettings ( )
101- => new (
102- GetBool ( SettingsNames . FormatOnType , defaultValue : true ) ,
103- GetBool ( SettingsNames . AutoClosingTags , defaultValue : true ) ,
104- GetBool ( SettingsNames . AutoInsertAttributeQuotes , defaultValue : true ) ,
105- GetBool ( SettingsNames . ColorBackground , defaultValue : false ) ,
106- GetBool ( SettingsNames . CodeBlockBraceOnNextLine , defaultValue : false ) ,
107- GetBool ( SettingsNames . CommitElementsWithSpace , defaultValue : true ) ,
108- GetEnum ( SettingsNames . Snippets , SnippetSetting . All ) ,
109- GetEnum ( SettingsNames . LogLevel , LogLevel . Warning ) ,
110- GetBool ( SettingsNames . FormatOnPaste , defaultValue : true ) ,
111- _taskListDescriptors ) ;
171+ => new ( FormatOnType , AutoClosingTags , AutoInsertAttributeQuotes , ColorBackground , CodeBlockBraceOnNextLine , CommitElementsWithSpace , Snippets , LogLevel , FormatOnPaste , TaskListDescriptors ) ;
112172
113173 public bool GetBool ( string name , bool defaultValue )
114174 {
115- if ( _unifiedSettingsReader . AssumeNotNull ( ) . GetValue < bool > ( name ) is { Outcome : SettingRetrievalOutcome . Success , Value : { } unifiedValue } )
175+ if ( _writableSettingsStore . PropertyExists ( SettingsNames . LegacyCollection , name ) )
116176 {
117- return unifiedValue ;
177+ return _writableSettingsStore . GetBoolean ( SettingsNames . LegacyCollection , name ) ;
118178 }
119179
120180 return defaultValue ;
121181 }
122182
123- public T GetEnum < T > ( string name , T defaultValue ) where T : struct , Enum
183+ public void SetBool ( string name , bool value )
124184 {
125- if ( _unifiedSettingsReader . AssumeNotNull ( ) . GetValue < string > ( name ) is { Outcome : SettingRetrievalOutcome . Success , Value : { } unifiedValue } )
185+ _writableSettingsStore . SetBoolean ( SettingsNames . LegacyCollection , name , value ) ;
186+ _telemetryReporter . Value . ReportEvent ( "OptionChanged" , Severity . Normal , new Property ( name , value ) ) ;
187+
188+ NotifyChange ( ) ;
189+ }
190+
191+ public int GetInt ( string name , int defaultValue )
192+ {
193+ if ( _writableSettingsStore . PropertyExists ( SettingsNames . LegacyCollection , name ) )
126194 {
127- if ( Enum . TryParse < T > ( unifiedValue , ignoreCase : true , out var parsed ) )
128- {
129- return parsed ;
130- }
195+ return _writableSettingsStore . GetInt32 ( SettingsNames . LegacyCollection , name ) ;
131196 }
132197
133198 return defaultValue ;
134199 }
135200
201+ public void SetInt ( string name , int value )
202+ {
203+ _writableSettingsStore . SetInt32 ( SettingsNames . LegacyCollection , name , value ) ;
204+ _telemetryReporter . Value . ReportEvent ( "OptionChanged" , Severity . Normal , new Property ( name , value ) ) ;
205+
206+ NotifyChange ( ) ;
207+ }
208+
136209 private void NotifyChange ( )
137210 {
138211 _initializeTask . Join ( ) ;
0 commit comments