Skip to content

Commit 7f7e755

Browse files
author
Andrew Hall
authored
Revert "Revert "Add Advanced Settings For Razor"" (#8181)
1 parent bae9d9e commit 7f7e755

File tree

64 files changed

+1154
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1154
-366
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/DefaultRazorConfigurationService.cs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
using Microsoft.CodeAnalysis.Razor.Editor;
88
using Microsoft.Extensions.Logging;
99
using Microsoft.VisualStudio.LanguageServer.Protocol;
10+
using Newtonsoft.Json;
1011
using Newtonsoft.Json.Linq;
1112

1213
namespace Microsoft.AspNetCore.Razor.LanguageServer;
1314

14-
internal class DefaultRazorConfigurationService : RazorConfigurationService
15+
internal class DefaultRazorConfigurationService : IConfigurationSyncService
1516
{
1617
private readonly ClientNotifierServiceBase _server;
1718
private readonly ILogger _logger;
@@ -32,7 +33,7 @@ public DefaultRazorConfigurationService(ClientNotifierServiceBase languageServer
3233
_logger = loggerFactory.CreateLogger<DefaultRazorConfigurationService>();
3334
}
3435

35-
public async override Task<RazorLSPOptions?> GetLatestOptionsAsync(CancellationToken cancellationToken)
36+
public async Task<RazorLSPOptions?> GetLatestOptionsAsync(CancellationToken cancellationToken)
3637
{
3738
try
3839
{
@@ -76,7 +77,7 @@ private static ConfigurationParams GenerateConfigParams()
7677
new ConfigurationItem()
7778
{
7879
Section = "vs.editor.razor"
79-
},
80+
}
8081
}
8182
};
8283
}
@@ -85,9 +86,9 @@ private static ConfigurationParams GenerateConfigParams()
8586
internal RazorLSPOptions BuildOptions(JObject[] result)
8687
{
8788
ExtractVSCodeOptions(result, out var trace, out var enableFormatting, out var autoClosingTags);
88-
ExtractVSOptions(result, out var insertSpaces, out var tabSize);
89+
var settings = ExtractVSOptions(result) ?? ClientSettings.Default;
8990

90-
return new RazorLSPOptions(trace, enableFormatting, autoClosingTags, insertSpaces, tabSize);
91+
return new RazorLSPOptions(trace, enableFormatting, autoClosingTags, settings);
9192
}
9293

9394
private void ExtractVSCodeOptions(
@@ -129,29 +130,32 @@ private void ExtractVSCodeOptions(
129130
}
130131
}
131132

132-
private void ExtractVSOptions(
133-
JObject[] result,
134-
out bool insertSpaces,
135-
out int tabSize)
133+
private ClientSettings ExtractVSOptions(JObject[] result)
136134
{
137-
var vsEditor = result[2];
135+
try
136+
{
137+
var settings = result[2]?.ToObject<ClientSettings>();
138+
if (settings is null)
139+
{
140+
return ClientSettings.Default;
141+
}
138142

139-
insertSpaces = RazorLSPOptions.Default.InsertSpaces;
140-
tabSize = RazorLSPOptions.Default.TabSize;
143+
// Deserializing can result in null properties. Fill with default as needed
144+
if (settings.ClientSpaceSettings is null)
145+
{
146+
settings = settings with { ClientSpaceSettings = ClientSpaceSettings.Default };
147+
}
141148

142-
if (vsEditor is null)
143-
{
144-
return;
145-
}
149+
if (settings.AdvancedSettings is null)
150+
{
151+
settings = settings with { AdvancedSettings = ClientAdvancedSettings.Default };
152+
}
146153

147-
if (vsEditor.TryGetValue(nameof(EditorSettings.IndentWithTabs), out var parsedInsertTabs))
148-
{
149-
insertSpaces = !GetObjectOrDefault(parsedInsertTabs, insertSpaces);
154+
return settings;
150155
}
151-
152-
if (vsEditor.TryGetValue(nameof(EditorSettings.IndentSize), out var parsedTabSize))
156+
catch (JsonReaderException)
153157
{
154-
tabSize = GetObjectOrDefault(parsedTabSize, tabSize);
158+
return ClientSettings.Default;
155159
}
156160
}
157161

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Extensions/IServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public static void AddTextDocumentServices(this IServiceCollection services)
166166

167167
public static void AddOptionsServices(this IServiceCollection services)
168168
{
169-
services.AddSingleton<RazorConfigurationService, DefaultRazorConfigurationService>();
169+
services.AddSingleton<IConfigurationSyncService, DefaultRazorConfigurationService>();
170170
services.AddSingleton<RazorLSPOptionsMonitor>();
171171
services.AddSingleton<IOptionsMonitor<RazorLSPOptions>, RazorLSPOptionsMonitor>();
172172
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/CSharpOnTypeFormattingPass.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Microsoft.CodeAnalysis.Razor.Workspaces.Extensions;
2121
using Microsoft.CodeAnalysis.Text;
2222
using Microsoft.Extensions.Logging;
23+
using Microsoft.Extensions.Options;
2324
using Microsoft.VisualStudio.LanguageServer.Protocol;
2425
using SyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode;
2526
using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan;
@@ -29,10 +30,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
2930
internal class CSharpOnTypeFormattingPass : CSharpFormattingPassBase
3031
{
3132
private readonly ILogger _logger;
33+
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;
3234

3335
public CSharpOnTypeFormattingPass(
3436
RazorDocumentMappingService documentMappingService,
3537
ClientNotifierServiceBase server,
38+
IOptionsMonitor<RazorLSPOptions> optionsMonitor,
3639
ILoggerFactory loggerFactory)
3740
: base(documentMappingService, server)
3841
{
@@ -42,11 +45,12 @@ public CSharpOnTypeFormattingPass(
4245
}
4346

4447
_logger = loggerFactory.CreateLogger<CSharpOnTypeFormattingPass>();
48+
_optionsMonitor = optionsMonitor;
4549
}
4650

4751
public async override Task<FormattingResult> ExecuteAsync(FormattingContext context, FormattingResult result, CancellationToken cancellationToken)
4852
{
49-
if (!context.IsFormatOnType || result.Kind != RazorLanguageKind.CSharp)
53+
if (!context.IsFormatOnType || result.Kind != RazorLanguageKind.CSharp || !_optionsMonitor.CurrentValue.FormatOnType)
5054
{
5155
// We don't want to handle regular formatting or non-C# on type formatting here.
5256
return result;

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/HtmlFormattingPass.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Microsoft.AspNetCore.Razor.LanguageServer.Protocol;
1414
using Microsoft.CodeAnalysis.Text;
1515
using Microsoft.Extensions.Logging;
16+
using Microsoft.Extensions.Options;
1617
using Microsoft.VisualStudio.LanguageServer.Protocol;
1718
using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan;
1819

@@ -21,11 +22,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
2122
internal class HtmlFormattingPass : FormattingPassBase
2223
{
2324
private readonly ILogger _logger;
25+
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;
2426

2527
public HtmlFormattingPass(
2628
RazorDocumentMappingService documentMappingService,
2729
ClientNotifierServiceBase server,
2830
DocumentVersionCache documentVersionCache,
31+
IOptionsMonitor<RazorLSPOptions> optionsMonitor,
2932
ILoggerFactory loggerFactory)
3033
: base(documentMappingService, server)
3134
{
@@ -37,6 +40,7 @@ public HtmlFormattingPass(
3740
_logger = loggerFactory.CreateLogger<HtmlFormattingPass>();
3841

3942
HtmlFormatter = new HtmlFormatter(server, documentVersionCache);
43+
_optionsMonitor = optionsMonitor;
4044
}
4145

4246
// We want this to run first because it uses the client HTML formatter.
@@ -52,7 +56,7 @@ public async override Task<FormattingResult> ExecuteAsync(FormattingContext cont
5256

5357
TextEdit[] htmlEdits;
5458

55-
if (context.IsFormatOnType && result.Kind == RazorLanguageKind.Html)
59+
if (context.IsFormatOnType && result.Kind == RazorLanguageKind.Html && _optionsMonitor.CurrentValue.FormatOnType)
5660
{
5761
htmlEdits = await HtmlFormatter.FormatOnTypeAsync(context, cancellationToken).ConfigureAwait(false);
5862
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/RazorDocumentOnTypeFormattingEndpoint.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(DocumentOnTypeFormatting
8282
return null;
8383
}
8484

85+
if (!_optionsMonitor.CurrentValue.FormatOnType)
86+
{
87+
requestContext.Logger.LogInformation("Formatting on type disabled.");
88+
return null;
89+
}
90+
8591
if (!s_allTriggerCharacters.Contains(request.Character, StringComparer.Ordinal))
8692
{
8793
requestContext.Logger.LogWarning("Unexpected trigger character '{requestCharacter}'.", request.Character);

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorConfigurationService.cs renamed to src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/IConfigurationSyncService.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
namespace Microsoft.AspNetCore.Razor.LanguageServer;
88

9-
internal abstract class RazorConfigurationService
9+
/// <summary>
10+
/// Service that syncs settings from the client to the LSP server
11+
/// </summary>
12+
internal interface IConfigurationSyncService
1013
{
11-
public abstract Task<RazorLSPOptions?> GetLatestOptionsAsync(CancellationToken cancellationToken);
14+
Task<RazorLSPOptions?> GetLatestOptionsAsync(CancellationToken cancellationToken);
1215
}
Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,28 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4-
using System;
5-
using Microsoft.Extensions.Internal;
4+
using Microsoft.CodeAnalysis.Razor.Editor;
65
using Microsoft.Extensions.Logging;
76

87
namespace Microsoft.AspNetCore.Razor.LanguageServer;
98

10-
internal class RazorLSPOptions : IEquatable<RazorLSPOptions>
9+
public record RazorLSPOptions(
10+
Trace Trace,
11+
bool EnableFormatting,
12+
bool AutoClosingTags,
13+
bool InsertSpaces,
14+
int TabSize,
15+
bool FormatOnType)
1116
{
12-
public RazorLSPOptions(Trace trace, bool enableFormatting, bool autoClosingTags, bool insertSpaces, int tabSize)
17+
public RazorLSPOptions(Trace trace, bool enableFormatting, bool autoClosingTags, ClientSettings settings)
18+
: this(trace, enableFormatting, autoClosingTags, !settings.ClientSpaceSettings.IndentWithTabs, settings.ClientSpaceSettings.IndentSize, settings.AdvancedSettings.FormatOnType)
1319
{
14-
Trace = trace;
15-
EnableFormatting = enableFormatting;
16-
AutoClosingTags = autoClosingTags;
17-
TabSize = tabSize;
18-
InsertSpaces = insertSpaces;
1920
}
2021

21-
public static RazorLSPOptions Default =>
22-
new(trace: default, enableFormatting: true, autoClosingTags: true, insertSpaces: true, tabSize: 4);
23-
24-
public Trace Trace { get; }
22+
public readonly static RazorLSPOptions Default = new(Trace: default, EnableFormatting: true, AutoClosingTags: true, InsertSpaces: true, TabSize: 4, FormatOnType: true);
2523

2624
public LogLevel MinLogLevel => GetLogLevelForTrace(Trace);
2725

28-
public bool EnableFormatting { get; }
29-
30-
public bool AutoClosingTags { get; }
31-
32-
public int TabSize { get; }
33-
34-
public bool InsertSpaces { get; }
35-
3626
public static LogLevel GetLogLevelForTrace(Trace trace)
3727
=> trace switch
3828
{
@@ -41,26 +31,4 @@ public static LogLevel GetLogLevelForTrace(Trace trace)
4131
Trace.Verbose => LogLevel.Trace,
4232
_ => LogLevel.None,
4333
};
44-
45-
public bool Equals(RazorLSPOptions? other)
46-
=> other is not null &&
47-
Trace == other.Trace &&
48-
EnableFormatting == other.EnableFormatting &&
49-
AutoClosingTags == other.AutoClosingTags &&
50-
InsertSpaces == other.InsertSpaces &&
51-
TabSize == other.TabSize;
52-
53-
public override bool Equals(object? obj)
54-
=> Equals(obj as RazorLSPOptions);
55-
56-
public override int GetHashCode()
57-
{
58-
var hash = new HashCodeCombiner();
59-
hash.Add(Trace);
60-
hash.Add(EnableFormatting);
61-
hash.Add(AutoClosingTags);
62-
hash.Add(InsertSpaces);
63-
hash.Add(TabSize);
64-
return hash;
65-
}
6634
}

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/RazorLSPOptionsMonitor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer;
1010

1111
internal class RazorLSPOptionsMonitor : IOptionsMonitor<RazorLSPOptions>
1212
{
13-
private readonly RazorConfigurationService _configurationService;
13+
private readonly IConfigurationSyncService _configurationService;
1414
private readonly IOptionsMonitorCache<RazorLSPOptions> _cache;
1515
private event Action<RazorLSPOptions, string>? OnChangeEvent;
1616
private RazorLSPOptions _currentValue;
1717

18-
public RazorLSPOptionsMonitor(RazorConfigurationService configurationService, IOptionsMonitorCache<RazorLSPOptions> cache)
18+
public RazorLSPOptionsMonitor(IConfigurationSyncService configurationService, IOptionsMonitorCache<RazorLSPOptions> cache)
1919
{
2020
if (configurationService is null)
2121
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT license. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace Microsoft.CodeAnalysis.Razor.Editor;
7+
8+
/// <summary>
9+
/// Settings that are set and handled on the client, but needed by the LSP Server to function correctly. When these are
10+
/// updated a workspace/didchangeconfiguration should be sent from client to the server. Then the server requests
11+
/// workspace/configuration to get the latest settings. For VS, the razor protocol also handles this and serializes the
12+
/// settings back to the server.
13+
/// </summary>
14+
/// <param name="ClientSpaceSettings"></param>
15+
/// <param name="AdvancedSettings"></param>
16+
public record ClientSettings(ClientSpaceSettings ClientSpaceSettings, ClientAdvancedSettings AdvancedSettings)
17+
{
18+
public static readonly ClientSettings Default = new(ClientSpaceSettings.Default, ClientAdvancedSettings.Default);
19+
}
20+
21+
public sealed record ClientSpaceSettings(bool IndentWithTabs, int IndentSize)
22+
{
23+
public static readonly ClientSpaceSettings Default = new(IndentWithTabs: false, IndentSize: 4);
24+
25+
public int IndentSize { get; } = IndentSize >= 0 ? IndentSize : throw new ArgumentOutOfRangeException(nameof(IndentSize));
26+
}
27+
28+
public sealed record ClientAdvancedSettings(bool FormatOnType)
29+
{
30+
public static readonly ClientAdvancedSettings Default = new(FormatOnType: true);
31+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace Microsoft.CodeAnalysis.Razor.Editor;
77

8-
public sealed class EditorSettingsChangedEventArgs : EventArgs
8+
public sealed class ClientSettingsChangedEventArgs : EventArgs
99
{
10-
public EditorSettingsChangedEventArgs(EditorSettings settings)
10+
public ClientSettingsChangedEventArgs(ClientSettings settings)
1111
{
1212
if (settings is null)
1313
{
@@ -17,5 +17,5 @@ public EditorSettingsChangedEventArgs(EditorSettings settings)
1717
Settings = settings;
1818
}
1919

20-
public EditorSettings Settings { get; }
20+
public ClientSettings Settings { get; }
2121
}

0 commit comments

Comments
 (0)