Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misleading formatting when closure signature is placed on its own line #681

Open
ahoppen opened this issue Jan 24, 2024 · 5 comments
Open

Comments

@ahoppen
Copy link
Contributor

ahoppen commented Jan 24, 2024

swift-format produces the following formatting.

let formattedBytes = try await withSwiftFormatConfiguration {
  (formatConfigUrl) -> [UInt8] in
  return []
}

This is misleading because it makes (formatConfigUrl) -> [UInt8] in look like a statement within the closure. I think it would be better if we either added another indentation level to it or preferred to add the line break at a different location (eg. before try) so that the signature can be on the same line as the {.

This came up in https://github.com/apple/sourcekit-lsp/pull/769/files#r1464107380

@MahdiBM
Copy link

MahdiBM commented Jan 24, 2024

In my opinion this formatting is much better than the alternatives you suggested. Those just make it look very weird.

I prefer to have the in on the same line too, but if it makes the line exceed a line-limit, i'd rather it look like the code in the description of the issue than the suggestions.

Note that I don't use swift-format (I hope to be able to, one day, when it meets my expectations) so I'm not sure what exactly is the current behavior. I'm just mentioning what I think the behavior should be.

@judemille
Copy link
Contributor

judemille commented Jan 25, 2024

In my opinion this formatting is much better than the alternatives you suggested. Those just make it look very weird.

@MahdiBM Inserting a line break after the = and before the try is common procedure for a long declaration. Given that this is a declaration, it makes sense. I would much rather break the line there, than after the brace in this case. It looks funny, but is much more understandable.

Note that I don't use swift-format (I hope to be able to, one day, when it meets my expectations) so I'm not sure what exactly is the current behavior.

The current behavior is the code in the issue.

@MahdiBM
Copy link

MahdiBM commented Jan 25, 2024

I guess this would make a good candidate for an enum-like configurable formatting rule. Then everybody can configure swift-format to their liking.

@allevato
Copy link
Collaborator

Breaking the line before the try isn't always going to solve the problem. Depending on the length of the rest of the content of the line, you might still be forced to break around the closure signature:

//                                         margin is here --v
let formattedBytes =
  try await withSwiftFormatConfiguration { arg -> Result in
    somethingElse()

// but then...
//                                         margin is here --v

let formattedBytes =
  try await withSwiftFormatConfiguration {
    arg -> LongerResult in
    somethingElse()

The situation is slightly better for function calls with parenthesized arguments, because you have the option of breaking inside the ( ... ) if there's a trailing closure, which would move the trailing closure signature as far to the left as possible.

Looking at other options, there are rare cases where we move the { onto a new line when the indentation of the line where the { would normally fall is the same as the indentation of the block inside the {. However, we only apply this to declarations and control flow statements which are always followed by that brace-delimited block. But I don't think that's a good option for function calls with trailing closures—the presence of the { immediately after the function name or argument list is critical visual signal to understanding that the call involves a trailing closure.

We have a similar issue with wrapped case clauses, where the indentation is potentially confusable with a statement inside the clause:

switch x {
case .firstCase, .secondCase, .thirdCase,
  .fourthCase:
  somethingElse()
}

@ahoppen
Copy link
Contributor Author

ahoppen commented Apr 23, 2024

Tracked in Apple’s issue tracker as rdar://126948376

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants