From d1acbc3ec1fee98ef566b844e7d1511beff4ae49 Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Tue, 3 Sep 2024 13:57:29 -0700 Subject: [PATCH 1/9] OnAutoInsert Cohosting Tests --- .../Cohost/CohostOnAutoInsertEndpoint.cs | 18 ++- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 136 ++++++++++++++++++ 2 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs index 1b90bd110ac..b13b727a0e4 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs @@ -85,10 +85,11 @@ private static ImmutableArray CalculateTriggerChars(IEnumerable request.TextDocument.ToRazorTextDocumentIdentifier(); - protected override async Task HandleRequestAsync(VSInternalDocumentOnAutoInsertParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) - { - var razorDocument = context.TextDocument.AssumeNotNull(); + protected override Task HandleRequestAsync(VSInternalDocumentOnAutoInsertParams request, RazorCohostRequestContext context, CancellationToken cancellationToken) + => HandleRequestAsync(request, context.TextDocument.AssumeNotNull(), cancellationToken); + private async Task HandleRequestAsync(VSInternalDocumentOnAutoInsertParams request, TextDocument razorDocument, CancellationToken cancellationToken) + { _logger.LogDebug($"Resolving auto-insertion for {razorDocument.FilePath}"); var clientSettings = _clientSettingsManager.GetClientSettings(); @@ -173,4 +174,15 @@ private static ImmutableArray CalculateTriggerChars(IEnumerable new(this); + + internal readonly struct TestAccessor(CohostOnAutoInsertEndpoint instance) + { + public Task HandleRequestAsync( + VSInternalDocumentOnAutoInsertParams request, + TextDocument razorDocument, + CancellationToken cancellationToken) + => instance.HandleRequestAsync(request, razorDocument, cancellationToken); + } } diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs new file mode 100644 index 00000000000..7f88f0721f9 --- /dev/null +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -0,0 +1,136 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodBeAnalysis.Remote.Razor.AutoInsert; +using Microsoft.CodeAnalysis.ExternalAccess.Razor; +using Microsoft.CodeAnalysis.Razor.AutoInsert; +using Microsoft.CodeAnalysis.Razor.Settings; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.LanguageServer.Protocol; +using Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; +using Microsoft.VisualStudio.Razor.Settings; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; + +public class CohostOnAutoInsertEndpointTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper) +{ + [Theory] + [InlineData("PageTitle", "$0", ">")] + [InlineData("div", "$0", ">")] + [InlineData("text", "$0", ">")] + + public async Task Component_AutoInsertEndTag(string startTag, string endTag, string triggerCharacter) + { + var input = $""" + This is a Razor document. + + <{startTag}$$ + + The end. + """; + + await VerifyOnAutoInsertAsync(input, endTag, triggerCharacter); + } + + [Theory] + [InlineData("div style", "\"\"", "=")] + public async Task Component_AutoInsertAttributeQuotes(string startTag, string insertedText, string triggerCharacter) + { + var input = $""" + This is a Razor document. + + <{startTag}$$ + + The end. + """; + + await VerifyOnAutoInsertAsync(input, insertedText, triggerCharacter, createDelegatedResponse: true); + } + + [Theory] + [InlineData(""" + @code { + //$$ + void TestMethod() {} + } + """, + "/// ", "/")] + public async Task Component_AutoInsertCSharp(string input, string insertedText, string triggerCharacter) + { + await VerifyOnAutoInsertAsync(input, insertedText, triggerCharacter); + } + + private async Task VerifyOnAutoInsertAsync( + string input, + string insertedText, + string triggerCharacter, + bool createDelegatedResponse = false) + { + TestFileMarkupParser.GetPosition(input, out input, out var cursorPosition); + var document = CreateProjectAndRazorDocument(input); + var sourceText = await document.GetTextAsync(DisposalToken); + + var clientSettingsManager = new ClientSettingsManager([], null, null); + clientSettingsManager.Update(ClientAdvancedSettings.Default with { FormatOnType = true, AutoClosingTags = true }); + + IOnAutoInsertTriggerCharacterProvider[] onAutoInsertTriggerCharacterProviders = [ + new RemoteAutoClosingTagOnAutoInsertProvider(), + new RemoteCloseTextTagOnAutoInsertProvider()]; + + VSInternalDocumentOnAutoInsertResponseItem? response = null; + if (createDelegatedResponse) + { + var start = sourceText.GetPosition(cursorPosition + triggerCharacter.Length); + var end = start; + response = new VSInternalDocumentOnAutoInsertResponseItem() + { + TextEdit = new TextEdit() { NewText = insertedText, Range = new() { Start = start, End = end } }, + TextEditFormat = InsertTextFormat.Snippet + }; + } + + var requestInvoker = new TestLSPRequestInvoker([(VSInternalMethods.OnAutoInsertName, response)]); + + var endpoint = new CohostOnAutoInsertEndpoint( + RemoteServiceInvoker, + clientSettingsManager, + onAutoInsertTriggerCharacterProviders, + TestHtmlDocumentSynchronizer.Instance, + requestInvoker, + LoggerFactory); + + var formattingOptions = new FormattingOptions() + { + InsertSpaces = true, + TabSize = 4 + }; + + var request = new VSInternalDocumentOnAutoInsertParams() + { + TextDocument = new TextDocumentIdentifier() + { + Uri = document.CreateUri() + }, + Position = sourceText.GetPosition(cursorPosition), + Character = triggerCharacter, + Options = formattingOptions + }; + + var result = await endpoint.GetTestAccessor().HandleRequestAsync(request, document, DisposalToken); + + Assert.NotNull(result); + + if (createDelegatedResponse) + { + Assert.Equal(response, result); + } + + Assert.Equal(insertedText, result.TextEdit.NewText); + } +} From 4197f6d5b320f535496c63588e4c3f60ce6ecc3a Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Wed, 4 Sep 2024 14:04:29 -0700 Subject: [PATCH 2/9] Fixing C# case (and correcting others) All text should already be in the document/buffer when OnAutoInsert is being executed. Tigger character is not being added to the buffer, it should already be in the buffer. --- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index 7f88f0721f9..ec813fabda4 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -30,7 +30,7 @@ public async Task Component_AutoInsertEndTag(string startTag, string endTag, str var input = $""" This is a Razor document. - <{startTag}$$ + <{startTag}>$$ The end. """; @@ -39,7 +39,7 @@ The end. } [Theory] - [InlineData("div style", "\"\"", "=")] + [InlineData("div style=", "\"\"", "=")] public async Task Component_AutoInsertAttributeQuotes(string startTag, string insertedText, string triggerCharacter) { var input = $""" @@ -55,12 +55,17 @@ The end. [Theory] [InlineData(""" - @code { - //$$ - void TestMethod() {} - } - """, - "/// ", "/")] + @code { + ///$$ + void TestMethod() {} + } + """, + """ + + /// $0 + /// + """, + "/")] public async Task Component_AutoInsertCSharp(string input, string insertedText, string triggerCharacter) { await VerifyOnAutoInsertAsync(input, insertedText, triggerCharacter); From 81ddf78232dc272eae2c2b74b2539f08fa04a97e Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Thu, 5 Sep 2024 11:48:55 -0700 Subject: [PATCH 3/9] PR feedback Switching to applying edit instead of verifying edit contents and range. Switching from Theories to separate Facts where input was complex. Other misc cleanup. --- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index ec813fabda4..9c0b059d4ac 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System; -using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodBeAnalysis.Remote.Razor.AutoInsert; using Microsoft.CodeAnalysis.ExternalAccess.Razor; @@ -13,6 +11,7 @@ using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; using Microsoft.VisualStudio.Razor.Settings; +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -21,61 +20,75 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; public class CohostOnAutoInsertEndpointTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper) { [Theory] - [InlineData("PageTitle", "$0", ">")] - [InlineData("div", "$0", ">")] - [InlineData("text", "$0", ">")] - - public async Task Component_AutoInsertEndTag(string startTag, string endTag, string triggerCharacter) + [InlineData("PageTitle")] + [InlineData("div")] + [InlineData("text")] + public async Task Component_AutoInsertEndTag(string startTag) { var input = $""" This is a Razor document. <{startTag}>$$ + The end. + """; + var output = $""" + This is a Razor document. + + <{startTag}>$0 + The end. """; - await VerifyOnAutoInsertAsync(input, endTag, triggerCharacter); + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: ">"); } - [Theory] - [InlineData("div style=", "\"\"", "=")] - public async Task Component_AutoInsertAttributeQuotes(string startTag, string insertedText, string triggerCharacter) + [Fact] + public async Task Component_AutoInsertAttributeQuotes() { var input = $""" This is a Razor document. - <{startTag}$$ + The end. """; + var output = $""" + This is a Razor document. - await VerifyOnAutoInsertAsync(input, insertedText, triggerCharacter, createDelegatedResponse: true); + + + The end. + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "=", delegatedResponseText: "\"$0\""); } - [Theory] - [InlineData(""" + [Fact] + public async Task Component_AutoInsertCSharp_OnForwardSlash() + { + var input = """ @code { ///$$ void TestMethod() {} } - """, - """ - + """; + + var output = """ + @code { + /// /// $0 /// - """, - "/")] - public async Task Component_AutoInsertCSharp(string input, string insertedText, string triggerCharacter) - { - await VerifyOnAutoInsertAsync(input, insertedText, triggerCharacter); + void TestMethod() {} + } + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/"); } private async Task VerifyOnAutoInsertAsync( string input, - string insertedText, + string output, string triggerCharacter, - bool createDelegatedResponse = false) + string? delegatedResponseText = null) { TestFileMarkupParser.GetPosition(input, out input, out var cursorPosition); var document = CreateProjectAndRazorDocument(input); @@ -89,13 +102,13 @@ private async Task VerifyOnAutoInsertAsync( new RemoteCloseTextTagOnAutoInsertProvider()]; VSInternalDocumentOnAutoInsertResponseItem? response = null; - if (createDelegatedResponse) + if (delegatedResponseText is not null) { - var start = sourceText.GetPosition(cursorPosition + triggerCharacter.Length); + var start = sourceText.GetPosition(cursorPosition); var end = start; response = new VSInternalDocumentOnAutoInsertResponseItem() { - TextEdit = new TextEdit() { NewText = insertedText, Range = new() { Start = start, End = end } }, + TextEdit = new TextEdit() { NewText = delegatedResponseText, Range = new() { Start = start, End = end } }, TextEditFormat = InsertTextFormat.Snippet }; } @@ -131,11 +144,9 @@ private async Task VerifyOnAutoInsertAsync( Assert.NotNull(result); - if (createDelegatedResponse) - { - Assert.Equal(response, result); - } + var change = sourceText.GetTextChange(result.TextEdit); + sourceText = sourceText.WithChanges(change); - Assert.Equal(insertedText, result.TextEdit.NewText); + AssertEx.EqualOrDiff(output, sourceText.ToString()); } } From c3e577da4af21f546b0c79860c0c5ecbc1ef22dd Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Thu, 5 Sep 2024 13:35:57 -0700 Subject: [PATCH 4/9] Fixing options source and adding options tests --- .../Cohost/CohostOnAutoInsertEndpoint.cs | 4 +- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 72 ++++++++++++++++++- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs index b13b727a0e4..a89550e2248 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs @@ -95,8 +95,8 @@ private static ImmutableArray CalculateTriggerChars(IEnumerable( diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index 9c0b059d4ac..8fc03b3a35b 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -84,11 +84,77 @@ void TestMethod() {} await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/"); } + [Fact] + public async Task Component_AutoInsertCSharp_OnEnter() + { + var input = """ + @code { + void TestMethod() { + $$} + } + """; + + var output = """ + @code { + void TestMethod() + { + $0 + } + } + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n"); + } + + [Fact] + public async Task Component_AutoInsertCSharp_OnEnter_TwoSpaceIndent() + { + var input = """ + @code { + void TestMethod() { + $$} + } + """; + + var output = """ + @code { + void TestMethod() + { + $0 + } + } + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n", tabSize: 2); + } + + [Fact] + public async Task Component_AutoInsertCSharp_OnEnter_UseTabs() + { + var input = """ + @code { + void TestMethod() { + $$} + } + """; + + var tab = '\t'; + var output = $$""" + @code { + {{tab}}void TestMethod() + {{tab}}{ + {{tab}}{{tab}}$0 + {{tab}}} + } + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n", insertSpaces: false); + } + private async Task VerifyOnAutoInsertAsync( string input, string output, string triggerCharacter, - string? delegatedResponseText = null) + string? delegatedResponseText = null, + bool insertSpaces = true, + int tabSize = 4) { TestFileMarkupParser.GetPosition(input, out input, out var cursorPosition); var document = CreateProjectAndRazorDocument(input); @@ -125,8 +191,8 @@ private async Task VerifyOnAutoInsertAsync( var formattingOptions = new FormattingOptions() { - InsertSpaces = true, - TabSize = 4 + InsertSpaces = insertSpaces, + TabSize = tabSize }; var request = new VSInternalDocumentOnAutoInsertParams() From be473b3879f4f98170be83135236dbb2f1f49475 Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Thu, 5 Sep 2024 13:52:44 -0700 Subject: [PATCH 5/9] Tests for all options --- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 66 +++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index 8fc03b3a35b..19db31ddb36 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -43,6 +43,30 @@ The end. await VerifyOnAutoInsertAsync(input, output, triggerCharacter: ">"); } + [Theory] + [InlineData("PageTitle")] + [InlineData("div")] + [InlineData("text")] + public async Task Component_DoNotAutoInsertEndTag_DisabledAutoClosingTags(string startTag) + { + var input = $""" + This is a Razor document. + + <{startTag}>$$ + + The end. + """; + var output = $""" + This is a Razor document. + + <{startTag}> + + The end. + """; + + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: ">", autoClosingTags: false, expectResult: false); + } + [Fact] public async Task Component_AutoInsertAttributeQuotes() { @@ -84,6 +108,25 @@ void TestMethod() {} await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/"); } + [Fact] + public async Task Component_DoNotAutoInsertCSharp_OnForwardSlashWithFormatOnTypeDisabled() + { + var input = """ + @code { + ///$$ + void TestMethod() {} + } + """; + + var output = """ + @code { + /// + void TestMethod() {} + } + """; + await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/", formatOnType: false, expectResult: false); + } + [Fact] public async Task Component_AutoInsertCSharp_OnEnter() { @@ -154,14 +197,17 @@ private async Task VerifyOnAutoInsertAsync( string triggerCharacter, string? delegatedResponseText = null, bool insertSpaces = true, - int tabSize = 4) + int tabSize = 4, + bool formatOnType = true, + bool autoClosingTags = true, + bool expectResult = true) { TestFileMarkupParser.GetPosition(input, out input, out var cursorPosition); var document = CreateProjectAndRazorDocument(input); var sourceText = await document.GetTextAsync(DisposalToken); var clientSettingsManager = new ClientSettingsManager([], null, null); - clientSettingsManager.Update(ClientAdvancedSettings.Default with { FormatOnType = true, AutoClosingTags = true }); + clientSettingsManager.Update(ClientAdvancedSettings.Default with { FormatOnType = formatOnType, AutoClosingTags = autoClosingTags }); IOnAutoInsertTriggerCharacterProvider[] onAutoInsertTriggerCharacterProviders = [ new RemoteAutoClosingTagOnAutoInsertProvider(), @@ -208,10 +254,20 @@ private async Task VerifyOnAutoInsertAsync( var result = await endpoint.GetTestAccessor().HandleRequestAsync(request, document, DisposalToken); - Assert.NotNull(result); + if (expectResult) + { + Assert.NotNull(result); + } + else + { + Assert.Null(result); + } - var change = sourceText.GetTextChange(result.TextEdit); - sourceText = sourceText.WithChanges(change); + if (result is not null) + { + var change = sourceText.GetTextChange(result.TextEdit); + sourceText = sourceText.WithChanges(change); + } AssertEx.EqualOrDiff(output, sourceText.ToString()); } From 9a2ef8a7ebbb2aeee9aaf006d9ba938dad5cd704 Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Thu, 5 Sep 2024 14:01:31 -0700 Subject: [PATCH 6/9] Switching to use TestCode class --- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index 19db31ddb36..a6ca34a3f48 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -2,11 +2,11 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodBeAnalysis.Remote.Razor.AutoInsert; using Microsoft.CodeAnalysis.ExternalAccess.Razor; using Microsoft.CodeAnalysis.Razor.AutoInsert; using Microsoft.CodeAnalysis.Razor.Settings; -using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.LanguageServices.Razor.LanguageClient.Cohost; @@ -202,8 +202,9 @@ private async Task VerifyOnAutoInsertAsync( bool autoClosingTags = true, bool expectResult = true) { - TestFileMarkupParser.GetPosition(input, out input, out var cursorPosition); - var document = CreateProjectAndRazorDocument(input); + var testCode = new TestCode(input); + + var document = CreateProjectAndRazorDocument(testCode.Text); var sourceText = await document.GetTextAsync(DisposalToken); var clientSettingsManager = new ClientSettingsManager([], null, null); @@ -216,7 +217,7 @@ private async Task VerifyOnAutoInsertAsync( VSInternalDocumentOnAutoInsertResponseItem? response = null; if (delegatedResponseText is not null) { - var start = sourceText.GetPosition(cursorPosition); + var start = sourceText.GetPosition(testCode.Position); var end = start; response = new VSInternalDocumentOnAutoInsertResponseItem() { @@ -247,7 +248,7 @@ private async Task VerifyOnAutoInsertAsync( { Uri = document.CreateUri() }, - Position = sourceText.GetPosition(cursorPosition), + Position = sourceText.GetPosition(testCode.Position), Character = triggerCharacter, Options = formattingOptions }; From 4660783c176e3b0f663892cab23313a5da19d595 Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Thu, 5 Sep 2024 21:58:56 -0700 Subject: [PATCH 7/9] Create options object for cohost OnAutoInsert to combined individual options passed to the remove service. --- .../Remote/IRemoteAutoInsertService.cs | 8 ++--- .../Remote/RemoteAutoInsertOptions.cs | 34 ++++++++++++++++++ .../AutoInsert/RemoteAutoInsertService.cs | 36 +++++++------------ .../Cohost/CohostOnAutoInsertEndpoint.cs | 10 ++---- 4 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteAutoInsertService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteAutoInsertService.cs index 3872965c0f7..5130487c88f 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteAutoInsertService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteAutoInsertService.cs @@ -3,12 +3,13 @@ using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.ExternalAccess.Razor; using Microsoft.CodeAnalysis.Text; using Response = Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse; +namespace Microsoft.CodeAnalysis.Razor.Remote; + internal interface IRemoteAutoInsertService { ValueTask GetAutoInsertTextEditAsync( @@ -16,9 +17,6 @@ ValueTask GetAutoInsertTextEditAsync( DocumentId documentId, LinePosition position, string character, - bool autoCloseTags, - bool formatOnType, - bool indentWithTabs, - int indentSize, + RemoteAutoInsertOptions options, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs new file mode 100644 index 00000000000..cb3d2630337 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs @@ -0,0 +1,34 @@ +using System.Runtime.Serialization; +using Microsoft.CodeAnalysis.Razor.Settings; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Razor.Remote; + +[DataContract] +internal readonly record struct RemoteAutoInsertOptions +{ + [DataMember(Order = 0)] + public bool EnableAutoClosingTags { get; init; } = true; + + [DataMember(Order = 1)] + public bool FormatOnType { get; init; } = true; + + [DataMember(Order = 2)] + public bool InsertSpaces { get; init; } = true; + + [DataMember(Order = 3)] + public int TabSize { get; init; } = 4; + + public RemoteAutoInsertOptions() + { + } + + public static RemoteAutoInsertOptions From(ClientSettings clientSettings, FormattingOptions formattingOptions) + => new() + { + EnableAutoClosingTags = clientSettings.AdvancedSettings.AutoClosingTags, + FormatOnType = clientSettings.AdvancedSettings.FormatOnType, + InsertSpaces = formattingOptions.InsertSpaces, + TabSize = formattingOptions.TabSize + }; +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs index 9793c86b68e..59820afa838 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.AutoInsert; +using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; @@ -42,10 +43,7 @@ public ValueTask GetAutoInsertTextEditAsync( DocumentId documentId, LinePosition linePosition, string character, - bool autoCloseTags, - bool formatOnType, - bool indentWithTabs, - int indentSize, + RemoteAutoInsertOptions options, CancellationToken cancellationToken) => RunServiceAsync( solutionInfo, @@ -54,10 +52,7 @@ public ValueTask GetAutoInsertTextEditAsync( context, linePosition, character, - autoCloseTags, - formatOnType, - indentWithTabs, - indentSize, + options, cancellationToken), cancellationToken); @@ -65,10 +60,7 @@ private async ValueTask TryResolveInsertionAsync( RemoteDocumentContext remoteDocumentContext, LinePosition linePosition, string character, - bool autoCloseTags, - bool formatOnType, - bool indentWithTabs, - int indentSize, + RemoteAutoInsertOptions options, CancellationToken cancellationToken) { var sourceText = await remoteDocumentContext.GetSourceTextAsync(cancellationToken).ConfigureAwait(false); @@ -86,7 +78,7 @@ private async ValueTask TryResolveInsertionAsync( codeDocument, VsLspExtensions.ToPosition(linePosition), character, - autoCloseTags, + options.EnableAutoClosingTags, out var insertTextEdit)) { return Response.Results(RemoteAutoInsertTextEdit.FromLspInsertTextEdit(insertTextEdit)); @@ -110,9 +102,7 @@ private async ValueTask TryResolveInsertionAsync( remoteDocumentContext, mappedPosition, character, - formatOnType, - indentWithTabs, - indentSize, + options, cancellationToken); default: Logger.LogError($"Unsupported language {languageKind} in {nameof(RemoteAutoInsertService)}"); @@ -124,9 +114,7 @@ private async ValueTask TryResolveInsertionInCSharpAsync( RemoteDocumentContext remoteDocumentContext, LinePosition mappedPosition, string character, - bool formatOnType, - bool indentWithTabs, - int indentSize, + RemoteAutoInsertOptions options, CancellationToken cancellationToken) { // Special case for C# where we use AutoInsert for two purposes: @@ -140,7 +128,7 @@ private async ValueTask TryResolveInsertionInCSharpAsync( // Therefore we are just going to no-op if the user has turned off on type formatting. Maybe one day we can make this // smarter, but at least the user can always turn the setting back on, type their "///", and turn it back off, without // having to restart VS. Not the worst compromise (hopefully!) - if (!formatOnType) + if (!options.FormatOnType) { return Response.NoFurtherHandling; } @@ -153,8 +141,8 @@ private async ValueTask TryResolveInsertionInCSharpAsync( var generatedDocument = await remoteDocumentContext.Snapshot.GetGeneratedDocumentAsync().ConfigureAwait(false); var formattingOptions = new RoslynFormattingOptions() { - InsertSpaces = !indentWithTabs, - TabSize = indentSize + InsertSpaces = options.InsertSpaces, + TabSize = options.TabSize }; var autoInsertResponseItem = await OnAutoInsert.GetOnAutoInsertResponseAsync( @@ -172,8 +160,8 @@ private async ValueTask TryResolveInsertionInCSharpAsync( var razorFormattingOptions = new RazorFormattingOptions() { - InsertSpaces = !indentWithTabs, - TabSize = indentSize + InsertSpaces = options.InsertSpaces, + TabSize = options.TabSize }; var vsLspTextEdit = VsLspFactory.CreateTextEdit( diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs index a89550e2248..b0ecbac96ed 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs @@ -93,10 +93,7 @@ private static ImmutableArray CalculateTriggerChars(IEnumerable( @@ -107,10 +104,7 @@ private static ImmutableArray CalculateTriggerChars(IEnumerable Date: Fri, 6 Sep 2024 14:24:52 -0700 Subject: [PATCH 8/9] More PR feedback --- .../Cohost/CohostOnAutoInsertEndpoint.cs | 2 +- .../Cohost/CohostOnAutoInsertEndpointTest.cs | 263 +++++++++--------- 2 files changed, 129 insertions(+), 136 deletions(-) diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs index b0ecbac96ed..db0d7db8cd0 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostOnAutoInsertEndpoint.cs @@ -177,6 +177,6 @@ internal readonly struct TestAccessor(CohostOnAutoInsertEndpoint instance) VSInternalDocumentOnAutoInsertParams request, TextDocument razorDocument, CancellationToken cancellationToken) - => instance.HandleRequestAsync(request, razorDocument, cancellationToken); + => instance.HandleRequestAsync(request, razorDocument, cancellationToken); } } diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs index a6ca34a3f48..b7dbb70194a 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostOnAutoInsertEndpointTest.cs @@ -23,188 +23,180 @@ public class CohostOnAutoInsertEndpointTest(ITestOutputHelper testOutputHelper) [InlineData("PageTitle")] [InlineData("div")] [InlineData("text")] - public async Task Component_AutoInsertEndTag(string startTag) + public async Task EndTag(string startTag) { - var input = $""" - This is a Razor document. + await VerifyOnAutoInsertAsync( + input: $""" + This is a Razor document. - <{startTag}>$$ + <{startTag}>$$ - The end. - """; - var output = $""" - This is a Razor document. + The end. + """, + output: $""" + This is a Razor document. - <{startTag}>$0 + <{startTag}>$0 - The end. - """; - - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: ">"); + The end. + """, + triggerCharacter: ">"); } [Theory] [InlineData("PageTitle")] [InlineData("div")] [InlineData("text")] - public async Task Component_DoNotAutoInsertEndTag_DisabledAutoClosingTags(string startTag) + public async Task DoNotAutoInsertEndTag_DisabledAutoClosingTags(string startTag) { - var input = $""" - This is a Razor document. - - <{startTag}>$$ - - The end. - """; - var output = $""" - This is a Razor document. + await VerifyOnAutoInsertAsync( + input: $""" + This is a Razor document. - <{startTag}> + <{startTag}>$$ - The end. - """; - - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: ">", autoClosingTags: false, expectResult: false); + The end. + """, + output: null, + triggerCharacter: ">", + autoClosingTags: false); } [Fact] - public async Task Component_AutoInsertAttributeQuotes() + public async Task AttributeQuotes() { - var input = $""" - This is a Razor document. + await VerifyOnAutoInsertAsync( + input: $""" + This is a Razor document. - + - The end. - """; - var output = $""" - This is a Razor document. + The end. + """, + output: $""" + This is a Razor document. - + - The end. - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "=", delegatedResponseText: "\"$0\""); + The end. + """, + triggerCharacter: "=", + delegatedResponseText: "\"$0\""); } [Fact] - public async Task Component_AutoInsertCSharp_OnForwardSlash() + public async Task CSharp_OnForwardSlash() { - var input = """ - @code { - ///$$ - void TestMethod() {} - } - """; - - var output = """ - @code { - /// - /// $0 - /// - void TestMethod() {} - } - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/"); + await VerifyOnAutoInsertAsync( + input: """ + @code { + ///$$ + void TestMethod() {} + } + """, + output: """ + @code { + /// + /// $0 + /// + void TestMethod() {} + } + """, + triggerCharacter: "/"); } [Fact] - public async Task Component_DoNotAutoInsertCSharp_OnForwardSlashWithFormatOnTypeDisabled() + public async Task DoNotAutoInsertCSharp_OnForwardSlashWithFormatOnTypeDisabled() { - var input = """ - @code { - ///$$ - void TestMethod() {} - } - """; - - var output = """ - @code { - /// - void TestMethod() {} - } - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "/", formatOnType: false, expectResult: false); + await VerifyOnAutoInsertAsync( + input: """ + @code { + ///$$ + void TestMethod() {} + } + """, + output: null, + triggerCharacter: "/", + formatOnType: false); } [Fact] - public async Task Component_AutoInsertCSharp_OnEnter() + public async Task CSharp_OnEnter() { - var input = """ - @code { - void TestMethod() { - $$} - } - """; - - var output = """ - @code { - void TestMethod() - { - $0 - } - } - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n"); + await VerifyOnAutoInsertAsync( + input: """ + @code { + void TestMethod() { + $$} + } + """, + output: """ + @code { + void TestMethod() + { + $0 + } + } + """, + triggerCharacter: "\n"); } [Fact] - public async Task Component_AutoInsertCSharp_OnEnter_TwoSpaceIndent() + public async Task CSharp_OnEnter_TwoSpaceIndent() { - var input = """ - @code { - void TestMethod() { - $$} - } - """; - - var output = """ - @code { - void TestMethod() - { - $0 - } - } - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n", tabSize: 2); + await VerifyOnAutoInsertAsync( + input: """ + @code { + void TestMethod() { + $$} + } + """, + output: """ + @code { + void TestMethod() + { + $0 + } + } + """, + triggerCharacter: "\n", + tabSize: 2); } [Fact] - public async Task Component_AutoInsertCSharp_OnEnter_UseTabs() + public async Task CSharp_OnEnter_UseTabs() { - var input = """ - @code { - void TestMethod() { - $$} - } - """; - - var tab = '\t'; - var output = $$""" - @code { - {{tab}}void TestMethod() - {{tab}}{ - {{tab}}{{tab}}$0 - {{tab}}} - } - """; - await VerifyOnAutoInsertAsync(input, output, triggerCharacter: "\n", insertSpaces: false); + const char tab = '\t'; + await VerifyOnAutoInsertAsync( + input: """ + @code { + void TestMethod() { + $$} + } + """, + output: $$""" + @code { + {{tab}}void TestMethod() + {{tab}}{ + {{tab}}{{tab}}$0 + {{tab}}} + } + """, + triggerCharacter: "\n", + insertSpaces: false); } private async Task VerifyOnAutoInsertAsync( - string input, - string output, + TestCode input, + string? output, string triggerCharacter, string? delegatedResponseText = null, bool insertSpaces = true, int tabSize = 4, bool formatOnType = true, - bool autoClosingTags = true, - bool expectResult = true) - { - var testCode = new TestCode(input); - - var document = CreateProjectAndRazorDocument(testCode.Text); + bool autoClosingTags = true) + { + var document = CreateProjectAndRazorDocument(input.Text); var sourceText = await document.GetTextAsync(DisposalToken); var clientSettingsManager = new ClientSettingsManager([], null, null); @@ -217,7 +209,7 @@ private async Task VerifyOnAutoInsertAsync( VSInternalDocumentOnAutoInsertResponseItem? response = null; if (delegatedResponseText is not null) { - var start = sourceText.GetPosition(testCode.Position); + var start = sourceText.GetPosition(input.Position); var end = start; response = new VSInternalDocumentOnAutoInsertResponseItem() { @@ -248,20 +240,21 @@ private async Task VerifyOnAutoInsertAsync( { Uri = document.CreateUri() }, - Position = sourceText.GetPosition(testCode.Position), + Position = sourceText.GetPosition(input.Position), Character = triggerCharacter, Options = formattingOptions }; var result = await endpoint.GetTestAccessor().HandleRequestAsync(request, document, DisposalToken); - if (expectResult) + if (output is not null) { Assert.NotNull(result); } else { Assert.Null(result); + return; } if (result is not null) From b37cf89c555d8fa2d84cf6a8e562aeddeda47aca Mon Sep 17 00:00:00 2001 From: Alex Gavrilov Date: Fri, 6 Sep 2024 15:02:29 -0700 Subject: [PATCH 9/9] Switching to nested RazorFormattingOptions --- .../Formatting/RazorFormattingOptions.cs | 8 ++++++++ .../Remote/RemoteAutoInsertOptions.cs | 13 +++++++------ .../AutoInsert/RemoteAutoInsertService.cs | 14 ++------------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingOptions.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingOptions.cs index a0397ec80f5..41e1e855a55 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingOptions.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingOptions.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.ExternalAccess.Razor; using Microsoft.VisualStudio.LanguageServer.Protocol; +using RoslynFormattingOptions = Roslyn.LanguageServer.Protocol.FormattingOptions; namespace Microsoft.CodeAnalysis.Razor.Formatting; @@ -33,4 +34,11 @@ public RazorIndentationOptions ToIndentationOptions() UseTabs: !InsertSpaces, TabSize: TabSize, IndentationSize: TabSize); + + public RoslynFormattingOptions ToRoslynFormattingOptions() + => new RoslynFormattingOptions() + { + InsertSpaces = InsertSpaces, + TabSize = TabSize + }; } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs index cb3d2630337..9281506849c 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/RemoteAutoInsertOptions.cs @@ -1,4 +1,5 @@ using System.Runtime.Serialization; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Settings; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -14,10 +15,11 @@ internal readonly record struct RemoteAutoInsertOptions public bool FormatOnType { get; init; } = true; [DataMember(Order = 2)] - public bool InsertSpaces { get; init; } = true; - - [DataMember(Order = 3)] - public int TabSize { get; init; } = 4; + public RazorFormattingOptions FormattingOptions { get; init; } = new RazorFormattingOptions() + { + InsertSpaces = true, + TabSize = 4 + }; public RemoteAutoInsertOptions() { @@ -28,7 +30,6 @@ public static RemoteAutoInsertOptions From(ClientSettings clientSettings, Format { EnableAutoClosingTags = clientSettings.AdvancedSettings.AutoClosingTags, FormatOnType = clientSettings.AdvancedSettings.FormatOnType, - InsertSpaces = formattingOptions.InsertSpaces, - TabSize = formattingOptions.TabSize + FormattingOptions = RazorFormattingOptions.From(formattingOptions, codeBlockBraceOnNextLine: false) }; } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs index 59820afa838..b3d7d0d23f6 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs @@ -18,7 +18,6 @@ using Microsoft.VisualStudio.LanguageServer.Protocol; using Roslyn.LanguageServer.Protocol; using Response = Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse; -using RoslynFormattingOptions = Roslyn.LanguageServer.Protocol.FormattingOptions; using RoslynInsertTextFormat = Roslyn.LanguageServer.Protocol.InsertTextFormat; namespace Microsoft.CodeAnalysis.Remote.Razor; @@ -139,17 +138,12 @@ private async ValueTask TryResolveInsertionInCSharpAsync( } var generatedDocument = await remoteDocumentContext.Snapshot.GetGeneratedDocumentAsync().ConfigureAwait(false); - var formattingOptions = new RoslynFormattingOptions() - { - InsertSpaces = options.InsertSpaces, - TabSize = options.TabSize - }; var autoInsertResponseItem = await OnAutoInsert.GetOnAutoInsertResponseAsync( generatedDocument, mappedPosition, character, - formattingOptions, + options.FormattingOptions.ToRoslynFormattingOptions(), cancellationToken ); @@ -158,11 +152,7 @@ private async ValueTask TryResolveInsertionInCSharpAsync( return Response.NoFurtherHandling; } - var razorFormattingOptions = new RazorFormattingOptions() - { - InsertSpaces = options.InsertSpaces, - TabSize = options.TabSize - }; + var razorFormattingOptions = options.FormattingOptions; var vsLspTextEdit = VsLspFactory.CreateTextEdit( autoInsertResponseItem.TextEdit.Range.ToLinePositionSpan(),