id | title |
---|---|
installation |
Installation |
You can use Scalafmt from your editor, build tool or terminal.
The Scala plugin compatible with recent versions of IntelliJ IDEA has built-in support for Scalafmt (see Note below). DO NOT install the deprecated Scalafmt plugin unless you have an older version of Intellij.
When opening a
project that contains a .scalafmt.conf
file, you will be
prompted to use it:
Choose the scalafmt formatter and IntelliJ's Reformat Code
action will then
use Scalafmt when formatting files. See below for shortcuts.
Note: IntelliJ 2019.1 or later is required in order for the Scala plugin
to support Scalafmt and the dynamic version
set in your .scalafmt.conf
. If
you must use an older version, see the FAQ for an alternative.
- Opt + Cmd + L (macOS)
- Ctrl + Alt + L (other)
To re-configure the shortcut:
- Open
Preferences > Keymap
- Search for "Reformat Code"
Scalafmt is primarily designed to operate on entire text files—formatting selected ranges of code may produce undesirable results. For this reason, IntelliJ uses its own formatter for ranges by default. It is not recommended to change this, and is instead recommended to format files when saving.
- for the current project (recommended):
Preferences > Editor > Code Style > Scala
- for all new projects:
File > Other Settings > Preferences for New Projects… > Editor > Code Style > Scala
To reset the formatter to IntelliJ for an existing project that uses the Scalafmt formatter:
- Open
Preferences > Editor > Code Style > Scala
- Switch "Formatter" value to "IntelliJ"
It is not possible to reset this setting for all existing projects.
You can use the Metals language server to format code with Scalafmt in VS Code. For more details, refer to the Metals documentation.
You can use the Metals language server to format code with Scalafmt in Vim and NeoVim. For more details, refer to the Metals documentation.
You can use the Metals language server to format code with Scalafmt in Emacs. For more details, refer to the Metals documentation.
The externally maintained format-all extension to Emacs also supports scalafmt as one of its formatters.
You can use the Metals language server to format code with Scalafmt in Sublime Text. For more details, refer to the Metals documentation.
You can use the Metals language server to format code with Scalafmt in Eclipse. For more details, refer to the Metals documentation.
Metals automatically uses Scalafmt to respond
to formatting requests from the editor, according to the configuration defined
in .scalafmt.conf
.
In most editors, if you there is no .scalafmt.conf
, upon receiving the first
format request Metals will create the .scalafmt.conf
file for you.
You can find more information on triggering a format request for individual editors in their respective parts of the Metals site.
NB: keep in mind that versions of scalafmt-core
and sbt-scalafmt
are released
independently and don't have to align. The version of scalafmt-core
is defined
in the .scalafmt.conf
configuration file and downloaded dynamically.
// In project/plugins.sbt. Note, does not support sbt 0.13, only sbt 1.x.
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0") // "2.4.0" is just sbt plugin version
To configure the scalafmt version add the following line into .scalafmt.conf
:
version = @STABLE_VERSION@
The latest version will be used by default.
myproject/scalafmt
: Format main sources ofmyproject
projectmyproject/test:scalafmt
: Format test sources ofmyproject
projectscalafmtCheck
: Check if the scala sources under the project have been formatted.scalafmtSbt
: Format*.sbt
andproject/*.scala
files.scalafmtSbtCheck
: Check if the files have been formatted byscalafmtSbt
.scalafmtOnly
: Format a single given file.scalafmtAll
: Execute the scalafmt task for all configurations in which it is enabled. (By default this means the Compile and Test configurations.) (available as of v2.0.0-RC5)scalafmtCheckAll
: Execute the scalafmtCheck task for all configurations in which it is enabled. (By default this means the Compile and Test configurations.) (available as of v2.0.0-RC5)
scalafmtConfig: File
: The location of the.scalafmt.conf
configuration file. Defaults to the.scalafmt.conf
file at the root of the project.
scalafmtOnCompile: Boolean
: Defines if the sbt-scalafmt should run scalafmt on compile. Defaultfalse
.
⚠️ This option is discouraged since it messes up undo buffers in the editor and it slows down compilation. It is recommended to use "format on save" in the editor instead.
The sbt plugin is enabled by default for the Test and Compile configurations.
Use scalafmtConfigSettings
to enable the plugin for integration tests and then
use it:scalafmt
to format.
inConfig(IntegrationTest)(org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings)
To share configuration across different sbt builds, create a custom sbt plugin
that generates .scalafmt-common.conf
on build reload, then include the
generated file from .scalafmt.conf
// project/MyScalafmtPlugin.scala
import sbt._
object MyScalafmtPlugin extends AutoPlugin {
override def trigger = allRequirements
override def requires = plugins.JvmPlugin
override def buildSettings: Seq[Def.Setting[_]] = {
SettingKey[Unit]("scalafmtGenerateConfig") :=
IO.write(
// writes to file once when build is loaded
file(".scalafmt-common.conf"),
"maxColumn = 100".stripMargin.getBytes("UTF-8")
)
}
}
// .scalafmt.conf
include ".scalafmt-common.conf"
You can limit formatting parallelism for projects with multiple subprojects in your build.sbt
:
import org.scalafmt.sbt.ConcurrentRestrictionTags
Global / concurrentRestrictions += Tags.limit(org.scalafmt.sbt.ConcurrentRestrictionTags.Scalafmt, 4)
The recommended way to install the scalafmt command line tool is with Coursier.
If you're using a recent version of coursier
which supports direct
installation
of packages, the simplest approach is by running
cs install scalafmt
scalafmt --version # should be @STABLE_VERSION@
Alternatively, you can create a complete standalone executable with:
coursier bootstrap org.scalameta:scalafmt-cli_2.13:@STABLE_VERSION@ \
-r sonatype:snapshots --main org.scalafmt.cli.Cli \
--standalone \
-o scalafmt
./scalafmt --version # should be @STABLE_VERSION@
Finally, you can choose to obtain a slim 15 KiB bootstrap script instead with:
coursier bootstrap org.scalameta:scalafmt-cli_2.13:@STABLE_VERSION@ \
-r sonatype:snapshots --main org.scalafmt.cli.Cli \
-o scalafmt
./scalafmt --version # should be @STABLE_VERSION@
If a version
is defined in .scalafmt.conf
, the CLI binary will honor it
by automatically resolving and downloading the corresponding artifacts if it
does not match its own version. Otherwise, it is recommended to put this
bootstrap script in your code repository to make sure everyone on your team,
as well as CI, uses the same scalafmt version.
To configure which files to format, see project.
To customize the JVM options, use the Coursier option --java-opt
, more info
with
coursier bootstrap --help | grep -A 1 "\-\-java-opt"
Our CI publishes a pre-release version of scalafmt to Sonatype Snapshots on every merge into master. To use a pre-release, replace @STABLE_VERSION@ with the version here:
If you use coursier to install a pre-release, be sure to include the flag
-r sonatype:snapshots
so that the artifact can be resolved.
If you use sbt to install a pre-release, be sure to add the following setting:
resolvers += Resolver.sonatypeRepo("snapshots")
For macOS and Linux, it's possible to download pre-built GraalVm native binaries with instant startup and fast performance for short-lived Scalafmt runs.
VERSION=@STABLE_VERSION@
INSTALL_LOCATION=/usr/local/bin/scalafmt-native
curl https://raw.githubusercontent.com/scalameta/scalafmt/master/bin/install-scalafmt-native.sh | \
bash -s -- $VERSION $INSTALL_LOCATION
scalafmt-native --help # should show version @STABLE_VERSION@
The native image binaries have the limitation of working only with one version of Scalafmt. The native binaries fail when the
version
setting in.scalafmt.conf
does not match the version of the native binary. It's recommended to use the JVM binary if you expect to use Scalafmt in multiple projects with different Scalafmt versions.
Please see issue #1569 if you'd like to contribute support for building native images for Windows!
Nailgun is recommended if you want to integrate scalafmt with a text editor like vim/Emacs/Atom/Sublime/VS Code.
- Make sure you have a nailgun client installed. For example with
brew install nailgun
. - Create a standalone executable in
/usr/local/bin/scalafmt_ng
with (sudo if necessary)
coursier bootstrap --standalone org.scalameta:scalafmt-cli_2.13:@STABLE_VERSION@ \
-r sonatype:snapshots -f --main com.martiansoftware.nailgun.NGServer \
-o /usr/local/bin/scalafmt_ng
scalafmt_ng & // start nailgun in background
ng ng-alias scalafmt org.scalafmt.cli.Cli
ng scalafmt --version # should be @STABLE_VERSION@
Nailgun keeps scalafmt running on a local server to avoid the JVM startup penalty and also so scalafmt can benefit from JIT. This makes scalafmt up to 10x faster when formatting a single file from the CLI. The downside to Nailgun is that the setup is complicated and the long-running server needs to be restarted once in awhile.
The recommended way to install the scalafmt command line tool is with Coursier, itself available via Homebrew.
brew install coursier/formulas/coursier
coursier install scalafmt
scalafmt --version // should be @STABLE_VERSION@
If necessary, make sure to follow the Coursier instructions for updating
$PATH
so that the scalafmt
binary becomes available in your terminal.
You can install scalafmt for Arch Linux from AUR. There is the scalafmt-native-bin package that installs scalafmt binary built with GraalVM. GraalVM native binary provides instant startup without Nailgun.
yaourt -S scalafmt-native-bin
scalafmt --version // should be @STABLE_VERSION@
println(website.plaintext(org.scalafmt.cli.CliArgParser.buildInfo))
println(website.plaintext(org.scalafmt.cli.CliArgParser.scoptParser.usage))
It is possible to use scalafmt in gradle with the following externally maintained plugins:
It is possible to use scalafmt in Maven with the following externally maintained plugin:
Mill have scalafmt support built-in:
Use the scalafmt-dynamic
module to integrate with Scalafmt.
libraryDependencies += "org.scalameta" %% "scalafmt-dynamic" % "@STABLE_VERSION@"
First, create an instance of Scalafmt
and get paths for the file to format
along with it's configuration file.
import java.nio.file._
import org.scalafmt.interfaces.Scalafmt
val scalafmt = Scalafmt.create(this.getClass.getClassLoader)
val config = Paths.get(".scalafmt.conf")
val file = Paths.get("Main.scala")
Use the format
method to format a string with the given config and filename.
println(scalafmt.format(config, file, "object A { }"))
Stable public APIs:
org.scalafmt.interfaces
(recommended): pure Java APIs with no external dependencies. Can be loaded via thescalafmt-dynamic
module.org.scalafmt.Scalafmt
(discouraged): old public API that is stable and will remain stable but has several limitations.- no support for
version
in.scalafmt.conf
- does not respect
project.excludeFilters
in.scalafmt.conf
- doesn't automatically handle
*.sbt
and*.sc
files - no caching of
.scalafmt.conf
- no support for
Internal APIs that are subject to binary breaking changes in any release:
org.scalafmt.dynamic
: private implementation ofscalafmt-interfaces
. These classes can be used via the static methodorg.scalafmt.interfaces.Scalafmt.create(ClassLoader)
.org.scalafmt.config
: case classes for.scalafmt.conf
configuration that that are only intended for internal usage.org.scalafmt.cli
: private implementation of the command-line interface.
It's possible to format *.sbt
and *.sc
files.
println(scalafmt.format(config, Paths.get("build.sbt"), "lazy val x = project"))
println(scalafmt.format(config, Paths.get("build.sc"), "def main( ) = println()"))
The scalafmt
instance automatically picks the correct parser depending on the
provided filename.
By default, the scalafmt
instance automatically downloads the Scalafmt version
declared in .scalafmt.conf
. If the version
setting is not declared, the
original file contents are returned unchanged and an error is reported with
instructions how to fix the problem.
Use withRespectVersion(false)
to fall back to a default Scalafmt version when
its not declared in .scalafmt.conf
. Use withDefaultVersion(version)
to
customize the fallback version.
val scalafmtThatDoesntRequireVersionSetting = scalafmt
.withRespectVersion(false)
.withDefaultVersion("@STABLE_VERSION@")
By default, Scalafmt errors are reported to System.err
. Extend
org.scalafmt.interfaces.ScalafmtReporter
to customize error reporting to
handle parse and config errors.
Here is an example how to extend ScalafmtReporter
.
Use withReporter(reporter)
to pass in your custom reporter.
import java.io._
import org.scalafmt.dynamic._
val myOut = new ByteArrayOutputStream()
val myReporter = new ConsoleScalafmtReporter(new PrintStream(myOut))
val customReporterScalafmt = scalafmt.withReporter(myReporter)
By default, scalafmt
only formats files that match the
project.{excludeFilters,includeFilters}
settings in .scalafmt.conf
. Use
withRespectExcludeFilters(false)
to disable this behavior.
val scalafmtThatIgnoresProjectSettings = scalafmt.withRespectProjectFilters(false)
Use the clear()
method to clear up resources of the scalafmt
instance.
scalafmt.clear()
It's possible to call Scalafmt from Java without depending directly on Scala libraries.
First, depend on the scalafmt-interfaces
module, which is a pure Java library
with no external dependencies.
<dependency>
<groupId>org.scalameta</groupId>
<artifactId>scalafmt-interfaces</artifactId>
<version>@STABLE_VERSION@</version>
</dependency>
Next, obtain a classloader with the scalafmt-dynamic_2.12
classpath.
import java.net.URLClassLoader;
// this package contains only Java APIs.
import org.scalafmt.interfaces.*;
// ClassLoader that shares only org.scalafmt.interfaces from this classloader.
ClassLoader sharedParent = new ScalafmtClassLoader(this.getClass.getClassLoader)
// Jars to org.scalameta:scalafmt-dynamic_2.12:@STABLE_VERSION@ classpath. Obtain
// these from your build tool or programmatically with ivy/coursier.
URL[] jars = // ...
ClassLoader scalafmtDynamic = new URLClassLoader(jars, sharedParent)
Finally, create an instance of Scalafmt
with the scalafmt-dynamic
classloader.
Scalafmt scalafmt = Scalafmt.create(scalafmtDynamic)
String formatted = scalafmt.format(config, file, "object A { }")