Skip to content

Commit

Permalink
Add flags to support apache/spark style of configuration
Browse files Browse the repository at this point in the history
Add a `verticalAlignMultilineOperators` boolean flag to vertically align multiline operator chains

Make `danglingParentheses` a case class so it can be specified separately for def and call sites (we only enable it for callsites)
  • Loading branch information
lihaoyi-databricks authored and olafurpg committed Apr 3, 2019
1 parent ef17130 commit 53409ef
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.scalafmt.config

import metaconfig._

case class DanglingParentheses(
callSite: Boolean,
defnSite: Boolean
) {
val decoder: ConfDecoder[DanglingParentheses] =
generic.deriveDecoder(this).noTypos
}
object DanglingParentheses {
val default = DanglingParentheses(true, true)
implicit lazy val surface: generic.Surface[DanglingParentheses] =
generic.deriveSurface

implicit val decoder: ConfDecoder[DanglingParentheses] =
ConfDecoder.instance[DanglingParentheses] {
case Conf.Bool(true) => Configured.Ok(DanglingParentheses(true, true))
case Conf.Bool(false) => Configured.Ok(DanglingParentheses(false, false))
case els => default.decoder.read(els)
}

implicit val encoder: ConfEncoder[DanglingParentheses] =
ConfEncoder.instance[DanglingParentheses] {
case DanglingParentheses(true, true) => Conf.Bool(true)
case DanglingParentheses(true, false) =>
Conf.Obj("callSite" -> Conf.Bool(true), "defnSite" -> Conf.Bool(false))
case DanglingParentheses(false, true) =>
Conf.Obj("callSite" -> Conf.Bool(false), "defnSite" -> Conf.Bool(true))
case DanglingParentheses(false, false) => Conf.Bool(false)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,15 @@ case class ScalafmtConfig(
includeCurlyBraceInSelectChains: Boolean = true,
includeNoParensInSelectChains: Boolean = false,
assumeStandardLibraryStripMargin: Boolean = false,
danglingParentheses: Boolean = true,
danglingParentheses: DanglingParentheses = DanglingParentheses(true, true),
poorMansTrailingCommasInConfigStyle: Boolean = false,
trailingCommas: TrailingCommas = TrailingCommas.never,
@deprecated("Use VerticalMultiline.atDefnSite instead", "1.6.0")
verticalMultilineAtDefinitionSite: Boolean = false,
@deprecated("Use VerticalMultiline.arityThreshold instead", "1.6.0")
verticalMultilineAtDefinitionSiteArityThreshold: Int = 100,
verticalMultiline: VerticalMultiline = VerticalMultiline(),
verticalAlignMultilineOperators: Boolean = false,
onTestFailure: String = "",
encoding: Codec = "UTF-8",
project: ProjectFiles = ProjectFiles()
Expand Down Expand Up @@ -212,7 +213,7 @@ object ScalafmtConfig {
optIn = default.optIn.copy(
configStyleArguments = false
),
danglingParentheses = true
danglingParentheses = DanglingParentheses(true, true)
)

def addAlign(style: ScalafmtConfig): ScalafmtConfig = style.copy(
Expand Down Expand Up @@ -286,7 +287,7 @@ object ScalafmtConfig {
maxColumn = 79,
assumeStandardLibraryStripMargin = false,
includeCurlyBraceInSelectChains = false,
danglingParentheses = false,
danglingParentheses = DanglingParentheses(false, false),
align = default.align.copy(
tokens = Set.empty,
openParenCallSite = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,9 @@ class FormatOps(val tree: Tree, val initStyle: ScalafmtConfig) {
rightIsComment = formatToken.right.isInstanceOf[Comment]
)
val indent = {
if (style.unindentTopLevelOperators &&
if (style.verticalAlignMultilineOperators) {
if (formatToken.left.text == "=") 2 else 0
} else if (style.unindentTopLevelOperators &&
!isTopLevelInfixApplication(owner) &&
style.indentOperator.includeRegexp
.findFirstIn(formatToken.left.syntax)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,18 +665,21 @@ class Router(formatOps: FormatOps) {

val tooManyArguments = args.length > 100

val newlinePolicy: Policy = if (style.danglingParentheses) {
val breakOnClosing = Policy({
case d @ Decision(FormatToken(_, `close`, _), s) =>
d.onlyNewlines
}, close.end)
breakOnClosing
} else {
Policy(PartialFunction.empty[Decision, Decision], close.end)
}
val newlinePolicy: Policy =
if (style.danglingParentheses.defnSite && defnSite ||
style.danglingParentheses.callSite && !defnSite) {
val breakOnClosing = Policy({
case d @ Decision(FormatToken(_, `close`, _), s) =>
d.onlyNewlines
}, close.end)
breakOnClosing
} else {
Policy(PartialFunction.empty[Decision, Decision], close.end)
}

val noSplitPolicy =
if (style.danglingParentheses) {
if (style.danglingParentheses.defnSite && defnSite ||
style.danglingParentheses.callSite && !defnSite) {
SingleLineBlock(close, exclude = excludeRanges)
} else singleLine(10)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
maxColumn = 6
danglingParentheses = {callSite: true, defnSite: false}

<<< classes and methods
object Foo3 {
def f(a: A, b: B, c: C) = 1
class F(a: A, b: B, c: C)

f(a, b, c)
new F(a, b, c)
}
>>>
object Foo3 {
def f(
a: A,
b: B,
c: C) =
1
class F(
a: A,
b: B,
c: C)

f(
a,
b,
c
)
new F(
a,
b,
c
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
verticalAlignMultilineOperators = true
maxColumn = 10

<<< in function call
object Foo1 {
function(
a &&
b
)
}
>>>
object Foo1 {
function(
a &&
b
)
}
<<< after assignment
object Foo2 {
val x =
a +
b
}
>>>
object Foo2 {
val x =
a +
b
}
<<< in template body
object Foo3 {
a +
b
}
>>>
object Foo3 {
a +
b
}

0 comments on commit 53409ef

Please sign in to comment.