Help Provide Feedback: Vote Up Kotlin Formatter Issues relevant to you

@yole is right without feedback how can we complain that issues don’t get addressed in a timely manner. The other side of the coin is that there are a lot of issues and just going through them is a major time investment.

I have struggled between wanting to help with feedback to existing issues and not having the time to go through the 1800+ issues, even to vote on ones I find important. It is a catch 22 situation.

This is my attempt to help with providing feedback to the Kotlin team on existing issues and at the same time to make this feedback more time efficient for users.

The issues here are taken from KT-2440 Formatter issue which is the parent issue for all formatter related bugs and feature requests.

I extracted a summary from the issue and placed it here for convenience. If you find the summary relevant to your needs, please follow the issue link and vote the issue up. If there is an issue that is missing please open it on YouTrack and add a comment with a link to it here.

Kotlin YouTrack Formatter Issues

 

KT-16032 Kotlin code formatter merges comment line with non-comment line

enum class TestFormatter {  
    FOO, // I am a comment  
    BAR, // I am also a comment  
}

becomes

enum class TestFormatter {  
    FOO, // I am a comment BAR, // I am also a comment  
}

 

 

KT-15980 Inconsistency when formatting enums with comments

enum class E1 {
    A,     // A
    B,     // B   
}

enum class E2 {
    A,     // A
    B      // B
}

Gets reformatted to

enum class E1 {
    A, // A
    B, // B
}

enum class E2 {
    A, // A B  // B
}

 

 

KT-15504 Add code style options to limit number of blank lines

To parallel the corresponding Java options.

@vladimir_schneider, My minimum needs would be addressed with:

  • absolute max blank lines in code to limit blank lines anywhere in the file
  • max blank lines before }

 

 

KT-15099 Odd code formatting when chaining lambdas and splitting lines on operators

When chaining operators in RxJava I constantly find myself coming across this annoying code formatting. Is this a bug, or is this intended?

// This code ends up indenting unexpectedly:
fun test() {
    Single.just(Object())
            .map {
                it
            }.map {
        it // The code unexpectedly shifts to the left
    }
}

// This code indents as expected:
fun test() {
    Single.just(Object())
            .map {
                it
            }
            .map {
                it // The code is indented as expected
            }
}

 

 

KT-14950 Code Style: Wrapping and Braces / “Local variable annotations” setting could be supported

Seems that there is no options for local variable annotation in Settings / … / Code Style / Kotlin / Wrapping and Braces.
When the annotation is inserted by a quick fix, it always occupies separate line:

...
@SuppressSomething("name")
val local = 33;
... 

I’d like to have it on the same line:

...
@SuppressSomething("name") val local = 33;
... 

So a setting could be introduced.
NB: for Java it is provided. See Settings / … / Code Style / Java / Wrapping and Braces / Local variable annotations.
NB: if I put the annotation on the same line manually, then reformatting does not change this. It’s Ok. If a setting is introduced, then both auto-formatting, and re-formatting by command should obey it.

 

 

KT-14902 Formatter: Vertically aligning call on new line in case of assignment

Code:

fun foo() {
    val foobar = "ABCDEFGH"
            .toUpperCase()
}

The call to toUpperCase() should be aligned to the receiver, not the lhs of the assignment.

 

 

KT-14601 Formatter inserts unnecessary indent before ‘else’

fun test(b: Boolean) {
    if (b) {
    }<caret>
    else if (!b) {
    }
}

Press Enter.
Expected result:

fun test(b: Boolean) {
    if (b) {
    }
    <caret>
    else if (!b) {
    }
}

Actual result:

fun test(b: Boolean) {
    if (b) {
    }
        <caret>
    else if (!b) {
    }
}

 

 

KT-14362 ‘else’ part indentation in if-expression formatting

if-expression is now formatted like this:

fun abs(x: Int) = if (x > 0) x
else -x

That doesn’t look good because of hanging ‘else’, with indentation of the top-level statement or declaration (which it isn’t).
This leads to a code like:

fun abs(x: Int) =
        if (x > 0) x
        else -x

that is mostly Ok, but could be a less preferable option due to one extra line and precious vertical space.
I’d expect ‘else’ part to be indented as ‘if’ part in the cases like the original one:

fun abs(x: Int) = if (x > 0) x
                  else -x

 

 

KT-14165 Strange formatting effects in presence of ‘?: <expression>’

Original code with formatting

        val newDescriptor = oldDescriptor.newCopyBuilder()
                .setValueParameters(unsubstitutedValueParameters)
                .build()

Now add ?: … :

        val newDescriptor = oldDescriptor.newCopyBuilder()
                .setValueParameters(unsubstitutedValueParameters)
                .build()
                            ?: throw AssertionError("Incorrect substitution while building a replacement for local function $oldDescriptor")

Now reformat everything with Ctrl+Alt+L:

        val newDescriptor = oldDescriptor.newCopyBuilder()
                                    .setValueParameters(unsubstitutedValueParameters)
                                    .build()
                            ?: throw AssertionError("Incorrect substitution while building a replacement for local function $oldDescriptor")

Neither looks satisfactory to me, still, the overall behavior is rather strange.

 

 

KT-14126 Code style wrapping options for enum constants

Kotlin code formatter puts all enum constants in a single line:

enum class A {
    ENUM_OPTION_A, ENUM_OPTION_B, ENUM_OPTION_C, ENUM_OPTION_D
}

While it might be readable for simple enums with just a few constants with relatively short names, it looks quite messy when there are more constants or enum has constructor.

enum class A(val i: Int) {
    ENUM_OPTION_A(1500), ENUM_OPTION_B(2900), ENUM_OPTION_C(42), ENUM_OPTION_D(-1)
}

I’d like to have a similar option as in Java code style - selecting between Do not wrap/Wrap if long/Chop down if long/Do not wrap.

enum class A {
    ENUM_OPTION_A, 
    ENUM_OPTION_B, 
    ENUM_OPTION_C, 
    ENUM_OPTION_D,
}

 

 

KT-14083 Formatting of where clasuses

Hi! There are two problems with formatting of where clauses.

  1. They are not indented when applied to the class
  2. The bounds themselves are not aligned

Here is an example of bad formatting:

abstract class RustNavigationContributorBase<T> protected constructor(
    private val indexKey: StubIndexKey<String, T>,
    private val clazz: Class<T>
) : ChooseByNameContributor, GotoClassContributor
where T : NavigationItem,
T : RustNamedElement { 
    ...    
}

fun <T> foo()
    where T : NavigationItem,
T : RustNamedElement {
}

Here is how it ought be formatted imo:

abstract class RustNavigationContributorBase<T> protected constructor(
    private val indexKey: StubIndexKey<String, T>,
    private val clazz: Class<T>
) : ChooseByNameContributor, GotoClassContributor
    where T : NavigationItem,
          T : RustNamedElement {
}

fun <T> foo()
    where T : NavigationItem,
          T : RustNamedElement {
}

 

 

KT-14066 Comments on when branches are misplaced

Current formatting:

when (2 + 2) {
// comment
    5 -> print("Radiohead")
}

Desired formatting:

when (2 + 2) {
    // comment
    5 -> print("Radiohead")
}

 

 

KT-13980 Accessors are not autoindented on typing

Type:

class C {
    val x: Int
    <caret>
}

Try to specify a getter for the property. Regardless of whether you accept a completion suggestion or simply type “get”, the accessor is not indented. At least accepting the completion variant should add an indent; better yet, indent after “get(” has been typed.

 

 

KT-13979 Incorrect caret position after pressing Enter after top-level annotation

Type in the end of a file:

@Target(AnnotationTarget.PROPERTY)

Press Enter at EOL. Expected indent: 0, actual indent: 8.

 

 

KT-13099 formatting in angle brackets ignored and not fixed

the formatter will not remove them, or add them where they belong.
(see below, where i tried inserting spaces everywhere i could)

foo.bar           <kotlin       .      .    Array     <Any>>()

 

 

KT-12980 Code Style / Wrapping and Braces / Binary expressions: standard wrapping options could be supported

Settings / … / Code Style / Kotlin / Wrapping and Braces / Binary expressions: there is no typical choice like “Do not wrap”, “Wrap if long”, “Chop down if long”, etc. Could be provided, like for Java.

If does matter, met this case when creating Kotlin Android activities. Java code like:

View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | 
View.SYSTEM_UI_FLAG_LAYOUT_STABLE   

can be wrapped, while Kotlin:

View.SYSTEM_UI_FLAG_LOW_PROFILE or View.SYSTEM_UI_FLAG_FULLSCREEN or 
View.SYSTEM_UI_FLAG_LAYOUT_STABLE   

cannot.
Studio 145.3001415 (2.2 preview 4) + Kotlin plugin 1.0.3-Studio2.2-14.
IDEA 163.905 + Kotlin plugin 1.1.0-dev-1545.

 

 

KT-12862 Formatting: Weird wrapping setting for long ?: operator

Reformat this:

val result = declarationDomain.mapTupleArguments(actualType, helper, SwiftSubstitutor.EMPTY, false) ?: throw GenericResolver.InferenceFail()

Expected:

val result = declarationDomain.mapTupleArguments(actualType, helper, SwiftSubstitutor.EMPTY, false) ?: 
             throw GenericResolver.InferenceFail()

Actual:

val result = declarationDomain.mapTupleArguments(actualType, helper, SwiftSubstitutor.EMPTY, 
                                                 false) ?: throw GenericResolver.InferenceFail()

 

 

KT-12491 Code Style (Formatter): consider support of “Simple in one line” settings

There are formatting options: Settings / … / Code Style / Java / Wrapping and Braces / Simple X in one line. (X are blocks, methods, lambdas, classes.)

There are no such settings for Kotlin. Could it be reasonable to provide them? On one hand, if a function has one statement body, it can be written in single expression form: fun x() = 0 In this case the setting is not necessary.

However, this form is not supported for some elements like constructors and init blocks. Also, I don’t completely realize how to manage single statement lambda formatting: what if one user likes them in one line, and another - in several lines. So maybe these settings still could have sense in Kotlin.

 

 

KT-12490 Formatter inserts empty line between constructors without bodies in presence of comment

Dummy Kotlin:

class Ctors(p: Boolean) {
    // Comment.
    constructor(p: Int) : this(p == 0)
    constructor(p: String) : this(p.isEmpty())
} 

Reformat (Ctrl+Alt+L): the empty line is inserted between constructors. AFAIU, this is not desirable (KT-12175).
Undo, remove the comment, format again: now no empty line, Ok.

 

 

KT-12176 Formatter could reformat long primary constructors

class A(delegate: MethodVisitor, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {

}

// I'd prefer something like, but it's probably too resetrictive
class A(
        delegate: MethodVisitor,
        access: Int,
        name: String,
        desc: String,
        signature: String?,
        exceptions: Array<out String>?
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {

}

Comment:

I’m not sure that aligning to ( is the best choice. If A is something like AbstracBarrelProxyFactory , this will waste a large amount of white space. I personally prefer a single indent here:

class MissingToolchainNotificationProvider(
    private val project: Project,
    private val notifications: EditorNotifications
) : EditorNotifications.Provider<EditorNotificationPanel>() {
    ...
}

 

 

KT-12123 Formatter: always indent after newline in variable initialization

fun test() {
    val x = <caret>
    println()
}

Press Enter. Expected behavior:

fun test() {
    val x =
            <caret>
    println()
}

Actual behavior:

fun test() {
    val x =
    <caret>
    println()
}

Note that the expression on the next line is important here, everything works fine without it or if it’s replaced by (for example) another val declaration.

 

 

KT-11518 Auto-formatter breaks comments on when entries

Suppose we have

fun foo(arg: Any?) {
    when (arg) {
        // 1
        is String -> println("1")
        // 2
        else -> println("2")
    }
}

then we make auto-formatting (CTRL+ALT+L) and get the following instead:

fun foo(arg: Any?) {
    when (arg) {
    // 1
        is String -> println("1")
    // 2
        else -> println("2")
    }
}

Looks like a bug, isn’t it?

 

 

KT-11231 Bad new line behaviour in lambda when “Method call arguments” multiline alignment is enabled

fun some(f: () -> Unit, s: String) {}
fun test() {
    some({
        val test = 1<caret> // Hit Enter
        val more = 1
    }, "hello")
}

// SET_TRUE: ALIGN_MULTILINE_PARAMETERS_IN_CALLS

Result:

fun some(f: () -> Unit, s: String) {}
fun test() {
    some({
        val test = 1
             <caret>
        val more = 1
    }, "hello")
}

 

 

KT-10591 Zero auto-indent inside function body with unindented comment right before function

This is tested with default code style settings, i.e. indent is > 0 (currently = 4).
Provide dummy Kotlin code, | is the caret:

class CommentContainer {
//  fun previous() {} // No line break after.
    fun point() {|}
} 

Effect 1: press Enter, get the following:

class CommentContainer {
//  fun previous() {}
    fun point() {
|}
} 

The closing brace is not indented.
Effect 2: select the whole function code via Expand Selection (Ctrl+W), but not the comment.
Format the selection: it is unindented to the 0 position.
Comparing to “analogous” Java code:

  1. In Java the effect 1 does not occur, the indent is correct.
  2. In Java the same effect occurs. But while in Java two methods on the next lines are “bad style”, in Kotlin they are quite probable.

(Or not? There are no “Blank Lines” settings in Kotlin code style.)

 

 

KT-10030 Figure out indentation for ‘if’ expressions

          val existingList = if (commitMessage == changeList?.getName()) 
            PerforceNumberNameSynchronizer.getInstance(project).getAnyNumber(connection.getConnectionKey(), commitMessage) 
          else null

The second line should probably be indented relative to ‘if’, not relative to the beginning of the line.

 

 

KT-9818 Code style for method expression bodies

The original example now is indented with 4 spaces, which looks good:

class Spam {
    private fun transmognificator(): List<Char> =
        "92".toArrayList().reversed().filter { it.isLetter() }
}

However indentation is off for get() = :

class Spam {
    private val transmognificator: List<Char> get() =
    "92".toArrayList().reversed().filter { it.isLetter() }
}

 

 

KT-9562 Wrong indent after Enter after an annotation

In an empty file type

@Aaaa

and press Enter. The caret is indented 8 characters to the right.

 

 

KT-9423 Code style: increase options to match other languages

When working in Java, PHP etc the code styling preferences are extremely configurable.
Yet, for Kotlin, it seems many of the same preferences (such as spaces within method parentheses ) are mysteriously absent. Is it possible to add them and match the code style preferences available for Java?

 

 

KT-9220 Provide ‘align when multiline’ formatter feature for chained method calls

Java code looks awesome when chained methods aligned by ‘dot’ symbol. We need same for Kotlin

 

 

KT-8363 Detect file indent + Kotlin: doc comment affects auto-detection, project reopening required

Not sure, is this code style issue or Kotlin issue, it’s specific for both, please check.
Settings / … / Code Style / Detect and use existing file indent = Yes (default value).
Settings / … / Code Style / both Java and Kotlin : make the same Tab and Indents settings.
Mine are: Use tab character = No, Tab size = 4, Indent = 4, Continuation indent = 8.
Provide Java and Kotlin files with similar content:
SampleJava.java

package pack;

/**
 * Created by ache on 02/07/15.
 */
public class SampleJava {
} 

SampleKotlin.kt

package pack

/**
 * Created by ache on 02/07/15.
 */
public class SampleKotlin {
} 

In every file put the caret after opening brace { . Press Enter.
In Java indent of 4 spaces is inserted: correct.
In Kotlin indent of 1 space is inserted ( problem 1 ) and warning about this appears in the file caption. Why?
Don’t accept any suggestion, undo changes. Close and reopen the file.
Erase the doc comment. Repeat the same: get the same warning. It’s problem 2 : the comment is erased, where does it get a space?
Don’t accept any suggestion, undo changes. Close and reopen the whole project.
Repeat the same: now 4 spaces are inserted. Finally correct.

 

 

KT-7718 Auto-formatting behaves incorrectly on super keyword

In the code like

class Base(val prop: Int)

class Derived: Base {
    constructor(arg: Int):
            super(arg)
}

auto-formatter tries to align “super” by “constructor” border, like the following

class Base(val prop: Int)

class Derived: Base {
    constructor(arg: Int):
    super(arg)
}

 

 

KT-6752 Code Style: Split parameter “put left brace on new line” for in-method structures and classes/traits/functions, properties

Please split parameter “put left brace on new line” for in-method structures (if, when, closure, SAM, etc) and classes, traits, enums, functions, and properties.
So we can use different settings, like:

fun foo()
{
  if (true) {
    // something
  }
}

class A
{
  fun B()
  {
    for (i in 1..10) {
      println(i)
    }
  }

  val c: Boolean
    get() {
      return true
    }
}

 

 

KT-6155 Strange block comment formatting on overriding method before

open class A() {
    open fun foo(value : Int) : Unit = println(value)
    open val bar : Int = 0
}

class C : A() {
    val constant = 42
    // Some comment
    <caret>
    /*
        Some another comment
    */
    fun someAnotherFunction() {

    }
}
open class A() {
    open fun foo(value : Int) : Unit = println(value)
    open val bar : Int = 0
}

class C : A() {
    val constant = 42
    // Some comment
    override val bar: Int = <caret>0<!--</span-->selection>
    override fun equals(other: Any?): Boolean {
        return super<A>.equals(other)
    }

    override fun foo(value: Int) {
        super<A>.foo(value)
    }

    override fun hashCode(): Int {
        return super<A>.hashCode()
    }

    override fun toString(): String {
        return super<A>.toString()
    }

    /*
            Some another comment
        */
    fun someAnotherFunction() {

    }
}

 

 

KT-5790 Wrong indent after opening lambda bracket when it is not first in line

        run(
                /* :) */ {<caret>
                }
        )

Press enter and get:

        run(
                /* :) */ {
            <caret>
                }
        )

Expected:

        run(
                /* :) */ {
                    <caret>
                }
        )

 

 

KT-4949 Add align if-else property to formatter

Expected behavior:

fun test() {
    return if (true)
               "hello"
           else
               "other"
}

 

 

KT-4001 Allow to set arguments indent to 1 tab (currently two and not customized)

Current style:

someFunction(
        arg1,
        arg2
)

But I want:

someFunction(
    arg1,
    arg2
)

Please allow customize this option.

 

4 Likes