diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala index d7dd1974dd..783a339c75 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala @@ -1238,7 +1238,12 @@ class Router(formatOps: FormatOps) { val noSplit = if (nlOnly) Split.ignored else if (singleLineOnly || noNLPolicy == null) baseNoSplit - .withSingleLine(close, sjsExclude, noSyntaxNL = true) + .withSingleLine( + close, + sjsExclude, + noSyntaxNL = true, + killOnFail = !dangleCloseDelim, + ) else { def noSingleArgIndents = oneline || singleArgAsInfix.isDefined || !style.binPack.indentCallSiteSingleArg || @@ -1284,7 +1289,12 @@ class Router(formatOps: FormatOps) { } unindentPolicy & indentOncePolicy } - baseNoSplit.withOptimalToken(opt) + val optLite = style.newlines.keep && preferConfigStyle && + !isSingleArg + val kof = style.newlines.keep && preferConfigStyle && isSingleArg && + !dangleCloseDelim && singleArgAsInfix.isEmpty + baseNoSplit + .withOptimalToken(opt, recurseOnly = optLite, killOnFail = kof) .withPolicy(noSplitPolicy & indentPolicy & noNLPolicy()) .withIndents(noSplitIndents) } diff --git a/scalafmt-tests/src/test/resources/newlines/source_keep.stat b/scalafmt-tests/src/test/resources/newlines/source_keep.stat index b9c4584f29..c629c81fb6 100644 --- a/scalafmt-tests/src/test/resources/newlines/source_keep.stat +++ b/scalafmt-tests/src/test/resources/newlines/source_keep.stat @@ -8692,7 +8692,7 @@ object a { barBarBarBarBarBarBar; val baz = foo } -<<< SKIP #4133 binpack with complex nested applies and not forcing config style, !dangling +<<< #4133 binpack with complex nested applies and not forcing config style, !dangling binPack.preset = always danglingParentheses.preset = false runner.optimizer { @@ -8731,7 +8731,55 @@ object a { ) } >>> -FormatTests:54 [e]: org.scalafmt.Error$SearchStateExploded: Search state exploded on '[227] )∙(: RightParen [1072..1073) [] LeftParen [1073..1074)', line 27: exceeded `runner.maxStateVisits` [see https://scalameta.org/scalafmt/docs/configuration.html#search-state-exploded] +object a { + div(cls := "cover")( + div(cls := "doc")(bodyContents), + Option.when(full)( + section(id := "attributes")( + Option.when( + memberTypeParams.nonEmpty)( + Seq( + h2(cls := "h500")( + "Type parameters"), + dl(cls := "attributes")( + memberTypeParams *) + )).toSeq.flatten, + Option.when( + memberValueParams.nonEmpty)( + Seq( + h2(cls := "h500")( + "Value parameters"), + dl(cls := "attributes")( + memberValueParams *) + )).toSeq.flatten, + h2(cls := "h500")("Attributes"), + dl(cls := "attributes")( + attributes *) + ) + ).getOrElse( + Option.when( + memberTypeParams.nonEmpty)( + Seq( + h2(cls := "h200")( + "Type parameters"), + dl(cls := "attributes attributes-small")( + memberTypeParams *) + )).toSeq.flatten ++ + Option.when( + memberValueParams.nonEmpty)( + Seq( + h2(cls := "h200")( + "Value parameters"), + dl(cls := "attributes attributes-small")( + memberValueParams *) + )).toSeq.flatten :+ + h2(cls := "h200")( + "Attributes") :+ + dl(cls := "attributes attributes-small")( + attributes *) + ) + ) +} <<< #4133 binpack with complex nested applies and not forcing config style, dangling binPack.preset = always danglingParentheses.preset = true diff --git a/scalafmt-tests/src/test/resources/newlines/source_unfold.stat b/scalafmt-tests/src/test/resources/newlines/source_unfold.stat index 1876578140..c2c6712a95 100644 --- a/scalafmt-tests/src/test/resources/newlines/source_unfold.stat +++ b/scalafmt-tests/src/test/resources/newlines/source_unfold.stat @@ -8936,7 +8936,7 @@ object a { val foo = barBarBarBarBarBarBar; val baz = foo } -<<< SKIP #4133 binpack with complex nested applies and not forcing config style, !dangling +<<< #4133 binpack with complex nested applies and not forcing config style, !dangling binPack.preset = always danglingParentheses.preset = false runner.optimizer { @@ -8975,7 +8975,68 @@ object a { ) } >>> -FormatTests:54 [e]: org.scalafmt.Error$SearchStateExploded: Search state exploded on '[227] )∙(: RightParen [1072..1073) [] LeftParen [1073..1074)', line 27: exceeded `runner.maxStateVisits` [see https://scalameta.org/scalafmt/docs/configuration.html#search-state-exploded] +object a { + div(cls := "cover")( + div(cls := "doc")(bodyContents), + Option + .when(full)( + section(id := "attributes")( + Option + .when( + memberTypeParams + .nonEmpty)( + Seq( + h2(cls := "h500")( + "Type parameters"), + dl(cls := "attributes")( + memberTypeParams *))) + .toSeq + .flatten, + Option + .when( + memberValueParams + .nonEmpty)( + Seq( + h2(cls := "h500")( + "Value parameters"), + dl(cls := "attributes")( + memberValueParams *))) + .toSeq + .flatten, + h2(cls := "h500")( + "Attributes"), + dl(cls := "attributes")( + attributes *))) + .getOrElse( + Option + .when( + memberTypeParams.nonEmpty)( + Seq( + h2(cls := "h200")( + "Type parameters"), + dl( + cls := "attributes attributes-small")( + memberTypeParams *))) + .toSeq + .flatten ++ + Option + .when( + memberValueParams + .nonEmpty)( + Seq( + h2(cls := "h200")( + "Value parameters"), + dl( + cls := "attributes attributes-small")( + memberValueParams *))) + .toSeq + .flatten :+ + h2(cls := "h200")( + "Attributes") :+ + dl( + cls := "attributes attributes-small")( + attributes *))) +} <<< #4133 binpack with complex nested applies and not forcing config style, dangling binPack.preset = always danglingParentheses.preset = true diff --git a/scalafmt-tests/src/test/resources/scala3/OptionalBraces_keep.stat b/scalafmt-tests/src/test/resources/scala3/OptionalBraces_keep.stat index a044d71c2c..86a0baee81 100644 --- a/scalafmt-tests/src/test/resources/scala3/OptionalBraces_keep.stat +++ b/scalafmt-tests/src/test/resources/scala3/OptionalBraces_keep.stat @@ -6780,9 +6780,10 @@ object a: def foo = for template <- templates do val current_Map_String__Object = - template_templateFile_settings_getOrElse("page", Map.empty).asInstanceOf[ - Map_String_Object - ] + template_templateFile_settings_getOrElse( + "page", + Map.empty + ).asInstanceOf[Map_String_Object] <<< scala.js overflow within for-yield !dangling binPack.preset = always danglingParentheses.preset = false @@ -6796,8 +6797,8 @@ object a: def foo = for template <- templates do val current_Map_String__Object = - template_templateFile_settings_getOrElse("page", Map.empty).asInstanceOf[ - Map_String_Object] + template_templateFile_settings_getOrElse( + "page", Map.empty).asInstanceOf[Map_String_Object] <<< #4133 for-yield with rewritten body rewrite.scala3.removeOptionalBraces = yes === @@ -7079,10 +7080,15 @@ object a: object a: if (args.isEmpty) { run(insertClasspathInArgs(args1, - List(dottyCompiler, dottyInterfaces, asm, dottyStaging, - dottyTastyInspector, tastyCore, compilerInterface).mkString( - File.pathSeparator - ))) + List( + dottyCompiler, + dottyInterfaces, + asm, + dottyStaging, + dottyTastyInspector, + tastyCore, + compilerInterface + ).mkString(File.pathSeparator))) } else run(args) <<< #4133 overflow apply/selects with binpack, dangling maxColumn = 70 @@ -7098,10 +7104,15 @@ object a: if (args.isEmpty) { run(insertClasspathInArgs( args1, - List(dottyCompiler, dottyInterfaces, asm, dottyStaging, - dottyTastyInspector, tastyCore, compilerInterface).mkString( - File.pathSeparator - ).mkString(File.pathSeparator) + List( + dottyCompiler, + dottyInterfaces, + asm, + dottyStaging, + dottyTastyInspector, + tastyCore, + compilerInterface + ).mkString(File.pathSeparator).mkString(File.pathSeparator) )) } else run(args) <<< #4133 overflow apply with binpack, !dangling @@ -7149,11 +7160,13 @@ object a: >>> object a: if (args.isEmpty) { - run(insertClasspathInArgs( + run( + insertClasspathInArgs( args1, List(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyInspector, tastyCore, compilerInterface).mkString( - File.pathSeparator).mkString(File.pathSeparator) + File.pathSeparator).mkString( + File.pathSeparator) )) } else run(args) <<< #4133 overflow select with binpack, dangling