Avoid redundant allocations (#620)
Summary:
- Optimizes work with
PsiElement: no directtextaccess where appropriate as it’s relatively expensive- Some early returns to avoid String copying when it is not necessary
- Around 6-7% performance improvements on my machine on sequential
kotlinx.coroutinesruns (5 -> 4.65 sec in sequantial mode)Partially addresses https://github.com/facebook/ktfmt/issues/619
Pull Request resolved: https://github.com/facebook/ktfmt/pull/620
Reviewed By: cortinico
Differential Revision: D107013190
Pulled By: hick209
fbshipit-source-id: 8a420697a5d5bbe708e46d016c0042b9d2fd3a71
ktfmt

ktfmtis a program that pretty-prints (formats) Kotlin code, based on google-java-format.The minimum supported runtime version is JDK 11, released September 2018.
Demo
ktfmtFor comparison, the same code formatted by
ktlintand IntelliJ:ktlintPlayground
We have a live playground where you can easily see how ktfmt would format your code. Give it a try! https://facebook.github.io/ktfmt/
Using the formatter
IntelliJ, Android Studio, and other JetBrains IDEs
A ktfmt IntelliJ plugin is available from the plugin repository. To install it:
PluginscategoryMarketplacetabktfmtpluginThe plugin will be disabled by default. To enable it in the current project, go to
File → Settings... → ktfmt Settings(orIntelliJ IDEA → Preferences... → Editor → ktfmt Settingson macOS) and check theEnable ktfmtcheckbox. A notification will be presented when you first open a project offering to do this for you.To enable it by default in new projects, use
File → New Project Settings → Preferences for new Projects → Editor → ktfmt Settings.When enabled, it will replace the normal
Reformat Codeaction, which can be triggered from theCodemenu or with the Ctrl-Alt-L (by default) keyboard shortcut.To configure IntelliJ to approximate ktfmt’s formatting rules during code editing, you can edit your project’s
.editorconfigfile to include the Kotlin section from one of the files insidedocs/editorconfig.Share IntelliJ ktfmt settings
In order to share the settings, make sure to commit the file
.idea/ktfmt.xmlinto your codebase.Installation
Homebrew
If you’re a Homebrew user, you can install ktfmt via:
from the command-line
Download the formatter and run it with:
--kotlinlang-stylemakesktfmtuse a block indent of 4 spaces instead of 2. See below for details.--enable-editorconfigmakesktfmtenable limited support to override the style’s configuration based on the following subset of editorconfig properties:max_line_lengthindent_sizeor
tab_widthifindent_size = tabij_continuation_indent_sizektfmt_trailing_comma_management_strategynone,only_addorcompletewill override the trailing comma management strategy
Preserving Lambda Line Breaks
By default,
ktfmtrespects user-authored line breaks inside lambda bodies. This is useful for DSLs where nesting carries semantic meaning (Jetpack Compose UI hierarchies, Kotlin Gradle scripts, etc.) without ktfmt prescribing a specific outcome.A lambda body whose source spans multiple lines stays multi-line; one that fits on a single line stays single-line if written that way. For example, the following is left as-is:
Note: There is no configurability as to the formatter’s algorithm for formatting (apart from the different styles or limited
.editorconfigsupport). This is a deliberate design decision to unify our code formatting on a single format.using Gradle
A Gradle plugin (ktfmt-gradle) is available on the Gradle Plugin Portal. To set it up, just follow the instructions in the How-to-use section.
Alternatively, you can use Spotless with the ktfmt Gradle plugin.
using Maven
Consider using Spotless with the ktfmt Maven plugin.
using pre-commit hooks
A pre-commit hook is implemented in language-formatters-pre-commit-hooks
FAQ
ktfmtvsktlintvs IntelliJktfmtuses google-java-format’s underlying engine, and as such, many items on google-java-format’s FAQ apply toktfmtas well.In particular, here are the principles that we try to adhere to:
ktfmtignores most existing formatting. It respects existing newlines in some places, but in general, its output is deterministic and is independent of the input code.ktfmtexposes no configuration options that govern formatting behavior. See https://github.com/google/google-java-format/wiki/FAQ#i-just-need-to-configure-it-a-bit-differently-how for the rationale.style, we aim to make sure that those are easily shared across your organization/codebase to avoid bikeshedding discussions about code format.These two properties make
ktfmta good fit in large Kotlin code bases, where consistency is very important.We created
ktfmtbecause at the timektlintand IntelliJ sometimes failed to produce nice-looking code that fits in 100 columns, as can be seen in the Demo section.ktfmtuses a 2-space indent; why not 4? any way to change that?Two reasons -
However, we do offer an alternative style for projects that absolutely cannot make the move to
ktfmtbecause of 2-space: the style--kotlinlang-stylechanges block indents to 4-space.Alternatively, the
ktfmtcommand-line supports a limited subset of.editorconfigproperties; see above.Developer’s Guide
Setup
Open the
build.gradle.ktsat the root of the repo in IntelliJ. Choose “Open as a Project”.Development
FormatterTest.kt.Building on the Command Line
./gradlew :ktfmt:shadowJarjava -jar core/build/libs/ktfmt-<VERSION>-with-dependencies.jarReleasing
See RELEASING.md.
License
Apache License 2.0