Swiftformat: Update indent rule behavior to match Xcode 12

Created on 20 Sep 2020  路  8Comments  路  Source: nicklockwood/SwiftFormat

Xcode 12 adds new alignment rules for wrapped expressions, e.g.

if let foo = bar,
    let baz = quux {

}

Now aligns the lets vertically:

if let foo = bar,
   let baz = quux {

}

Which means that the second line is actually indented exactly 3 spaces and not a multiple of the specified indent level.

SwiftFormat should probably adopt this, especially when using --xcodeindentation true. There's a question of whether this should have some way to retain the old behavior though for teams that haven't upgraded to Xcode 12.

@calda, any thoughts?

enhancement fixed in develop

All 8 comments

I would love to see this be an option even for teams that aren't using --xcodeindentation true!

We use --indent 2 and --xcodeindentation disabled (I think we don't like how Xcode indents guard statements), but if there was a --multilineConditional alignKeywords option that works like this then I would totally lobby for us to adopt it.

This is the same for guard, it will align it vertically

Xcode 12 indent

guard let foo = bar,
      let baz = quux else {
    return
}

swiftformat indent

guard let foo = bar,
    let baz = quux else {
        return
}

Also with swiftformat the return in case of guard is alligned at 8 spaces comparing to 4 with Xcode 12.
For if statement, both Xcode 12 and swiftformat allign the return at 4 spaces.

The above indentation was with the following command swiftformat . --rules indent --indent 4 --xcodeindentation enabled

Implemented in 0.47.0

Nice job, just tested it works, in most of the cases.
There are still situations where Xcode indentation is not following their own rules

Xcode

guard let value = foo
        .doSomething()
        .doSomethingElse() else {
    return
}

guard let x = x,
      let value = MyType(
        x: x,
        y: y,
        z: z
      ) else {
    return
}

Swiftformat

guard let value = foo
    .doSomething()
    .doSomethingElse() else {
    return
}

guard let x = x,
      let value = MyType(
          x: x,
          y: y,
          z: z
      ) else {
    return
}

Also } else if let does vertical aligning

Xcode

if foo {

} else if let bar = guas,
          let xuas = assas {

}

if foo ||
    bar &&
    asda {

} else if foo ||
            bar &&
            asda {

}

Swiftformat

if foo {

} else if let bar = guas,
    let xuas = assas {

}

if foo ||
    bar &&
    asda {

} else if foo ||
    bar &&
    asda {

}

@nicklockwood maybe the thing that is missing is the vertical alignment for else if let

@georgescumihai thanks, I'll fix these cases in the next update

For my tests to check the differences I use SourceKitten to interact with SourceKit.

find . -type f -name "*.swift" | while read line; do
  sourcekitten format --file "$line";
done

Fixed in 0.47.1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

igorkulman picture igorkulman  路  3Comments

meherkasam picture meherkasam  路  3Comments

AniHovhannisyanAni picture AniHovhannisyanAni  路  3Comments

shripada picture shripada  路  3Comments

fellipecaetano picture fellipecaetano  路  4Comments