提交 c482985e 编写于 作者: B Balaji Soundrarajan

Formatting Service should honor Smart Indent Option

Fix #2224 : Formatting Service should not format the whitespaces before
Braces if Smart Indentation Option is set to None
上级 ae819709
......@@ -21,6 +21,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.Formatting.FormattingOptions;
namespace Microsoft.CodeAnalysis.Editor.CSharp.AutomaticCompletion.Sessions
{
......@@ -146,17 +147,20 @@ private void FormatTrackingSpan(IBraceCompletionSession session, IEnumerable<IFo
}
}
// skip whitespace
while (startPosition >= 0 && char.IsWhiteSpace(snapshot[startPosition]))
if (session.SubjectBuffer.GetOption(SmartIndent) != IndentStyle.None)
{
startPosition--;
}
// skip whitespace
while (startPosition >= 0 && char.IsWhiteSpace(snapshot[startPosition]))
{
startPosition--;
}
// skip token
startPosition--;
while (startPosition >= 0 && !char.IsWhiteSpace(snapshot[startPosition]))
{
// skip token
startPosition--;
while (startPosition >= 0 && !char.IsWhiteSpace(snapshot[startPosition]))
{
startPosition--;
}
}
session.SubjectBuffer.Format(TextSpan.FromBounds(Math.Max(startPosition, 0), endPosition), rules);
......
......@@ -4,6 +4,7 @@
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editor.Implementation.Formatting.Indentation;
......@@ -85,7 +86,14 @@ public IList<TextChange> FormatToken(Workspace workspace, SyntaxToken token, Can
}
var smartTokenformattingRules = (new SmartTokenFormattingRule()).Concat(_formattingRules);
return Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(previousToken.SpanStart, adjustedEndPosition) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken);
var adjustedStartPosition = previousToken.SpanStart;
if (token.IsKind(SyntaxKind.OpenBraceToken) && token.IsFirstTokenOnLine(token.SyntaxTree.GetText()) &&
workspace.Options.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) == FormattingOptions.IndentStyle.None)
{
adjustedStartPosition = token.SpanStart;
}
return Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(adjustedStartPosition, adjustedEndPosition) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken);
}
private class NoLineChangeFormattingRule : AbstractFormattingRule
......
......@@ -789,6 +789,35 @@ public void X()
}
}
[WorkItem(2224, "https://github.com/dotnet/roslyn/issues/2224")]
[Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
public void NoSmartOrBlockIndentationWithAutomaticBraceFormattingDisabled()
{
var code = @"namespace NS1
{
public class C1
$$
}";
var expected = @"namespace NS1
{
public class C1
{ }
}";
var optionSet = new Dictionary<OptionKey, object>
{
{ new OptionKey(FormattingOptions.SmartIndent, LanguageNames.CSharp), FormattingOptions.IndentStyle.None }
};
using (var session = CreateSession(code, optionSet))
{
Assert.NotNull(session);
CheckStart(session.Session);
Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText());
}
}
internal Holder CreateSession(string code, Dictionary<OptionKey, object> optionSet = null)
{
return CreateSession(
......
// 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.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Implementation.Formatting;
......@@ -1060,10 +1061,43 @@ class C1<U>
AssertFormatAfterTypeChar(code, expected);
}
private static void AssertFormatAfterTypeChar(string code, string expected)
[WorkItem(2224, "https://github.com/dotnet/roslyn/issues/2224")]
[Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
public void DontSmartFormatBracesOnSmartIndentNone()
{
var code = @"class Program<T>
{
class C1<U>
{$$
}";
var expected = @"class Program<T>
{
class C1<U>
{
}";
var optionSet = new Dictionary<OptionKey, object>
{
{ new OptionKey(FormattingOptions.SmartIndent, LanguageNames.CSharp), FormattingOptions.IndentStyle.None }
};
AssertFormatAfterTypeChar(code, expected, optionSet);
}
private static void AssertFormatAfterTypeChar(string code, string expected, Dictionary<OptionKey, object> changedOptionSet = null)
{
using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(code))
{
if (changedOptionSet != null)
{
var options = workspace.Options;
foreach (var entry in changedOptionSet)
{
options = options.WithChangedOption(entry.Key, entry.Value);
}
workspace.Options = options;
}
var subjectDocument = workspace.Documents.Single();
var textUndoHistory = new Mock<ITextUndoHistoryRegistry>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册