From 50b257a2b323869650bab8280248733194fdfa7b Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 30 Jan 2024 17:20:01 +0100 Subject: [PATCH 1/3] POC double indentation. --- .../ExperimentalDoubleIdentParametersTests.fs | 30 +++++++++++++++++++ .../Fantomas.Core.Tests.fsproj | 1 + src/Fantomas.Core/FormatConfig.fs | 10 +++++-- .../EditorConfigurationTests.fs | 23 ++++++++++++-- 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs diff --git a/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs b/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs new file mode 100644 index 0000000000..afabb526db --- /dev/null +++ b/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs @@ -0,0 +1,30 @@ +module Fantomas.Core.Tests.ExperimentalDoubleIdentParametersTests + +open NUnit.Framework +open FsUnit +open Fantomas.Core.Tests.TestHelpers + +let config = + { config with + ExperimentalDoubleIndentParameters = true + MaxLineLength = 10 } + +[] +let ``initial sample`` () = + formatSourceString + """ +let sillyfuncWithParams parameterName1 ignoredParameterName2 ignoredParameterName3 = + longBody +""" + config + |> prepend newline + |> should + equal + """ +let sillyfuncWithParams + parameterName1 + ignoredParameterName2 + ignoredParameterName3 + = + longBody +""" diff --git a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj index dcaf08cfa3..a004379070 100644 --- a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj +++ b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj @@ -132,6 +132,7 @@ + diff --git a/src/Fantomas.Core/FormatConfig.fs b/src/Fantomas.Core/FormatConfig.fs index e2abad7247..a257781b76 100644 --- a/src/Fantomas.Core/FormatConfig.fs +++ b/src/Fantomas.Core/FormatConfig.fs @@ -227,7 +227,12 @@ type FormatConfig = [] [] - ExperimentalElmish: bool } + ExperimentalElmish: bool + + [] + [] + [] + ExperimentalDoubleIndentParameters: bool } member x.IsStroustrupStyle = x.MultilineBracketStyle = Stroustrup @@ -268,4 +273,5 @@ type FormatConfig = MultilineBracketStyle = Cramped KeepMaxNumberOfBlankLines = 100 NewlineBeforeMultilineComputationExpression = true - ExperimentalElmish = false } + ExperimentalElmish = false + ExperimentalDoubleIndentParameters = false } diff --git a/src/Fantomas.Tests/EditorConfigurationTests.fs b/src/Fantomas.Tests/EditorConfigurationTests.fs index 6c00fdc2a3..dfa4c0da2f 100644 --- a/src/Fantomas.Tests/EditorConfigurationTests.fs +++ b/src/Fantomas.Tests/EditorConfigurationTests.fs @@ -507,7 +507,7 @@ fsharp_multiline_bracket_style = cramped Assert.That(config.MultilineBracketStyle, Is.EqualTo Cramped) [] -let fsharp_prefer_computation_expression_name_on_same_line () = +let fsharp_newline_before_multiline_computation_expression () = let rootDir = tempName () let editorConfig = @@ -526,7 +526,7 @@ fsharp_newline_before_multiline_computation_expression = false Assert.That(config.NewlineBeforeMultilineComputationExpression, Is.False) [] -let fsharp_stroustrup_final_list_arguments () = +let fsharp_experimental_elmish () = let rootDir = tempName () let editorConfig = @@ -543,3 +543,22 @@ fsharp_experimental_elmish = true let config = EditorConfig.readConfiguration fsharpFile.FSharpFile Assert.That(config.ExperimentalElmish, Is.True) + +[] +let fsharp_experimental_double_indent_parameters () = + let rootDir = tempName () + + let editorConfig = + """ +[*.fs] +fsharp_experimental_double_indent_parameters = true +""" + + use configFixture = + new ConfigurationFile(defaultConfig, rootDir, content = editorConfig) + + use fsharpFile = new FSharpFile(rootDir) + + let config = EditorConfig.readConfiguration fsharpFile.FSharpFile + + Assert.That(config.ExperimentalDoubleIndentParameters, Is.True) From c4f0774bfc40a7a7b91feb25dc5c52aa0f29c442 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 9 Feb 2024 11:52:25 +0100 Subject: [PATCH 2/3] Extract helper function to Context. --- src/Fantomas.Core/CodePrinter.fs | 4 ++-- src/Fantomas.Core/Context.fs | 18 ++++++++++++++++++ src/Fantomas.Core/Context.fsi | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 94a282eb62..3ab606d351 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -2925,7 +2925,7 @@ let genBinding (b: BindingNode) (ctx: Context) : Context = +> afterLetKeyword +> sepSpace +> genFunctionName - +> indent + +> experimentalDoubleIndent +> sepNln +> genParameters +> onlyIf nlnOnSeparateLine sepNln @@ -2934,7 +2934,7 @@ let genBinding (b: BindingNode) (ctx: Context) : Context = sepNln +> genSingleTextNode b.Equals else sepSpace +> genSingleTextNode b.Equals) - +> unindent + +> experimentalDoubleUnindent +> onlyIf hasTriviaAfterLeadingKeyword unindent) ctx diff --git a/src/Fantomas.Core/Context.fs b/src/Fantomas.Core/Context.fs index 31540dcb3f..14629a5ced 100644 --- a/src/Fantomas.Core/Context.fs +++ b/src/Fantomas.Core/Context.fs @@ -391,6 +391,24 @@ let indent (ctx: Context) = let unindent (ctx: Context) = writerEvent (UnIndentBy ctx.Config.IndentSize) ctx +let experimentalDoubleIndent (ctx: Context) = + let indentSize = + if not ctx.Config.ExperimentalDoubleIndentParameters then + ctx.Config.IndentSize + else + 2 * ctx.Config.IndentSize + + writerEvent (IndentBy indentSize) ctx + +let experimentalDoubleUnindent (ctx: Context) = + let indentSize = + if not ctx.Config.ExperimentalDoubleIndentParameters then + ctx.Config.IndentSize + else + 2 * ctx.Config.IndentSize + + writerEvent (UnIndentBy indentSize) ctx + /// Apply function f at an absolute indent level (use with care) let atIndentLevel alsoSetIndent level (f: Context -> Context) (ctx: Context) = if level < 0 then diff --git a/src/Fantomas.Core/Context.fsi b/src/Fantomas.Core/Context.fsi index 9118d47469..dab39de20b 100644 --- a/src/Fantomas.Core/Context.fsi +++ b/src/Fantomas.Core/Context.fsi @@ -78,6 +78,15 @@ val lastWriteEventIsNewline: ctx: Context -> bool val indent: ctx: Context -> Context /// Unindent one more level based on configuration val unindent: ctx: Context -> Context + +/// Add double indent if ExperimentalDoubleIndentParameters is active +/// Otherwise, add single indent +val experimentalDoubleIndent: ctx: Context -> Context + +/// Add double unindent if ExperimentalDoubleIndentParameters is active +/// Otherwise, add single unindent +val experimentalDoubleUnindent: ctx: Context -> Context + // /// Apply function f at an absolute indent level (use with care) val atIndentLevel: alsoSetIndent: bool -> level: int -> f: (Context -> Context) -> ctx: Context -> Context // /// Set minimal indentation (`atColumn`) at current column position - next newline will be indented on `max indent atColumn` From 285a4a03e915b17fd8f5f66f778956e64aa6de9e Mon Sep 17 00:00:00 2001 From: nojaf Date: Sat, 10 Feb 2024 10:15:11 +0100 Subject: [PATCH 3/3] Add example of long member with tuple parameter. --- .../ExperimentalDoubleIdentParametersTests.fs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs b/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs index afabb526db..c07d93a6b8 100644 --- a/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs +++ b/src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs @@ -28,3 +28,37 @@ let sillyfuncWithParams = longBody """ + +[] +let ``sample in long member`` () = + formatSourceString + """ +type X() = + member x.Y(a:int, b:int, c:int, d:int, e:int) = + + // Long body goes here... + longBody +""" + config + |> prepend newline + |> should + equal + """ +type X() = + member x.Y + ( + a: + int, + b: + int, + c: + int, + d: + int, + e: + int + ) = + + // Long body goes here... + longBody +"""