-
Notifications
You must be signed in to change notification settings - Fork 276
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
Add verticalMultilineAtDefinitionSiteArityThreshold setting #1143
Changes from all commits
db40ab1
9f33a58
27364b2
4444f20
439b42a
4a034ce
f4f1384
de1b363
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,12 +109,15 @@ import org.scalafmt.util.ValidationOps | |
* ) | ||
* }}} | ||
* | ||
* All parameters are on their on line indented by four (4), seperation between | ||
* parament groups are indented by two (2). ReturnType is on its own line at | ||
* then end. This will only trigger if the function would go over | ||
* [[maxColumn]]. If a multi-line funcion can fit in a single line, it will | ||
* All parameters are on their own line indented by four (4), separation between | ||
* parameter groups are indented by two (2). ReturnType is on its own line at | ||
* the end. This will only be triggered if the function would go over | ||
* [[maxColumn]]. If a multi-line function can fit in a single line, it will | ||
* make it so. Note that this setting ignores continuation.defnSite, | ||
* [[binPack.unsafeDefnSite]], and [[align.openParenDefnSite]]. | ||
* @param verticalMultilineAtDefinitionSiteArityThreshold If set, this will trigger a vertical multi-line formatting as | ||
* described above even though the definition falls below the | ||
* [[maxColumn]] width. | ||
*/ | ||
@DeriveConfDecoder | ||
case class ScalafmtConfig( | ||
|
@@ -142,6 +145,7 @@ case class ScalafmtConfig( | |
danglingParentheses: Boolean = false, | ||
poorMansTrailingCommasInConfigStyle: Boolean = false, | ||
verticalMultilineAtDefinitionSite: Boolean = false, | ||
verticalMultilineAtDefinitionSiteArityThreshold: Int = 100, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really wanted to make this an Option but there isn't a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't remember why I never implemented a decoder for Option[T], there was some reason. I agree dummy Int values are not great, but it's consistent with some other settings so it's fine here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I'll leave this as it for now then 👍 |
||
onTestFailure: String = "", | ||
encoding: Codec = "UTF-8", | ||
@Recurse project: ProjectFiles = ProjectFiles() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,20 +4,19 @@ import scala.annotation.tailrec | |
import scala.collection.mutable | ||
import scala.meta.Case | ||
import scala.meta.Ctor | ||
import scala.meta.Decl | ||
import scala.meta.Defn | ||
import scala.meta.Import | ||
import scala.meta.Name | ||
import scala.meta.Pat | ||
import scala.meta.Pkg | ||
import scala.meta.Template | ||
import scala.meta.Term | ||
import scala.meta.Term.Apply | ||
import scala.meta.Tree | ||
import scala.meta.Type | ||
import scala.meta.prettyprinters.Structure | ||
import scala.meta.tokens.Token | ||
import scala.meta.tokens.Token._ | ||
import scala.meta.tokens.Tokens | ||
import org.scalafmt.Error.CaseMissingArrow | ||
import org.scalafmt.config.ScalafmtConfig | ||
import org.scalafmt.internal.ExpiresOn.Left | ||
|
@@ -31,7 +30,6 @@ import org.scalafmt.util.TreeOps | |
import org.scalafmt.util.Whitespace | ||
import org.scalafmt.util.Modifier | ||
import org.scalafmt.util.RightParenOrBracket | ||
import org.scalameta.logger | ||
|
||
/** | ||
* Helper functions for generating splits/policies for a given tree. | ||
|
@@ -823,8 +821,19 @@ class FormatOps(val tree: Tree, val initStyle: ScalafmtConfig) { | |
if (isBracket) close // If we can fit the type params, make it so | ||
else lastParen // If we can fit all in one block, make it so | ||
|
||
val maxArity = valueParamsOwner match { | ||
case d: Decl.Def if d.paramss.nonEmpty => d.paramss.map(_.size).max | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Seems in v1 @ q"@a(1)(2) def foo = 1"
res1: Defn.Def = Defn.Def(List(Mod.Annot(Term.Apply(Term.Apply(Ctor.Ref.Name("a"), List(Lit.Int(1))), List(Lit.Int(2))))), Term.Name("foo"), List(), List(), None, Lit.Int(1)) It's fine to skip those as they only appear in curried annotations, which is quite rare. |
||
case d: Defn.Def if d.paramss.nonEmpty => d.paramss.map(_.size).max | ||
case m: Defn.Macro if m.paramss.nonEmpty => m.paramss.map(_.size).max | ||
case c: Ctor.Primary if c.paramss.nonEmpty => c.paramss.map(_.size).max | ||
case c: Ctor.Secondary if c.paramss.nonEmpty => c.paramss.map(_.size).max | ||
case _ => 0 | ||
} | ||
|
||
val aboveArityThreshold = maxArity >= style.verticalMultilineAtDefinitionSiteArityThreshold | ||
|
||
Seq( | ||
Split(NoSplit, 0) | ||
Split(NoSplit, 0, ignoreIf = !isBracket && aboveArityThreshold) | ||
.withPolicy(SingleLineBlock(singleLineExpire)), | ||
Split(Newline, 1) // Otherwise split vertically | ||
.withIndent(firstIndent, close, Right) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
maxColumn = 80 | ||
verticalMultilineAtDefinitionSite = true | ||
verticalMultilineAtDefinitionSiteArityThreshold = 2 | ||
danglingParentheses = true | ||
continuationIndent.defnSite = 2 | ||
<<< Verify that verticalMultilineAtDefinitionSiteArityThreshold works as expected | ||
case class Foo(x: String) | ||
case class Bar(x: String, y: String) | ||
case class VeryLongNames(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String) | ||
object A { | ||
def foo(x: String, y: String) | ||
def hello(how: String)(are: String)(you: String) = how + are + you | ||
} | ||
>>> | ||
case class Foo(x: String) | ||
case class Bar( | ||
x: String, | ||
y: String) | ||
case class VeryLongNames( | ||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dangling parentheses is explicitly ignored for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @olafurpg Do you have any thoughts in this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, is this a peculiarity of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mads-hartmann Yeah, the feature ignores dangling (and most other options). It is one of those features that don't make sense if it listens to every other scalafmt option. It is a holistic style, instead of a piece-meal one (like dangling or align). As for why, well it looks ugly if you allow dangling. So it only dangles when the class |
||
object A { | ||
def foo( | ||
x: String, | ||
y: String | ||
) | ||
def hello(how: String)(are: String)(you: String) = how + are + you | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job figuring out the fancy website generation 😄