Hi! I've updated a project from `1.2.1` to `1.7.1`...
# ktlint
m
Hi! I've updated a project from
1.2.1
to
1.7.1
, and the gradle plugin to the latest version. I enabled
max_line_length
which was previously disabled for .kt files. Unfortunately Ktlint has started wrapping some expressions in a way I really don't like, in order to fit within the line length. This and similar expression are being formatted like this:
Copy code
//BEFORE
val actual = runBlocking { alternativeDatesListingExperiment.sanitizeResponse(subQueryResult, subQuerySanitizer, mockSubListingDetails, getNonPropertyCardStrippingContext(egGraphQLContext, searchParameters = searchParameters)) }

//AFTER
val actual =
    runBlocking {
        alternativeDatesListingExperiment.sanitizeResponse(
            subQueryResult,
            subQuerySanitizer,
            mockSubListingDetails,
            getNonPropertyCardStrippingContext(egGraphQLContext, searchParameters = searchParameters)
        )
    }
No matter how I tweak the wrapping rules, it stubbornly wraps the expression on the next line after the assignment. What I'd like is this:
Copy code
val actual = runBlocking {
    ...
}
I've read the rules documentation thoroughly more than once, and I can't find a reason why it's wrapping the expression like this. Is there something I'm missing or is it impossible to configure Ktlint in such a way? Thanks. Attaching my editor config for reference.
b
big version jumps like that are always hard to manage... I recommend you disable all the new rules to begin with, get the upgrade in, and then re-enable the rules you really want, one by one, adjusting the configs to suit your needs.
m
Thanks, already tried to disable the rules but it didn't work.
I mean: in that case it won't format any code to honor the max_line_length
Another incomprehensible behavior to me is that this line is being formatted like this:
Copy code
//BEFORE
private val carSearchResponseAdapter = CarSearchResponseAdapter(carsPricingAdapter, carSaveTripAdapter, mockLoyaltyMapper, carsOfferCardFeatureConfig, configUtil, carsPriceDisplayUtils)
//AFTER
private val carSearchResponseAdapter =
    CarSearchResponseAdapter(carsPricingAdapter, carSaveTripAdapter, mockLoyaltyMapper, carsOfferCardFeatureConfig, configUtil, carsPriceDisplayUtils)
while this other:
Copy code
//BEFORE
val response: PropertySearchResponse = carSearchResponseAdapter.adaptToPropertySearchResponse(egtpSearchOfferResponse, primarySearch, secondarySearch, searchParameters, egGraphQLContext, setOf(), false, listOf(), context)
//AFTER
val response: PropertySearchResponse = carSearchResponseAdapter.adaptToPropertySearchResponse(
    egtpSearchOfferResponse,
    primarySearch,
    secondarySearch,
    searchParameters,
    egGraphQLContext,
    setOf(),
    false,
    listOf(),
    context
)
this is ridiculous: the same configuration yields two different results, the latter being my desired one
p
The answer can be found mosy easily with the ktlint CLI:
Copy code
$ ktlint-1.7.0 **/Foo.kt --relative
src/main/kotlin/Foo.kt:1:1: Missing space after // (standard:comment-spacing)
src/main/kotlin/Foo.kt:2:13: Missing newline before "runBlocking { alternativeDatesListingExperiment.sanitizeResponse(subQueryResult, subQuerySanitizer, mockSubListingDetails, getNonPropertyCardStrippingContext(egGraphQLContext, searchParameters = searchParameters)) }" (standard:property-wrapping)
src/main/kotlin/Foo.kt:2:26: Newline expected after opening brace (standard:function-literal)
src/main/kotlin/Foo.kt:2:79: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:95: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:114: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:137: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:172: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:181: Exceeded max line length (180) (standard:max-line-length)
src/main/kotlin/Foo.kt:2:190: Argument should be on a separate line (unless all arguments can fit a single line) (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:225: Missing newline before ")" (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:226: Missing newline before ")" (standard:argument-list-wrapping)
src/main/kotlin/Foo.kt:2:228: Newline expected before closing brace (standard:function-literal)
17:58:21.868 [main] WARN com.pinterest.ktlint.cli.internal.KtlintCommandLine -- Lint has found errors than can be autocorrected using 'ktlint --format'

Summary error count (descending) by rule:
  standard:argument-list-wrapping: 8
  standard:function-literal: 2
  standard:comment-spacing: 1
  standard:max-line-length: 1
  standard:property-wrapping: 1
Disable
ktlint_standard_property-wrapping
for the result that you want.
👍 1
m
Thanks a lot for your help! Since I'm using Gradle for linting and working on a mass reformatting, I mostly used the auto-formatting so I didn't see the involved rules clearly. I have to say that I did read the documentation for
property-wrapping
among others, more than once, and unfortunately its description is not clear at all: I thought it affected a different aspect of the style and not what I was interested in 😞 "property" in my Kotlin vocabulary means only a class field declaration, but this applies also to local variables. Also the example shows just how a type declaration wraps, and not the value, although the description mentions it but it confused me anyway. I'll try to propose an improvement to the docs if you like, as soon as I have time.
p
I was taken off guard as well by the documentation of the rule. I didn't have time to check with unit tests whether the rule is expected to trigger on this specific code usage.
👍 1
m
I can confirm that disabling this rule yielded the desired result.