Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC double indentation. #3039

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/Fantomas.Core.Tests/ExperimentalDoubleIdentParametersTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module Fantomas.Core.Tests.ExperimentalDoubleIdentParametersTests

open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelpers

let config =
{ config with
ExperimentalDoubleIndentParameters = true
MaxLineLength = 10 }

[<Test>]
let ``initial sample`` () =
formatSourceString
"""
let sillyfuncWithParams parameterName1 ignoredParameterName2 ignoredParameterName3 =
longBody
"""
config
|> prepend newline
|> should
equal
"""
let sillyfuncWithParams
parameterName1
ignoredParameterName2
ignoredParameterName3
=
longBody
"""

[<Test>]
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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@auduchinok this does the double indent but has the multiline tuple parameter.
According to the existing lore, we indent each entry of the tuple.
Does this meet your expectations?

(
a:
int,
b:
int,
c:
int,
d:
int,
e:
int
) =

// Long body goes here...
longBody
"""
1 change: 1 addition & 0 deletions src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
<Compile Include="DotLambdaTests.fs" />
<Compile Include="ConstraintIntersectionTests.fs" />
<Compile Include="BeginEndTests.fs" />
<Compile Include="ExperimentalDoubleIdentParametersTests.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Fantomas.Core\Fantomas.Core.fsproj" />
Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2925,7 +2925,7 @@ let genBinding (b: BindingNode) (ctx: Context) : Context =
+> afterLetKeyword
+> sepSpace
+> genFunctionName
+> indent
+> experimentalDoubleIndent
+> sepNln
+> genParameters
+> onlyIf nlnOnSeparateLine sepNln
Expand All @@ -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

Expand Down
18 changes: 18 additions & 0 deletions src/Fantomas.Core/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/Fantomas.Core/Context.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
10 changes: 8 additions & 2 deletions src/Fantomas.Core/FormatConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ type FormatConfig =

[<Category("Convention")>]
[<DisplayName("Applies the Stroustrup style to the final (two) array or list argument(s) in a function application")>]
ExperimentalElmish: bool }
ExperimentalElmish: bool

[<Category("Indentation")>]
[<DisplayName("Double indent parameters")>]
[<Description("Use double indentation for parameters.")>]
ExperimentalDoubleIndentParameters: bool }

member x.IsStroustrupStyle = x.MultilineBracketStyle = Stroustrup

Expand Down Expand Up @@ -268,4 +273,5 @@ type FormatConfig =
MultilineBracketStyle = Cramped
KeepMaxNumberOfBlankLines = 100
NewlineBeforeMultilineComputationExpression = true
ExperimentalElmish = false }
ExperimentalElmish = false
ExperimentalDoubleIndentParameters = false }
23 changes: 21 additions & 2 deletions src/Fantomas.Tests/EditorConfigurationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ fsharp_multiline_bracket_style = cramped
Assert.That(config.MultilineBracketStyle, Is.EqualTo Cramped)

[<Test>]
let fsharp_prefer_computation_expression_name_on_same_line () =
let fsharp_newline_before_multiline_computation_expression () =
let rootDir = tempName ()

let editorConfig =
Expand All @@ -526,7 +526,7 @@ fsharp_newline_before_multiline_computation_expression = false
Assert.That(config.NewlineBeforeMultilineComputationExpression, Is.False)

[<Test>]
let fsharp_stroustrup_final_list_arguments () =
let fsharp_experimental_elmish () =
let rootDir = tempName ()

let editorConfig =
Expand All @@ -543,3 +543,22 @@ fsharp_experimental_elmish = true
let config = EditorConfig.readConfiguration fsharpFile.FSharpFile

Assert.That(config.ExperimentalElmish, Is.True)

[<Test>]
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)
Loading