Skip to content
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

ScalafmtConfig: move importSelectors to binPack #4683

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
(Prior to v3.8.4, it was called `importSelectors`.)

```scala mdoc:defaults
importSelectors
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
Loading