nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.9k stars 640 forks source link

Indentation wrong in a commented method call chain #882

Closed sebastianludwig closed 3 years ago

sebastianludwig commented 3 years ago

We're using PromiseKit and sometimes like to annotate longer chains (I guess it's the same for Rx). Unfortunately the following code block

firstly {
    doSomething()
}
// then do something else
.then {
    doSomethingElse()
}
// convert the thing
.map {
    transform($0)
}

get's formatted to

firstly {
    doSomething()
}
// then do something else
    .then {
        doSomethingElse()
    }
    // convert the thing
        .map {
            transform($0)
        }

Running SwiftFormat with --verbose showed that only -- rules applied: indent was applied to the file. We did not find a way to change this behaviour - is there? Or is it a bug?

A block without comments remains unchanged

firstly {
    doSomething()
}
.then {
    doSomethingElse()
}.map {
    transform($0)
}
nicklockwood commented 3 years ago

@sebastianludwig I'm seeing a slightly different bug. When I try your code sample with the default rules I get:

firstly {
    doSomething()
}

// then do something else
.then {
    doSomethingElse()
}

// convert the thing
.map {
    transform($0)
}

which is caused by the blankLinesBetweenScopes rule. Can you confirm which version of SwiftFormat you are using, and what configuration (if any)?

sebastianludwig commented 3 years ago

oh, yeah, could have thought of that

--disable blankLinesBetweenScopes
--disable wrapMultilineStatementBraces
--commas false
--xcodeindentation enabled
--extensionacl on-declarations
--modifierorder public,override
nicklockwood commented 3 years ago

@sebastianludwig fixed in 0.47.13.

sebastianludwig commented 3 years ago

Hey, sorry for the delay, I just got around to testing the fix. The given example works great 👍 However I noticed a second constellation which does not work yet

input
    // trim whitespace and newlines at the beginning and end
    .trimmingCharacters(in: .whitespacesAndNewlines)
    // trim spaces at the end of every line
    .split(separator: "\n")
    .map { String($0).replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression) }
    .joined(separator: "\n")

becomes

input
    // trim whitespace and newlines at the beginning and end
        .trimmingCharacters(in: .whitespacesAndNewlines)
        // trim spaces at the end of every line
        .split(separator: "\n")
        .map { String($0).replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression) }
        .joined(separator: "\n")

Do you want me to open a separate issue for that?