Skip to content

Mapping of flags which affect indentation

Andrey Shcheglov edited this page Aug 1, 2022 · 23 revisions

Continuation indent

The mapping between IDEA and diKTat flags

Context Default value (diKTat) Default value (IDEA) diKTat IntelliJ IDEA[1] .editorconfig

Supertype (extends/implements) list

???, see #1404

false

???

CONTINUATION_INDENT_IN_SUPERTYPE_LISTS

ij_kotlin_continuation_indent_in_supertype_lists

Function declaration parameters

false[2]

false[3]

extendedIndentOfParameters

CONTINUATION_INDENT_IN_PARAMETER_LISTS

ij_kotlin_continuation_indent_in_parameter_lists

true

alignedParameters

ALIGN_MULTILINE_PARAMETERS

ij_kotlin_align_multiline_parameters

Function call arguments

false

extendedIndentOfParameters

CONTINUATION_INDENT_IN_ARGUMENT_LISTS

ij_kotlin_continuation_indent_in_argument_lists

false

N/A[4]

ALIGN_MULTILINE_PARAMETERS_IN_CALLS

ij_kotlin_align_multiline_parameters_in_calls

Chained function calls

false

extendedIndentBeforeDot

CONTINUATION_INDENT_FOR_CHAINED_CALLS

ij_kotlin_continuation_indent_for_chained_calls

Conditions (particularly, if() statements and while() loops)

true, but see #1351

false[5]

extendedIndentAfterOperators (almost)

CONTINUATION_INDENT_IN_IF_CONDITIONS

ij_kotlin_continuation_indent_in_if_conditions

Expression body functions

false

extendedIndentForExpressionBodies

CONTINUATION_INDENT_FOR_EXPRESSION_BODIES

ij_kotlin_continuation_indent_for_expression_bodies

Expressions (such as 1 + 2 or true && false, except for the predicates of if- and while-statements)

true

extendedIndentAfterOperators

N/A[6]

Elvis (?:) expressions

false

N/A[4]

CONTINUATION_INDENT_IN_ELVIS

ij_kotlin_continuation_indent_in_elvis

Function declaration parameters

There are actually three IDEA flags which control the continuation indent in function declarations:

  • CONTINUATION_INDENT_IN_PARAMETER_LISTS, false by default,

  • ALIGN_MULTILINE_PARAMETERS, true by default, and

  • METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE, true by default.

These flags interact as follows:

  • METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE is true (the default), forced newline after the opening parenthesis:

    fun functionWithArguments(
        arg0: Int,
        arg1: Int,
        arg2: Int) = Unit

    Formal parameters are indented according to the value of CONTINUATION_INDENT_IN_PARAMETER_LISTS and aligned; the actual value of ALIGN_MULTILINE_PARAMETERS has no effect. Equivalent diKTat configuration:

    - name: WRONG_INDENTATION
      configuration:
        extendedIndentOfParameters: any (the desired value)
        alignedParameters: any (has no effect)
  • METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE is false (no newline after the opening parenthesis), ALIGN_MULTILINE_PARAMETERS is true (the default):

    fun functionWithArguments(arg0: Int,
                              arg1: Int,
                              arg2: Int) = Unit

    In this case, the value of CONTINUATION_INDENT_IN_PARAMETER_LISTS has no effect at all. Equivalent diKTat configuration:

    - name: WRONG_INDENTATION
      configuration:
        extendedIndentOfParameters: any (has no effect)
        alignedParameters: true
  • METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE is false (no newline after the opening parenthesis), ALIGN_MULTILINE_PARAMETERS is false:

    fun functionWithArguments(arg0: Int,
        arg1: Int,
        arg2: Int) = Unit

    Formal parameters, except for the 1st one, are indented according to the value of CONTINUATION_INDENT_IN_PARAMETER_LISTS. Equivalent diKTat configuration:

    - name: WRONG_INDENTATION
      configuration:
        extendedIndentOfParameters: any (the desired value)
        alignedParameters: false

Conditions

Expressions in conditions

When within a predicate of an if- or a while-statement, IDEA ignores the default (non-configurable) continuation indent (8 spaces) which is normally used for expressions, and instead takes into account the value of CONTINUATION_INDENT_IN_IF_CONDITIONS.

Depending on the value of CONTINUATION_INDENT_IN_IF_CONDITIONS flag, IDEA may format long multi-line predicates either like this (continuation indent is on):

fun f() {
    if (true ||
            false ||
            true) {
        // block body
    }

    if (1 +
            2 +
            3 +
            4 == 10) {
        // block body
    }

    while (true ||
            false ||
            true) {
        // block body
    }

    do {
        // block body
    } while (true ||
            false ||
            true)
}

or like this (continuation indent is off, Kotlin Style Guide-recommended setting):

fun f() {
    if (true ||
        false ||
        true) {
        // block body
    }

    if (1 +
        2 +
        3 +
        4 == 10) {
        // block body
    }

    while (true ||
        false ||
        true) {
        // block body
    }

    do {
        // block body
    } while (true ||
        false ||
        true)
}

The above implies the below is a correctly formatted code fragment, too (continuation indent is off):

fun f() {
    if (
        true)
        return
}

If we set CONTINUATION_INDENT_IN_IF_CONDITIONS on:

fun f() {
    if (
            true)
        return
}

 — then no compatible diKTat configuration will exist (the value of extendedIndentAfterOperators will make no difference here).

Chained function calls in conditions

IDEA uses the values of both CONTINUATION_INDENT_IN_IF_CONDITIONS and CONTINUATION_INDENT_FOR_CHAINED_CALLS to calculate the indent of chained calls in conditions. Both flags are off (the default):

fun f() {
    if (""
            .isBlank()) {
        return
    }
}

Both flags are on:

fun f() {
    if (""
                    .isBlank()) {
        return
    }
}

Expressions

IDEA always uses the continuation indent for multi-line expressions, and this can’t be configured (unless the user changes the value of CONTINUATION_INDENT_SIZE or ij_continuation_indent_size):

(true ||
        false ||
        true ||
        false ||
        (true ||
                false) ||
        "".isEmpty())



(1 +
        2 +
        3 +
        4)

(1 to
        2 to
        3)

in and !in operators

val a: Boolean = (42
        in 1..100)

val b: Boolean = (42
        !in 1..100)

is and !is operators

        val a: Boolean = (""
                is String)

        val b: Boolean = (""
                !is String)

Cast operators (as and as?)

val a = 42 as
        Integer

val b = 42
        as Integer

val c = 42 as?
        Integer

val d = 42
        as? Integer

val e = "" as
        String

val f = ""
        as String

val g = "" as?
        String

val h = ""
        as? String

More examples

The argument of a when-expression:

when (true ||
        false) {
    true -> Unit
    else -> Unit
}

The branch condition of a when-expression:

when ("".isEmpty()) {
    (true ||
            false) -> Unit
    else -> Unit
}

Infix function calls in a for-loop:

for (i in 6 downTo
        0 step
        2) {
    return
}

Operator function calls in a for-loop:

for (i in 1..
        42) {
    return
}

Function call arguments:

fun f(): Int {
    return g(1 +
            2)
}

Expressions wrapped immediately after the opening parenthesis. Note the continuation indent, even though CONTINUATION_INDENT_FOR_EXPRESSION_BODIES may be false:

val v1 = (
        true)

val v2 = (
        1 + 2)

1. Under .idea/codeStyles/Project.xml.
2. Not applicable if alignedParameters is true and there’s no newline after the opening parenthesis.
3. Not applicable if ALIGN_MULTILINE_PARAMETERS is true and METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE is false at the same time.
4. Not configurable in diKTat.
5. In IDEA, the indent induced by the if()-statement per se cancels any indent caused by the predicate expression being wrapped.
6. Not configurable in IDEA.