Skip to content

Commit

Permalink
ScalafmtConfig: move importSelectors to binPack
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed Dec 26, 2024
1 parent f6db6ec commit 14588dd
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 64 deletions.
60 changes: 26 additions & 34 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ The preset itself is defined as:
defnSite = false
}
docstrings.style = Asterisk
importSelectors = binPack
indent.callSite = 4
newlines {
avoidInResultType = true
Expand Down Expand Up @@ -5299,22 +5298,44 @@ the selection of breaks, such as when dealing with multiline arguments
If set explicitly, will be used for type arguments or parameters,
instead of the respective [`binPack.xxxSite`](#binpackxxxsite).

### binpacking of `importSelectors`
### `binPack.importSelectors`

Import selectors (those grouped in `{...}`) will always be formatted on a single
line if they fit without exceeding `maxColumn`. This parameter controls how they
will be handled _if_ they overflow.

```scala mdoc:defaults
importSelectors
# called `importSelectors` prior to v3.8.4
binPack.importSelectors
```

Takes the following parameters:

- `noBinPack`: format one per line
- `binPack`: binpack, with as many as would fit on each line
- `unfold`: format one per line (prior to v3.8.4, called `noBinPack`)
- `fold`: fit as many as possible on each line (prior to v3.8.4, called `binPack`)
- `singleLine`: format all on one line

```scala mdoc:scalafmt
maxColumn = 10
binPack.importSelectors = unfold
---
import a.b.{c, d, e, f, g}
```

```scala mdoc:scalafmt
maxColumn = 10
binPack.importSelectors = fold
---
import a.b.{c, d, e, f, g}
```

```scala mdoc:scalafmt
maxColumn = 10
binPack.importSelectors = singleLine
---
import a.b.{c, d, e, f, g}
```

## Classic select chains

The parameters below control formatting of select chains when
Expand Down Expand Up @@ -5488,35 +5509,6 @@ is set and `git` parameter
is configured, then default value will be changed to `windows` if
`autocrlf=true`, and `preserve` if `false`.

### `importSelectors`

This parameter controls formatting of imports.

```scala mdoc:defaults
importSelectors
```

```scala mdoc:scalafmt
maxColumn = 10
importSelectors = noBinPack
---
import a.b.{c, d, e, f, g}
```

```scala mdoc:scalafmt
maxColumn = 10
importSelectors = binPack
---
import a.b.{c, d, e, f, g}
```

```scala mdoc:scalafmt
maxColumn = 10
importSelectors = singleLine
---
import a.b.{c, d, e, f, g}
```

## Markdown Formatting

> Since v3.0.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import metaconfig._
* Parent constructors are C and D in "class A extends B with C and D". If
* "Always", scalafmt will fit as many parent constructors on a single line.
* If "Never", each parent constructor gets its own line.
* @param importSelectors
* Controls formatting of import selectors with multiple names from the same
* package (default is currently `unfold`)
* - If `fold`, arranged to fit within the maximum line width
* - If `unfold`, broken to one per line
* - If `singleLine`, kept on a single line
*/
case class BinPack(
@annotation.ExtraName("unsafeCallSite")
Expand All @@ -42,6 +48,7 @@ case class BinPack(
literalsMinArgCount: Int = 5,
literalsInclude: Seq[String] = Seq(".*"),
literalsExclude: Seq[String] = Seq("String", "Term.Name"),
importSelectors: ImportSelectors = ImportSelectors.unfold,
) {
def literalsRegex: FilterMatcher =
FilterMatcher(literalsInclude, literalsExclude)
Expand Down Expand Up @@ -79,10 +86,18 @@ object BinPack {
.deriveSurface[BinPack]
implicit lazy val encoder: ConfEncoder[BinPack] = generic.deriveEncoder

def ctor(site: Site, parents: ParentCtors): BinPack =
BinPack(defnSite = site, callSite = site, parentConstructors = parents)

val never = BinPack.ctor(Site.Never, ParentCtors.Never)
def ctor(
site: Site,
parents: ParentCtors,
imports: ImportSelectors = ImportSelectors.fold,
): BinPack = BinPack(
defnSite = site,
callSite = site,
parentConstructors = parents,
importSelectors = imports,
)

val never = BinPack.ctor(Site.Never, ParentCtors.Never, ImportSelectors.unfold)
val always = BinPack.ctor(Site.Always, ParentCtors.Always)
private val oneline = BinPack.ctor(Site.Oneline, ParentCtors.Oneline)
private val onelineSjs = BinPack.ctor(Site.OnelineSjs, ParentCtors.Oneline)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import metaconfig._
/** ADT representing import selectors settings, specifically pertaining to the
* handling when multiple names are imported from the same package.
*
* When [[org.scalafmt.config.ImportSelectors.noBinPack]] is selected, imports
* are organized such that each line contains a single name imported from the
* base package:
* When [[org.scalafmt.config.ImportSelectors.unfold]] is selected, imports are
* organized such that each line contains a single name imported from the base
* package:
* {{{
* // max columns |
* import org.{
Expand All @@ -19,9 +19,9 @@ import metaconfig._
* }
* }}}
*
* When [[org.scalafmt.config.ImportSelectors.binPack]] is selected, imports
* are organized such that each line contains as many names as will fit within
* the column limit:
* When [[org.scalafmt.config.ImportSelectors.fold]] is selected, imports are
* organized such that each line contains as many names as will fit within the
* column limit:
* {{{
* // max columns |
* import org.{
Expand All @@ -43,13 +43,15 @@ sealed abstract class ImportSelectors
object ImportSelectors {

implicit val codec: ConfCodecEx[ImportSelectors] = ReaderUtil
.oneOfCustom[ImportSelectors](noBinPack, binPack, singleLine) {
case Conf.Bool(true) => Configured.ok(ImportSelectors.binPack)
case Conf.Bool(false) => Configured.ok(ImportSelectors.noBinPack)
.oneOfCustom[ImportSelectors](unfold, fold, singleLine) {
case Conf.Bool(value) => Configured
.ok(if (value) ImportSelectors.fold else ImportSelectors.unfold)
case Conf.Str("binPack") => Configured.ok(ImportSelectors.fold)
case Conf.Str("noBinPack") => Configured.ok(ImportSelectors.unfold)
}

case object noBinPack extends ImportSelectors
case object binPack extends ImportSelectors
case object fold extends ImportSelectors
case object unfold extends ImportSelectors
case object singleLine extends ImportSelectors

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@ import metaconfig._
* longerArg3
* )
* }}}
* @param importSelectors
* Controls formatting of import selectors with multiple names from the same
* package
* - If [[org.scalafmt.config.ImportSelectors.binPack]], import selectors are
* arranged to fit within the maximum line width
* - If [[org.scalafmt.config.ImportSelectors.noBinPack]], import selectors
* are broken to one per line
* - If [[org.scalafmt.config.ImportSelectors.singleLine]], import selectors
* are kept on a single line The default setting is currently `noBinPack`.
* @param lineEndings
* - If [[LineEndings.unix]], output will include only unix line endings
* - If [[LineEndings.windows]], output will include only windows line
Expand Down Expand Up @@ -97,6 +88,8 @@ import metaconfig._
@annotation.SectionRename("verticalAlignMultilineOperators", "indent.infix.assignmentOnly") // v3.8.4
@annotation.SectionRename("indentYieldKeyword", "indent.yieldKeyword") // v3.8.4
@annotation.SectionRename("rewriteTokens", "rewrite.tokens") // v3.8.4
@annotation.SectionRename("importSelectors", "binPack.importSelectors") // v3.8.4
@annotation.SectionRename("binPackImportSelectors", "binPack.importSelectors") // v3.8.4
// scalafmt: { maxColumn = 80 }
case class ScalafmtConfig(
version: String = org.scalafmt.Versions.stable,
Expand All @@ -114,8 +107,6 @@ case class ScalafmtConfig(
rewrite: RewriteSettings = RewriteSettings.default,
newlines: Newlines = Newlines(),
runner: ScalafmtRunner = ScalafmtRunner.default,
@annotation.ExtraName("binPackImportSelectors")
importSelectors: ImportSelectors = ImportSelectors.noBinPack,
includeCurlyBraceInSelectChains: Boolean = true,
includeNoParensInSelectChains: Boolean = false,
assumeStandardLibraryStripMargin: Boolean = false,
Expand Down Expand Up @@ -281,7 +272,6 @@ case class ScalafmtConfig(
binPack = BinPack.always,
danglingParentheses = DanglingParentheses(false, false),
indent = Indents(callSite = 4, defnSite = 4),
importSelectors = ImportSelectors.binPack,
newlines = newlines.copy(
avoidInResultType = true,
neverBeforeJsNative = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,18 +139,18 @@ class Router(formatOps: FormatOps) {
val beforeClose = prev(close)
val policy = SingleLineBlock(
close,
okSLC = style.importSelectors eq ImportSelectors.singleLine,
okSLC = style.binPack.importSelectors eq ImportSelectors.singleLine,
)
val newlineBeforeClosingCurly = decideNewlinesOnlyBeforeClose(close)

val mustDangleForTrailingCommas =
getMustDangleForTrailingCommas(beforeClose)
val mustUseNL = hasBreak() && isRightCommentThenBreak(ft)
val newlinePolicy = style.importSelectors match {
val newlinePolicy = style.binPack.importSelectors match {
case ImportSelectors.singleLine if mustUseNL => policy
case ImportSelectors.singleLine if !mustDangleForTrailingCommas =>
NoPolicy
case ImportSelectors.binPack => newlineBeforeClosingCurly
case ImportSelectors.fold => newlineBeforeClosingCurly
case _ => newlineBeforeClosingCurly &
splitOneArgOneLine(close, leftOwner)
}
Expand Down

0 comments on commit 14588dd

Please sign in to comment.