nicklockwood / SwiftFormat

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

Question: Wrap function calls #1530

Open gmoraleda opened 11 months ago

gmoraleda commented 11 months ago

Is there a way to enforce wrapping parameters in a function call? Similarly to wrapping parameters in a function definition.

I.e.:

--wrapparameters after-first
func foo(paramA: TypeA,
          paramB: TypeB,
          paramC: TypeC)

wrapping them when calling the function:

foo(paramA: paramA,
    paramB: paramB,
    paramC: paramC)
nicklockwood commented 11 months ago

--wraparguments wraps the arguments in a function call, --wrapparameters wraps them in a function definition.

gmoraleda commented 11 months ago

hmm, I overlooked that. We have indeed both rules configured in our .swiftformat file:

--binarygrouping none
--patternlet inline
--wraparguments before-first
--wrapcollections before-first
--wrapparameters before-first
--exclude SourcePackages,Packages/CapmoAPI
--enable blankLinesBetweenImports

It seems like sometimes it fails to format. E.g.:

extension DRAutoWeatherReadRequestResponse {
    static let mock = DRAutoWeatherReadRequestResponse(
-        offlineFirstWeather: DRAutoWeatherReadRequestResponse.DROfflineFirstWeather(
-            daily: .mockWeatherId, hourly: []
-        )
+        offlineFirstWeather: DRAutoWeatherReadRequestResponse.DROfflineFirstWeather(daily: .mockWeatherId, hourly: [])
    )
}

is this output expected? my assumption is that the parameters of DRAutoWeatherReadRequestResponse.DROfflineFirstWeather are also wrapped in several lines:


DRAutoWeatherReadRequestResponse.DROfflineFirstWeather(
    daily: .mockWeatherId,
    hourly: []
)
nicklockwood commented 11 months ago

That does seem like a bug. I'll investigate.

nicklockwood commented 10 months ago

@gmoraleda I've not been able to reproduce this with the isolated example you've given. The output I'm getting is the same as the input - i.e. it's not wrapping the hourly argument onto its own line, but it's also not unwrapping the whole thing onto one line.

The choice not to wrap the argument is probably something that should be controllable, but currently it's by design, for cases where the grouping is deliberate/significant.

gmoraleda commented 10 months ago

@nicklockwood thanks for looking into it. I got it doing some formatting by changing the setting from before-first to after-first and then back. That produced the output from the diff. I can share with you the source file and the configuration if that would help debugging.

nicklockwood commented 10 months ago

@gmoraleda I don't need the entire file as long as the problem is reproducible with that sample. I'll try the steps you suggested.

nicklockwood commented 10 months ago

@gmoraleda OK, I tested it. While it may seem odd, this is actually the expected behavior as the rule was designed:

Because the rule keeps grouped arguments together, setting --wraparguments after-first unwraps the whole thing onto one line by removing the line break before the first argument.

Because the rule is only applied either to functions that have already bee wrapped, or ones which exceed the specified --maxwidth, switching back to --wraparguments before-first then has no effect.

If you want lines like this to wrap, you should probably set a value for --maxwidth. If you don't want to apply a line length limit to your project in general then you can fix that by disabling the --wrap rule.