id | title |
---|---|
configuration |
Configuration |
Configuration for scalafmt is defined in a plain text file .scalafmt.conf
using HOCON syntax.
Here is an example .scalafmt.conf
:
align.preset = more // For pretty alignment.
maxColumn = 100 // For my wide 30" display.
maxColumn
- Keep in mind that 80 characters fit perfectly on a split laptop screen with regular resolution.
- GitHub mobile view only shows 80 characters and sometimes you might review code on your phone.
- Consider refactoring your code before of choosing a value above 100.
This parameter simply says the .stripMargin
method was not redefined by the
user to assign special meaning to indentation preceding the |
character.
Hence, that indentation can be modified.
assumeStandardLibraryStripMargin
align.stripMargin
If true
, lines starting with the margin character |
(or another if specified
in the .stripMargin(...)
call) will be indented differently.
If align.stripMargin
is true, they will align with the opening triple-quote
"""
in interpolated and raw string literals. Otherwise, they will be indented
relative to the start of the opening line.
assumeStandardLibraryStripMargin = true
align.stripMargin = true
---
val example1 =
s"""Examples:
| * one
| * two
| * $three
|""".stripMargin
assumeStandardLibraryStripMargin = true
align.stripMargin = false
---
val example1 =
s"""|Examples:
| * one
| * two
| * $three
|""".stripMargin
The pipe character can immediately follow the opening """
assumeStandardLibraryStripMargin = true
align.stripMargin = true
---
val example2 =
s"""|Examples:
| * one
| * two
| * $three
|""".stripMargin
Some sections provide preset values to set multiple parameters at once. These
are always accessed via the preset
key of the appropriate section, including
top-level.
preset=default
: this preset is implicit and sets all values to their defaults.preset=IntelliJ
: this preset is defined as
preset = default
continuationIndent.defnSite = 2
optIn.configStyleArguments = false
preset=defaultWithAlign
: this preset is defined as
preset = default
align.preset = more
preset=Scala.js
: this preset is defined as
preset = default
binPack.preset = true
align.ifWhileOpenParen = false
continuationIndent.callSite = 4
docstrings.style = Asterisk
importSelectors = binPack
newlines {
neverInResultType = true
neverBeforeJsNative = true
sometimesBeforeColonInMethodReturnType = false
}
runner.optimizer {
forceConfigStyleOnOffset = 500
forceConfigStyleMinArgCount = 5
}
continuationIndent.callSite
Example:
continuationIndent.callSite = 2
---
function(
argument1, // indented by 2
""
)
continuationIndent.defnSite
Same as continuationIndent.callSite
except for definition site. Example:
continuationIndent.defnSite = 4
---
def function(
argument1: Type1 // indented by 4
): ReturnType
Since v2.5.0.
Applies to constructors. Defaults to continuationIndent.defnSite
.
continuationIndent.ctorSite = 4
continuationIndent.defnSite = 2
---
class A(
field1: Type1 // indented by 4
) {
def function2(
argument1: Type1 // indented by 2
): ReturnType = None
}
continuationIndent.extendSite
continuationIndent.withSiteRelativeToExtends
continuationIndent.extendSite = 4
# this one added in v2.5.0
continuationIndent.withSiteRelativeToExtends = 2
maxColumn = 30
---
trait Foo extends A with B with C with D with E {
def foo: Boolean = true
}
Normally, the first eligible break inside a chain of infix operators is indented by 2.
This group of parameters allows overriding which infix operators are eligible and controls when indentation is omitted.
If true, only top-level infix operators are eligible to be exempted from the default indentation rule.
indentOperator.topLevelOnly
indentOperator.topLevelOnly = true
---
function(
a &&
b
)
function {
a &&
b
}
indentOperator.topLevelOnly = false
---
function(
a &&
b
)
function {
a &&
b
}
Defines a regular expression for excluded infix operators. If an eligible operator matches, it will not be indented.
indentOperator.exclude
Defines a regular expression for included infix operators. If an eligible operator matches and is not excluded explicitly by indentOperator.exclude, it be will indented.
indentOperator.include
default
- use defaults for all fields
spray
(alsoakka
)- set
include = "^.*=$"
,exclude = "^$"
- set
Default: some
Align has several nested fields, which you can customize. However, it comes with four possible presets: none, some, more, & most.
align.preset = none
---
x match { // false for case arrows
case 2 => 22 // also comments!
case 22 => 222 // don't align me!
}
Pro tip: Enable this setting to minimize git diffs/conflicts from renamings and other refactorings, without having to ignore whitespace changes in diffs or use
--ignore-all-space
to avoid conflicts when git merging or rebasing.
Starting with the introduction of
align.stripMargin
parameter in v2.5.0, one must explicitly enable it to get earlier behaviour ofalign.preset=none
. See assumeStandardLibraryStripMargin.
align.preset = some
---
x match { // true for case arrows
case 2 => 22
case 22 => 222
}
val x = 2 // false for assignment
val xx = 22
case object B extends A // false for `extends`
case object BB extends A
align.preset = more
---
val x = 2 // true for assignment
val xx = 22
case object B extends A // true for `extends`
case object BB extends A
q -> 22 // true for various infix operators
qq -> 3 // and also comments!
for {
x <- List(1) // true for alignment enumerator
yyy <- List(2)
} yield x ** yyy
x match { // true for multiple tokens across multiple lines
case 1 => 1 -> 2 // first
case 11 => 11 -> 22 // second
// A blank line separates alignment blocks.
case `ignoreMe` => 111 -> 222
}
// Align assignments of similar type.
def name = column[String]("name")
def status = column[Int]("status")
val x = 1
val xx = 22
// Align sbt module IDs.
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"com.lihaoyi" %% "sourcecode" % "0.1.1"
)
align.preset = most
---
for {
// align <- with =
x <- List()
yyy = 2
// aligns body by arrow
zzz <- new Integer {
def value = 3
}
} yield x
Note. Only for the truest vertical aligners. Feel free to open PR enabling more crazy vertical alignment here. Expect changes.
Default: [caseArrow]
An align token is a pair of code
, which is the string literal of an operator
of token, and owner
, which is the kind of the closest tree node that owns that
token. If no owner
is provided, then all tree kinds will be matched.
align.tokens = [{code = "=>", owner = "Case"}]
---
x match {
case 1 => 1 -> 2
case 11 => 11 -> 22
}
align.tokens = [
{code = "%", owner = "Term.ApplyInfix"},
{code = "%%", owner = "Term.ApplyInfix"}
]
---
val x = List(
"org.scala-lang" %% "scala-compiler" % scalaVersion.value,
"com.lihaoyi" %% "sourcecode" % "0.1.1"
)
To find the owner
part for a custom tree, depend on Scalameta and use
scala.meta.Tree.productPrefix
from the (for example, Ammonite) REPL.
@ import $ivy.`org.scalameta:scalameta_2.12:@SCALAMETA_VERSION@`, scala.meta._
@ val termMatch = q"x match { case 2 => foo(bar) }"
termMatch: Term.Match = x match {
case 2 =>
foo(bar)
}
@ termMatch.structure
res0: String = """
Term.Match(Term.Name("x"), Seq(Case(Lit.Int(2), None, Term.Apply(Term.Name("foo"), Seq(Term.Name("bar"))))))
"""
@ termMatch.productPrefix
res1: String = "Term.Match"
Usage is identical to align.tokens
, but token pairs will be added to
defaults rather than replacing them.
align.arrowEnumeratorGenerator
align.arrowEnumeratorGenerator = false
---
for {
x <- new Integer {
def value = 2
}
} yield x
align.arrowEnumeratorGenerator = true
---
for {
x <- new Integer {
def value = 2
}
} yield x
align.openParenCallSite
Default changed from
true
tofalse
in v1.6.
align.openParenCallSite = true
---
foo(arg1, arg2)
function(arg1, // align by (
arg2,
arg3)
function(
argument1,
argument2)
align.openParenCallSite = false
---
foo(arg1, arg2)
function(arg1, // no align by (
arg2,
arg3)
function(
argument1,
argument2)
align.openParenDefnSite
Default changed from
true
tofalse
in v1.6.
align.openParenDefnSite = true
---
class IntString(int: Int, string: String)
class IntStringLong(int: Int,
string: String,
long: Long)
align.openParenDefnSite = false
---
class IntString(int: Int, string: String)
class IntStringLong(
int: Int,
string: String,
long: Long
)
See assumeStandardLibraryStripMargin.
align.stripMargin
This functionality is enabled in all presets except align.preset=none
where it
was disabled since the parameter's introduction in v2.5.0.
If this flag is set, when alignment is applied, multiline statements will not be excluded from search of tokens to align.
Since v2.5.0.
align.multiline
align.preset = more
align.multiline = true
---
for {
a <- aaa
bbb <- bb
cccccc <- c {
3
}
dd <- ddddd
} yield ()
align.preset = more
align.multiline = false
---
for {
a <- aaa
bbb <- bb
cccccc <- c {
3
}
dd <- ddddd
} yield ()
The newlines.*
options are used to configure when and where scalafmt
should
insert newlines.
You might be interested in the Vertical Multiline section.
Since v2.5.0.
This parameter controls the general approach to line breaks, and whether to take into account existing newlines in the source. The default value (if the parameter is not specified) is the classic, original way. Below are the alternatives.
These alternatives are EXPERIMENTAL and might change in the future without regard to any
edition
settings, until fully released (and this message deleted).
This approach attempts to preserve line breaks in the input whenever possible.
These two approaches completely ignore existing line breaks, except around comments and blank lines (i.e., multiple consecutive newlines).
Might require increasing runner limits (
runner.optimizer.maxVisitsPerToken
, possibly evenrunner.maxStateVisits
), to avoid SearchStateExploded exceptions.
fold
attempts to remove line breaks whenever possible resulting in a more
horizontal, or vertically compact look.
unfold
, on the other hand, is intended for those who prefer a more vertical,
or horizontally compact look.
Both settings attempt to play nice with other parameters, but some combinations are prohibited and will result in an error.
This formatting applies to argument lists in class definitions and method calls.
It normally involves a newline after the opening parenthesis (or after the
implicit
keyword) and a newline before the closing parenthesis.
As part of the formatting output, arguments are output one per line (but this is not used in determining whether the source uses config-style formatting).
While this parameter is not technically under the newlines
section, it
logically belongs there.
If true, applies config-style formatting:
- if single-line formatting is impossible
- if the source uses config-style and
newlines.source = classic/keep
- if other parameters force config-style (see below)
optIn.configStyleArguments
optIn.configStyleArguments = true
maxColumn=45
---
object a {
// keeps single line
def method1(a: Int, b: String): Boolean
// forces config style
def method2(a: Int, b: String, c: String): Boolean
// preserves config style
def method3(
a: Int, b: String, c: String
): Boolean
}
Controls parameters which trigger forced config-style formatting. All conditions must be satisfied in order for this rule to apply.
runner.optimizer.forceConfigStyleOnOffset
runner.optimizer.forceConfigStyleMinArgCount
runner.optimizer.forceConfigStyleOnOffset
: applies to method calls; if positive, specifies the minimum character distance between the matching parentheses, excluding any whitespacerunner.optimizer.forceConfigStyleMinArgCount
applies to method calls; specifies the minimum number of arguments
optIn.configStyleArguments = true
runner.optimizer.forceConfigStyleOnOffset = 5
runner.optimizer.forceConfigStyleMinArgCount = 2
maxColumn = 60
---
object a {
// this is a definition, not a method call
def method(a: String, b: String = null): Boolean
// keeps single line; min offset not satisfied
method(a, b)
// keeps single line; min arg not satisfied
method(SomeVeryVeryVeryVeryLongArgument)
// forces config style
method(foo, bar)
}
While this parameter is not technically under the newlines
section, it
logically belongs there.
danglingParentheses.defnSite
danglingParentheses.defnSite = true
danglingParentheses.callSite = false
maxColumn=25
---
object a {
// defnSite
def method(a: Int, b: String): Boolean
// callSite
method(argument1, argument2)
}
danglingParentheses.callSite
danglingParentheses.defnSite = false
danglingParentheses.callSite = true
maxColumn=25
---
object a {
// defnSite
def method(a: Int, b: String): Boolean
// callSite
method(argument1, argument2)
}
Since v2.5.0.
Forces dangling on open/close parens around control structures (if
, while
,
for
) when line breaks must occur.
danglingParentheses.ctrlSite
danglingParentheses.ctrlSite = true
maxColumn=20
---
if (something) {
// nothing
}
if (something_else) {
// nothing
}
Since v2.5.0.
When the appropriate danglingParentheses
flag (e.g., defnSite
) has been set,
this parameter can be used to limit contexts where dangling is applied
(currently, class
, trait
and def
are supported).
danglingParentheses.exclude
continuationIndent.defnSite = 2
danglingParentheses.defnSite = true
danglingParentheses.exclude = [def]
---
def other(a: String, b: String)(c: String, d: String) = a + b + c
other(a, b)(c, d)
Since v2.5.0.
This parameter, together with its companions below, controls whether to enforce a blank line before and/or after a top-level statement spanning a certain number of lines.
This parameter will not cause any blank lines to be removed.
newlines.topLevelStatements
newlines.topLevelStatements = []
---
import org.scalafmt
package core { // no newline added here
class C1 {}
object O { // nor here
val x1 = 1
val x2 = 2
def A = "A"
def B = "B"
} // nor here
class C2 {}
}
newlines.topLevelStatements = [before]
---
import org.scalafmt
package core {
class C1 {}
object O {
val x1 = 1
val x2 = 2
def A = "A"
def B = "B"
}
class C2 {}
}
newlines.topLevelStatements = [after]
---
import org.scalafmt
package core {
class C1 {}
object O {
val x1 = 1
val x2 = 2
def A = "A"
def B = "B"
}
class C2 {}
}
newlines.topLevelStatements = [before,after]
---
import org.scalafmt
package core {
class C1 {}
object O {
val x1 = 1
val x2 = 2
def A = "A"
def B = "B"
}
class C2 {}
}
Since v2.5.0.
This parameter sets the minimum of line breaks between the first and last line
of a top-level statement (i.e., one less than the number of lines the statement
spans). For instance, newlines.topLevelStatementsMinBreaks=0
will apply to all
top-level statements, whereas 1 will require at least one line break (or a
multi-line statement).
newlines.topLevelStatementsMinBreaks
newlines.topLevelStatements = [before,after]
newlines.topLevelStatementsMinBreaks = 0
---
package core {
object O {
val x1 = 1
val x2 = 2
def A =
"A"
def B = {
"B"
}
}
}
newlines.topLevelStatements = [before,after]
newlines.topLevelStatementsMinBreaks = 2
---
import org.scalafmt
package core {
object O {
val x1 = 1
val x2 = 2
def A =
"A"
def B = {
"B"
}
}
}
Since 2.7.0
This parameter controls whether to force a new line before a multi-line body of
case/if/val
and how to format it if the space is allowed. (For multi-line
bodies of method definitions, please see
newlines.beforeMultilineDef
below.)
It accepts the same values as newlines.source
(and defaults
to that parameter's setting).
NB: for breaks before parameters of a multi-line lambda, use multiline
with
newlines.beforeCurlyLambdaParams
.
newlines.beforeMultiline = unfold
---
a match {
// had space after "=>"
case a => if (step != 0)
d.name should be("dir" + step)
// had newline after "=>"
case a =>
if (step != 0)
d.name should be("dir" + step)
}
newlines.beforeMultiline = fold
---
a match {
// had space after "=>"
case a => if (step != 0)
d.name should be("dir" + step)
// had newline after "=>"
case a =>
if (step != 0)
d.name should be("dir" + step)
}
newlines.beforeMultiline = keep
---
a match {
// had space after "=>"
case a => if (step != 0)
d.name should be("dir" + step)
// had newline after "=>"
case a =>
if (step != 0)
d.name should be("dir" + step)
}
# newlines.beforeMultiline = classic
---
a match {
// had space after "=>"
case a => if (step != 0)
d.name should be("dir" + step)
// had newline after "=>"
case a =>
if (step != 0)
d.name should be("dir" + step)
}
Since 2.7.0
This parameter applies to multi-line definitions only. It accepts the same
values as newlines.beforeMultiline
(and defaults
to that parameter's setting).
It replaced deprecated boolean newlines.alwaysBeforeMultilineDef
(with false
mapped to fold
and true
to unfold
).
newlines.beforeMultilineDef = unfold
---
// had space after "="
def foo: String = "123".map { x =>
x.toUpper
}
// had newline after "="
def foo: String =
"123".map { x =>
x.toUpper
}
newlines.beforeMultilineDef = fold
---
// had space after "="
def foo: String = "123".map { x =>
x.toUpper
}
// had newline after "="
def foo: String =
"123".map { x =>
x.toUpper
}
newlines.beforeMultilineDef = keep
---
// had space after "="
def foo: String = "123".map { x =>
x.toUpper
}
// had newline after "="
def foo: String =
"123".map { x =>
x.toUpper
}
# newlines.beforeMultilineDef = classic
---
// had space after "="
def foo: String = "123".map { x =>
x.toUpper
}
// had newline after "="
def foo: String =
"123".map { x =>
x.toUpper
}
newlines.alwaysBeforeElseAfterCurlyIf
newlines.alwaysBeforeElseAfterCurlyIf = true
---
if (someCond) {
foo()
} else {
bar()
}
newlines.alwaysBeforeElseAfterCurlyIf = false
---
if (someCond) {
foo()
}
else {
bar()
}
This parameter controls whether a newline is forced between the opening curly
brace and the parameters of a lambda or partial function. Added in 2.7.0,
replacing boolean alwaysBeforeCurlyBraceLambdaParams
.
newlines.beforeCurlyLambdaParams
newlines.beforeCurlyLambdaParams = never
---
// should keep one-line
x.map { x => s"${x._1} -> ${x._2}" }
x.map { case (c, i) => s"$c -> $i" }
// should break on arrow since case doesn't fit on a line
x.zipWithIndex.map { case (c, i) => s"$c -> $i" }
x.zipWithIndex.map { case (c, i) => s"$c -> $i (long comment)" }
newlines.beforeCurlyLambdaParams = always
---
// should break on brace, though fits on the same line
x.map { x => s"${x._1} -> ${x._2}" }
x.map { case (c, i) => s"$c -> $i" }
x.zipWithIndex.map { case (c, i) => s"$c -> $i (long comment)" }
// should break on brace and arrow as lambda doesn't fit on a line
x.zipWithIndex.map { x => s"${x._1} -> ${x._2} (long comment)" }
newlines.beforeCurlyLambdaParams = multiline
---
// should keep one-line
x.map { x => s"${x._1} -> ${x._2}" }
x.map { case (c, i) => s"$c -> $i" }
// should break on brace as lambda doesn't fit on the same line
x.zipWithIndex.map { x => s"${x._1} -> ${x._2}" }
x.zipWithIndex.map { case (c, i) => s"$c -> $i" }
// should break on brace and arrow as lambda doesn't fit on a line
x.zipWithIndex.map { x => s"${x._1} -> ${x._2} (long comment)" }
x.zipWithIndex.map { case (c, i) => s"$c -> $i (long comment)" }
newlines.beforeCurlyLambdaParams = multilineWithCaseOnly
---
// should keep one-line
x.map { x => s"${x._1} -> ${x._2}" }
x.map { case (c, i) => s"$c -> $i" }
// should break after arrow as lambda doesn't fit on the same line
x.zipWithIndex.map { x => s"${x._1} -> ${x._2}" }
x.zipWithIndex.map { x => s"${x._1} -> ${x._2} (long comment)" }
// should break on brace as lambda doesn't fit on the same line
x.zipWithIndex.map { case (c, i) => s"$c -> $i" }
// should break on brace and arrow as lambda doesn't fit on a line
x.zipWithIndex.map { case (c, i) => s"$c -> $i (long comment)" }
This parameter controls handling of newlines after the arrow following the parameters of a curly brace lambda or partial function, and whether a space can be used for one-line formatting of the entire function body (if allowed but the body doesn't fit, a break is always forced).
This parameter was renamed in 2.7.0 from afterCurlyLambda
, for clarity and
consistency with beforeCurlyLambdaParams
defined above.
newlines.afterCurlyLambdaParams
newlines.afterCurlyLambdaParams = squash
---
// remove all blank lines if any
// one-line formatting is allowed
something.map { x =>
f(x)
}
something.map { x => f(x) }
newlines.afterCurlyLambdaParams = never
---
// remove all blank lines if any
// one-line formatting depends on newlines.source:
// yes for fold; no for unfold; otherwise, only if there was no break
something.map { x =>
f(x)
}
something.map { x => f(x) }
newlines.afterCurlyLambdaParams = preserve
---
// if blank lines are present, keep only one
// one-line formatting depends on newlines.source:
// yes for fold; no for unfold; otherwise, only if there was no break
something.map { x =>
f(x)
}
something.map { x => f(x) }
newlines.afterCurlyLambdaParams = always
---
// ensure a single blank line
// one-line formatting is not allowed
something.map { x =>
f(x)
}
something.map { x => f(x) }
Since v2.5.0.
Since v3.0.0
using
soft keyword was introduced in Scala 3 and is supported in scalafmt.
The settings newlines.implicitParamListModifierPrefer
and
newlines.implicitParamListModifierForce
are from now on aliases for
newlines.usingParamListModifierPrefer
and newlines.usingParamListModifierForce
.
By picking one of them formatting will be applied at the same time to both implicit
and using
.
Besides parameter lists, using
can also be used with argument lists hence
provided rules will then also be applied to the argument lists.
Prefers newline after
implicit
. Newline will be added unless the entire implicit parameter list fits on a line, or config style is false. Newline can also be added before if the keyword itself would overflow the line.
maxColumn = 60
newlines.implicitParamListModifierPrefer = after
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
Prefers newline before
implicit
. Newline will not be added if the entire implicit parameter list fits on a line.
maxColumn = 60
newlines.implicitParamListModifierPrefer = before
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
If set, forces newline before
implicit
. Otherwise, newline can still be added if the keyword would overflow the line.
maxColumn = 60
newlines.implicitParamListModifierForce = [before]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
If set, forces newline after
implicit
. Otherwise, newline can still be added unlessbefore
is true, or the entire implicit parameter list fits on a line, or config style is false.
maxColumn = 60
newlines.implicitParamListModifierForce = [after]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
maxColumn = 60
newlines.implicitParamListModifierForce = [before,after]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
While config-style normally requires a newline after the opening parenthesis,
postponing that break until after the implicit
keyword is allowed if other
parameters require keeping this keyword attached to the opening brace.
Therefore, any of the parameters described in this section will take precedence
even when optIn.configStyleArguments = true
is used.
Since v2.5.0.
This parameter (and its companions) controls formatting around infix expressions.
The default value depends on
newlines.source
(see below).
This approach preserves line breaks in the input. This is the original
behaviour, and default for newlines.source=classic,keep
.
These approaches completely ignore existing newlines around infix, always use
a space before an infix operator and occasionally break after it. some
is
default for newlines.source=fold
, and many
for newlines.source=unfold
.
Might require increasing runner limits (
runner.optimizer.maxVisitsPerToken
, possibly evenrunner.maxStateVisits
), to avoid SearchStateExploded exceptions.
some
will introduce fewer line breaks than many
. Both will attempt to break
after
higher-precedence operators,
and both will always break before an expression enclosed in matching
parentheses.
newlines.afterInfixMaxCountPerFile
If the total number of infix operations in the entire file exceeds
newlines.afterInfixMaxCountPerFile
, the formatter automatically switches to
newlines.afterInfix=keep
for this file.
newlines.afterInfixMaxCountPerExprForSome
If newlines.afterInfix
is set to some
and the number of infix operations in
a given expression sequence (top-level or enclosed in parens/braces) exceeds
newlines.afterInfixMaxCountPerExprForSome
, the formatter switches to many
for that sequence only.
newlines.afterInfixBreakOnNested
If enabled, will force line breaks around a nested parenthesized sub-expression in a multi-line infix expression.
A list parameter (of comma-separated flags), with possible flags described
below. These flags relax formatting rules to allow occasional line overflow
(i.e., when line exceeds maxColumn
) in simple cases instead of introducing a
newline.
newlines.avoidForSimpleOverflow
Since v2.6.0.
This flag tries to avoid introducing a newline if the line would overflow even with a newline.
maxColumn = 50
danglingParentheses.callSite = false
newlines.avoidForSimpleOverflow = [tooLong]
---
object Example {
foo_bar_baz("the quick brown fox jumps over the lazy dog") {
println("")
}
foo_bar_baz("the quick brown fox jumps over a dog") {
println("")
}
}
Since v2.6.0.
This flag tries to avoid a newline if the line would overflow only because of trailing punctuation (non-alphanum symbols of length 1).
With the flag set:
maxColumn = 80
newlines.avoidForSimpleOverflow = [punct]
---
class Engine[TD, EI, PD, Q, P, A](
val dataSourceClassMap: Map[
String,
Class[_ <: BaseDataSource[TD, EI, Q, A]]]) {}
If true, newlines in definition result type will only be used if formatting
without them is impossible. This parameter was added in 2.7.0, replacing
neverInResultType
.
newlines.avoidInResultType
maxColumn = 40
newlines.avoidInResultType = true
newlines.neverBeforeJsNative = true
---
// no newlines in result type
def permissionState(a: A = js.native): js.Promise[PushPermissionState] = js.native
// no newlines in result type
val permissionState: js.Promise[PushPermissionState] = js.native
// can't format without newlines
implicit protected val td: TildeArrow {
type Out = RouteTestResult } = TildeArrow.injectIntoRoute
To enable a rewrite rule, add it to the config like this
rewrite.rules = [SortImports]
.
rewrite.rules = [AvoidInfix]
---
a success b
a error (b, c)
a map { x =>
x + 2
}
"o" % "a" % "v" c(D)
future recover {
case e: Err => 0
} map (_.toString)
rewrite.rules = [ExpandImportSelectors]
---
import a.{
b,
c
}, h.{
k, l
}
import d.e.{f, g}
import a.{
foo => bar,
zzzz => _,
_
}
Warning. This rewrite can cause non-idempotent formatting, see #1055.
rewrite.rules = [RedundantBraces]
---
def foo = {
List(1, 2, 3).sum
}
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.stringInterpolation = true
---
q"Hello ${name}"
rewrite.rules = [RedundantBraces]
---
List(1, 2, 3).map { x => x + 1 }
Entire power of RedundantBraces
can be accessed with
newlines.afterCurlyLambdaParams=squash
. It will try to squash lambda body in
one line and then replace braces with parens:
rewrite.rules = [RedundantBraces]
newlines.afterCurlyLambdaParams=squash
---
List(1, 2, 3).map { x =>
x + 1
}
List(1, 2, 3).map { x =>
println("you can't squash me!")
x + 1
}
rewrite.redundantBraces.generalExpressions
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.generalExpressions = true
---
while (x < 10) {
x += 1
}
str match {
case "a" => {
println("ok")
}
case _ => {
println("not ok")
}
}
rewrite.redundantBraces.ifElseExpressions
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.ifElseExpressions = true
---
if (a > b) {
doSomething()
} else {
doAnything()
}
rewrite.redundantBraces.methodBodies
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.methodBodies = true
---
def f() = {
1 + 1
}
rewrite.redundantBraces.includeUnitMethods
Affects only functions with explicitly specified Unit
type
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.methodBodies = true
rewrite.redundantBraces.includeUnitMethods = false
---
def f() = {
1 + 1
}
def x(): Unit = {
println("example")
}
rewrite.redundantBraces.stringInterpolation
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.stringInterpolation = true
---
s"user id is ${id}"
rewrite.redundantBraces.parensForOneLineApply
is true
by default for
edition
>= 2020-01. See also
newlines.afterCurlyLambdaParams = squash.
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.parensForOneLineApply = true
---
xs.map { x => x + 1 }
rewrite.redundantBraces.maxLines
rewrite.rules = [RedundantBraces]
rewrite.redundantBraces.maxLines = 3
---
def f() = {
collection
.map(x => x + 1)
.filter(_ < 10)
.map(_ * 2)
}
def f() = {
collection
.map(x => x + 1)
.filter(_ < 10)
.map(_ * 2)
.headOption
}
rewrite.rules = [RedundantParens]
---
for {
a <- b
if (a.nonEmpty)
} yield a
val z = (insertData *> readDatabase(id))
Modifiers are sorted based on the given order. Affects modifiers of the following definitions: trait, class, object, type, and val+var, both as fields and class parameters.
rewrite.rules = [SortModifiers]
---
final lazy private implicit val x = 42
lazy final implicit private val y = 42
rewrite.rules = [SortModifiers]
---
class Test(
implicit
final private val i1: Int,
private final val i2: String
)
rewrite.rules = [SortModifiers]
---
sealed protected[X] trait ADT
final private case object A1 extends ADT
private final case class A2(a: Int)
extends ADT
If you choose the non-default sort order then you have to specify all eight modifiers in the order you wish to see them. Hint: since some modifiers are mutually exclusive, you might want to order them next to each other.
rewrite.rules = [SortModifiers]
rewrite.sortModifiers.order = [
"implicit", "final", "sealed", "abstract",
"override", "private", "protected", "lazy"
]
---
override implicit final val x = 2
Replaces parentheses into curly braces in for comprehensions that contain multiple enumerator generators.
rewrite.rules = [PreferCurlyFors]
---
for(a <- as; b <- bs if b > 2)
yield (a, b)
The imports are sorted by the groups: symbols, lower-case, upper-case.
rewrite.rules = [SortImports]
---
import foo.{Zilch, bar, Random, sand}
The imports are sorted by their Ascii codes
rewrite.rules = [AsciiSortImports]
---
import foo.{~>, `symbol`, bar, Random}
See SIP
The rule handles how trailing commas are treated in case of a dangling closing delimiter (parenthesis or bracket for definitions or invocations, brace for import statements only).
Regardless of the setting, trailing commas are always removed if the closing delimiter is not dangling (i.e., follows the final argument without a line break).
This logic is not triggered via the
rewrite.rules
parameter, but by settingtrailingCommas
.
trailingCommas
Makes sure there are no trailing commas:
trailingCommas = never
---
import a.{
b,
c,
}
def method1(
a: Int,
b: Long,
) = {}
def method2(
a: Int,
b: Long*,
) = {}
def method3(
a: Int,
) = {}
method1(
a,
b,
)
method2(
a,
b: _*,
)
method3(
a,
)
Keeps any trailing commas:
trailingCommas = preserve
---
import a.{
b,
c,
}
def method1(
a: Int,
b: Long,
) = {}
def method2(
a: Int,
b: Long*
) = {}
def method3(
a: Int,
) = {}
method1(
a,
b
)
method2(
a,
b: _*,
)
method3(
a,
)
Makes sure there are trailing commas:
trailingCommas = always
---
import a.{
b,
c
}
def method1(
a: Int,
b: Long
) = {}
def method2(
a: Int,
b: Long*
) = {}
def method3(
a: Int
) = {}
method1(
a,
b
)
method2(
a,
b: _*
)
method3(
a
)
Since v2.5.0.
Makes sure there are trailing commas for multiple-argument expressions only, except when the last argument is repeated:
trailingCommas = multiple
---
import a.{
b,
c
}
def method1(
a: Int,
b: Long
) = {}
def method2(
a: Int,
b: Long*,
) = {}
def method3(
a: Int,
) = {}
method1(
a,
b
)
method2(
a,
b: _*,
)
method3(
a,
)
Since: v1.6.0.
If enabled this formats methods such that parameters are on their own line
indented by continuationIndent.defnSite
.
Separation between parameter groups are indented by two spaces less than
continuationIndent.defnSite
. The return type is on its own line at the end.
This formatting is only triggered if the method definition exceeds the maxColumn value in width or if the number of arguments to the method exceeds the
verticalMultiline.arityThreshold
.
verticalMultiline.arityThreshold
verticalMultiline.atDefnSite = true
verticalMultiline.arityThreshold = 2
---
case class Foo(x: String)
case class Bar(x: String, y: String)
object A {
def foo(x: String, y: String)
def hello(how: String)(are: String)(you: String) = how + are + you
}
verticalMultiline.newlineAfterOpenParen
continuationIndent.defnSite = 2
verticalMultiline.atDefnSite = true
verticalMultiline.arityThreshold = 2
verticalMultiline.newlineAfterOpenParen = true
---
def other(a: String, b: String)(c: String, d: String) = a + b + c
This parameter has been deprecated, please use danglingParentheses.exclude. Keep in mind, though, that the new parameter is empty by default while the old one isn't, so to use empty exclude list, one must set the old
verticalMultiline.excludeDanglingParens=[]
.
verticalMultiline.excludeDanglingParens
continuationIndent.defnSite = 2
verticalMultiline.excludeDanglingParens = [def]
verticalMultiline.atDefnSite = true
verticalMultiline.arityThreshold = 2
verticalMultiline.newlineAfterOpenParen = true
---
def other(a: String, b: String)(c: String, d: String) = a + b + c
other(a, b)(c, d)
Also see the general section on implicit parameter lists.
maxColumn = 60
verticalMultiline.atDefnSite = true
newlines.implicitParamListModifierForce = [before]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
maxColumn = 60
verticalMultiline.atDefnSite = true
newlines.implicitParamListModifierForce = [after]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
maxColumn = 60
verticalMultiline.atDefnSite = true
newlines.implicitParamListModifierForce = [before,after]
---
def format(code: String, age: Int)(implicit ev: Parser, c: Context): String
Since v2.6.0.
Allows wrapping comments exceeding maxColumn
.
comments.wrap
A standalone comment is one which is surrounded by line breaks.
maxColumn = 20
comments.wrap = standalone
---
/* long multiline comment */
// long singleline comment
val a = 1 // short
val b = 2 // long singleline comment
A trailing comment is one which is followed by a line break.
maxColumn = 20
comments.wrap = trailing
---
/* long multiline comment */
// long singleline comment
val a = 1 // short
val b = 2 // long singleline comment
Since v2.6.0.
This parameter allows formatting a standalone single-line comment (i.e., //
)
to be wrapped using the same type, not a multi-line comment (/* ... */
).
comments.wrapStandaloneSlcAsSlc
maxColumn = 20
comments.wrap = trailing
comments.wrapStandaloneSlcAsSlc = true
---
// long singleline comment
val b = 2 // long singleline comment
Since v2.6.0.
docstrings.style
Prohibits formatting of docstrings. All other docstrings
parameters are
ignored.
docstrings.style = Preserve
---
/** do not touch
* this style
* keep the text as-is
*/
This variant used to be called JavaDoc
.
docstrings.style = Asterisk
---
/** Skip first line, format intermediate lines with an asterisk
* below the first asterisk of the first line (aka JavaDoc)
*/
This variant used to be called ScalaDoc
.
docstrings.style = SpaceAsterisk
---
/** Format intermediate lines with a space and an asterisk,
* both below the two asterisks of the first line
*/
docstrings.style = AsteriskSpace
---
/** Format intermediate lines with an asterisk and a space,
* both below the two asterisks of the first line
*/
Since v2.6.0. Ignored for
docstrings.style = Preserve
.
docstrings.oneline
docstrings.style = Asterisk
docstrings.oneline = fold
---
/** Scaladoc oneline */
/**
* Scaladoc multiline
*/
val a = 1
docstrings.style = Asterisk
docstrings.oneline = unfold
---
/** Scaladoc oneline */
/**
* Scaladoc multiline
*/
val a = 1
docstrings.style = Asterisk
docstrings.oneline = keep
---
/** Scaladoc oneline */
/**
* Scaladoc multiline
*/
val a = 1
Will parse scaladoc comments and reformat them.
This functionality is generally limited to standard scaladoc elements and might lead to undesirable results in corner cases; for instance, the scaladoc parser doesn't have proper support of embedded HTML.
However, tables are supported.
Since v2.6.0. Ignored for
docstrings.style = Preserve
.
docstrings.wrap
docstrings.wrap = yes
maxColumn = 30
---
/**
* @param d the Double to square, meaning multiply by itself
* @return the result of squaring d
*
* Thus
* - if [[d]] represents a negative value:
* a. the result will be positive
* a. the value will be {{{d * d}}}
* a. it will be the same as for `-d`
* - however, if [[d]] is positive
* - the value will still be {{{d * d}}}
* - i.e., the same as {{{(-d) * (-d)}}}
*
* In other words:
* {{{
* res = d * d
* = (-d) * (-d) }}}
*/
def pow2(d: Double): Double
Controls whether to force the first line to be blank in a multiline docstring.
Keep in mind that some combinations of parameters are prohibited (e.g.,
blankFirstLine=keep
contradicts with style=Asterisk
).
Since v2.7.5. Ignored for
docstrings.style = Preserve
ordocstrings.wrap = no
.
docstrings.blankFirstLine
# do not force a blank first line
docstrings.blankFirstLine = no
docstrings.style = SpaceAsterisk
maxColumn = 30
---
/** Scaladoc oneline */
/** Scaladoc multiline1
*/
/**
* Scaladoc multiline2
*/
val a = 1
# force a blank first line
docstrings.blankFirstLine = yes
docstrings.style = SpaceAsterisk
maxColumn = 30
---
/** Scaladoc oneline */
/** Scaladoc multiline1
*/
/**
* Scaladoc multiline2
*/
val a = 1
# preserve a blank first line
docstrings.blankFirstLine = keep
docstrings.style = SpaceAsterisk
maxColumn = 30
---
/** Scaladoc oneline */
/** Scaladoc multiline1
*/
/**
* Scaladoc multiline2
*/
val a = 1
There is a possibility to override scalafmt config for a specific code with
// scalafmt: {}
comment:
---
// scalafmt: { align.preset = most, danglingParentheses.preset = false }
libraryDependencies ++= Seq(
"org.scalameta" %% "scalameta" % scalametaV,
"org.scalacheck" %% "scalacheck" % scalacheckV)
// scalafmt: { align.preset = some, danglingParentheses.preset = true } (back to defaults)
libraryDependencies ++= Seq(
"org.scalameta" %% "scalameta" % scalametaV,
"org.scalacheck" %% "scalacheck" % scalacheckV)
Disable formatting for specific regions of code by wrapping them in
// format: off
blocks:
---
// format: off
val identity = Array(1, 0, 0,
0, 1, 0,
0, 0, 1)
// format: on
Configure which source files should be formatted in this project.
# Only format files tracked by git.
project.git = true
# manually exclude files to format.
project.excludeFilters = [
regex1
regex2
]
# manually include files to format.
project.includeFilters = [
regex1
regex2
]
Since v2.5.0.
Allows specifying an additional subset of parameters for each file matching a PathMatcher pattern. For instance,
align.preset = none
fileOverride {
"glob:**/*.sbt" {
align.preset = most
}
"glob:**/src/test/scala/**/*.scala" {
maxColumn = 120
binPack.unsafeCallSite = true
}
}
uses align.preset=none
for all files except .sbt
for which
align.preset=most
will apply. It will also use different parameters for test
suites.
This parameter does not modify which files are formatted.
spaces.beforeContextBoundColon
spaces.beforeContextBoundColon=Never
---
def method[A: Bound]: B
def method[A : Bound]: B
def method[A: Bound: Bound2]: B
spaces.beforeContextBoundColon=Always
---
def method[A: Bound]: B
def method[A : Bound]: B
def method[A: Bound: Bound2]: B
spaces.beforeContextBoundColon=IfMultipleBounds
---
def method[A: Bound]: B
def method[A : Bound]: B
def method[A: Bound: Bound2]: B
spaces.inImportCurlyBraces
spaces.inImportCurlyBraces=true
---
import a.b.{c, d}
spaces.inParentheses
spaces.inParentheses=true
---
foo(a, b)
spaces.neverAroundInfixTypes
spaces.neverAroundInfixTypes=["##"]
---
def f: Foo##Repr
def g: Foo\/Repr
// usage same operator not as type
def e = a##b
spaces.afterKeywordBeforeParen
spaces.afterKeywordBeforeParen = false
---
if (a) println("HELLO!")
while (a) println("HELLO!")
spaces.inByNameTypes
spaces.inByNameTypes = false
---
def foo(a: => A): A
spaces.afterSymbolicDefs
spaces.afterSymbolicDefs=true
---
def +++(a: A): F[A]
Since v2.5.0.
Scalafmt allows flexible configuration of Integer and Floating Point literals formatting.
Default formatting:
---
123l
0XFff
0x1Abl
10E-1
10e-1D
Each literals.*
setting has three available options: Upper
, Lower
,
Unchanged
.
literals.long
Responsible for the case of Long
literals suffix L
literals.long=Upper
---
123l
literals.float
Responsible for the case of Float
literals suffix F
literals.float=Lower
---
42.0F
literals.double
Responsible for the case of Double
literals suffix D
literals.double=Lower
---
42.0d
literals.hexPrefix
Responsible for the case of hex integer literals prefix 0x
literals.hexPrefix=Lower
---
0X123
literals.hexDigits
Responsible for the case of hex integer literals digits
literals.hexDigits=Lower
literals.long=Upper
---
0xaAaA
0xaAaAl
literals.scientific
Responsible for the case of Double
literals exponent part
literals.scientific=Upper
literals.float=Lower
---
10e-1
10e-1f
Controls formatting of Scala embedded within XML.
Since v2.6.0.
If set, formats embedded Scala relative to containing XML, making the assumption that XML itself is properly formatted. Otherwise, formatting is relative to the outer Scala code which contains the XML literals.
xmlLiterals.assumeFormatted
maxColumn = 40
xmlLiterals.assumeFormatted = true
---
object Example2 {
def apply() = {
<foo>
<bar>{ (1 + 2 + 3).toString("some long format") }</bar>
</foo>
}
}
maxColumn = 40
xmlLiterals.assumeFormatted = false
---
object Example2 {
def apply() = {
<foo>
<bar>{ (1 + 2 + 3).toString("some long format") }</bar>
</foo>
}
}
binPack.literalArgumentLists
binPack.literalArgumentLists = true
---
val secret: List[Bit] = List(0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1,
0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1)
binPack.literalArgumentLists = false
---
val secret: List[Bit] = List(0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1)
binPack.literalArgumentLists = true
binPack.literalsSingleLine = true
---
val secret: List[Bit] = List(0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1,
0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1)
See also:
binPack.literalsIncludeSimpleExpr
(to allow a few select methods followed by a few nested single-argument apply calls, with literals as arguments); added in v2.5.0- all other
binPack.literalXXX
parameters (see list at the bottom) are self-explanatory.
Parent constructors are C
and D
in class A extends B with C and D
. Changed
from a boolean to a wider set of options in v2.6.0.
binPack.parentConstructors
Keep in mind that explicitly specifying the default value might change behaviour; other parameters, such as
newlines.source
, could interpret implied default differently but yield to an explicit value.
binPack.parentConstructors = Always
maxColumn = 30
---
object A {
trait Foo
extends Bar
with Baz
}
binPack.parentConstructors = Never
maxColumn = 30
---
object A {
trait Foo extends Bar with Baz
}
binPack.parentConstructors = Oneline
maxColumn = 30
---
object A {
class Foo(a: Int)
extends Bar
with Baz
class Foo(
a: Int
)
extends Bar
with Baz
}
binPack.parentConstructors = OnelineIfPrimaryOneline
maxColumn = 30
---
object A {
class Foo(a: Int, b: Int)
extends Bar
with Baz
class Foo(
a: Int,
b: Int
) extends Bar with Baz
}
The parameters below control formatting of select chains when
newlines.source = classic
, and specifically which select expressions are
included in a chain.
Generally, a chain can either be formatted on one line up to the last select, or will have a break on the first select.
Controls if select followed by curly braces can start a chain.
includeCurlyBraceInSelectChains
includeCurlyBraceInSelectChains = true
---
List(1).map { x =>
x + 2
}
.filter(_ > 2)
includeCurlyBraceInSelectChains = false
---
List(1)
.map { x =>
x + 2
}
.filter(_ > 2)
Controls if select not followed by an apply can start a chain.
includeNoParensInSelectChains
includeNoParensInSelectChains = true
---
List(1).toIterator.buffered
.map(_ + 2)
.filter(_ > 2)
includeNoParensInSelectChains = false
---
List(1).toIterator.buffered.map(_ + 2).filter(_ > 2)
Keeps the break on the first select of the chain if the source contained one. Has no effect if there was no newline in the source.
optIn.breakChainOnFirstMethodDot
optIn.breakChainOnFirstMethodDot = false
---
// collapse into a single line
foo
.map(_ + 1)
.filter(_ > 2)
optIn.breakChainOnFirstMethodDot = true
---
// preserve break on first dot and break on subsequent dots
foo
.map(_ + 1).filter(_ > 2)
Controls whether to preserve a newline before each subsequent select when the very first one used a line break; that is, this parameter doesn't prohibit single-line formatting even if there are source breaks down the chain.
If false, each subsequent select within the chain will behave exactly like the first, that is, either the entire chain will be formatted on one line, or will contain a break on every select.
If true, preserves existence or lack of breaks on subsequent selects if the first select was formatted with a newline.
optIn.breaksInsideChains
optIn.breaksInsideChains = true
maxColumn = 35
---
foo.bar(_ + 1)
.baz(_ > 2).qux
foo.bar(_ + 1).baz(_ > 2).qux
foo.bar(_ + 1).baz(_ > 2).qux(_ * 12)
foo.bar(_ + 1).baz(_ > 2).qux { _ * 12 }
foo.bar(_ + 1)
.baz(_ > 2).qux(_ * 12)
optIn.breaksInsideChains = false
maxColumn = 35
---
foo.bar(_ + 1)
.baz(_ > 2).qux
foo.bar(_ + 1).baz(_ > 2).qux
foo.bar(_ + 1).baz(_ > 2).qux(_ * 12)
foo.bar(_ + 1).baz(_ > 2).qux { _ * 12 }
foo.bar(_ + 1)
.baz(_ > 2).qux(_ * 12)
Controls what happens if a chain enclosed in parentheses is followed by additional selects. Those additional selects will be considered part of the enclosed chain if and only if this flag is false.
Since 2.6.2.
optIn.encloseClassicChains
optIn.encloseClassicChains = true
maxColumn = 30
---
(foo.map(_ + 1).map(_ + 1))
.filter(_ > 2)
optIn.encloseClassicChains = false
maxColumn = 30
---
(foo.map(_ + 1).map(_ + 1))
.filter(_ > 2)
Scalafmt has basic support for Scala 3 features that can be enabled by changing the dialect of the Scalafmt parser.
runner.dialect = Scala3
---
open class MyOpenClass()
val myQuote = '{ expr }
val mySplice = ${ expr }
enum class Weekday {
case Monday, Tuesday, Wednesday, Thursday, Friday
}
If true, always insert a blank line before docstrings;
If false, preserves blank line only if one exists before.
optIn.forceBlankLineBeforeDocstring
optIn.forceBlankLineBeforeDocstring = true
---
object Stuff {
/** Some function */
def hello = ()
}
optIn.forceBlankLineBeforeDocstring = false
---
object Stuff {
/** Some function */
def hello = ()
}
Map of tokens to rewrite. For example, Map("⇒" -> "=>") will rewrite unicode arrows to regular ascii arrows.
rewriteTokens
rewriteTokens = {
"⇒": "=>"
"→": "->"
"←": "<-"
}
---
val tuple = "a" → 1
val lambda = (x: Int) ⇒ x + 1
for {
a ← Option(1)
b ← Option(2)
} yield a + b
Removed in 2.7.0
Editions are no longer used. They were kept for backwards compatibility with old
configuration files but new changes to the default Scalafmt formatting behavior
will not respect the edition
setting.
To find all available configuration options, it's best to browse the source code
of Scalafmt. A good place to start is ScalafmtConfig
. Observe that this
listing below is the top-level, there are more configuration options if you
visited nested fields like spaces
and newlines
.