diff --git a/docs/configuration.md b/docs/configuration.md index ce59d1d226..d5ad160838 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -901,6 +901,10 @@ to be exempted from the default indentation rule: [scala-js coding style](https://github.com/scala-js/scala-js/blob/main/CODINGSTYLE.md#long-expressions-with-binary-operators). - `all`: all infix operators - this value replaced deprecated `indentOperator.topLevelOnly=false` +- `notAssign` (since v3.8.4): any non-assignment operator + - this value expanded upon deprecated `verticalAlignMultilineOperators` + which now simply maps to `{ exemptScope = notAssign, excludeRegex = ".*" }` +- `notWithinAssign` (since v3.8.4): any infix not part of a larger assignment expression ```scala mdoc:scalafmt indent.infix.exemptScope = oldTopLevel @@ -1026,11 +1030,6 @@ renamed from `indentOperator.include`. indent.infix.includeRegex ``` -#### `indent.infix.assignmentOnly` - -Indents only after an assignment operator. Prior to v3.8.4, was called -`verticalAlignMultilineOperators`. - #### `indent.infix.preset` - `default` diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/IndentOperator.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/IndentOperator.scala index 2659a3ac62..25f600654d 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/IndentOperator.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/IndentOperator.scala @@ -90,8 +90,16 @@ object IndentOperator { case object oldTopLevel extends Exempt case object aloneEnclosed extends Exempt case object aloneArgOrBody extends Exempt + case object notAssign extends Exempt + case object notWithinAssign extends Exempt - implicit val reader: ConfCodecEx[Exempt] = ReaderUtil - .oneOf[Exempt](all, oldTopLevel, aloneEnclosed, aloneArgOrBody) + implicit val reader: ConfCodecEx[Exempt] = ReaderUtil.oneOf[Exempt]( + all, + oldTopLevel, + aloneEnclosed, + aloneArgOrBody, + notAssign, + notWithinAssign, + ) } } diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala index cf0f09b380..7f8a94a86d 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatOps.scala @@ -575,6 +575,7 @@ class FormatOps( case IndentOperator.Exempt.oldTopLevel => isOldTopLevel(getChild) case IndentOperator.Exempt.aloneEnclosed => isAloneEnclosed(getChild) case IndentOperator.Exempt.aloneArgOrBody => isAloneArgOrBody(getChild) + case _ => true } if (cfg.assignmentOnly) isAfterAssignmentOp(false) else if (beforeLhs) assignBodyExpire.isEmpty diff --git a/scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalAlignMultilineOperators.stat b/scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalAlignMultilineOperators.stat index ed64dfd193..7ebfca9b06 100644 --- a/scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalAlignMultilineOperators.stat +++ b/scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalAlignMultilineOperators.stat @@ -37,3 +37,167 @@ object Foo3 { a + b } +<<< #4681 verticalAlignMultilineOperators +maxColumn = 16 +=== +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} +>>> +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} +<<< #4681 notAssign +maxColumn = 16 +indent.infix { + exemptScope = notAssign + excludeRegex = ".*" +} +=== +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} +>>> +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} +<<< #4681 notWithinAssign +maxColumn = 16 +indent.infix { + exemptScope = notWithinAssign + excludeRegex = ".*" +} +=== +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} +>>> +object a { + val foo1 = a + + b + foo1 = aaaa - + bbbb + foo1 = + aaaabbbb + foo1 += aaaa - + bbbb + foo1 += + aaaabbbb + foo1 == aaaa - + bbbb + foo1 == + aaaabbbb + foo1 := aaaa - + bbbb + foo1 := + aaaabbbb + foo1 >= aaaa - + bbbb + foo1 >= + aaaabbbb +} diff --git a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala index c85fb1b067..596bd967ce 100644 --- a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala +++ b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala @@ -144,7 +144,7 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { val explored = Debug.explored.get() logger.debug(s"Total explored: $explored") if (!onlyUnit && !onlyManual) - assertEquals(explored, 1241608, "total explored") + assertEquals(explored, 1241926, "total explored") val results = debugResults.result() // TODO(olafur) don't block printing out test results. // I don't want to deal with scalaz's Tasks :'(