Change https://github.com/swiftlang/sourcekit-lsp/pull/1072 introduced automatic expansion of trailing closures. For example, when requesting completion for a call to the function func foo(bar: Bar, baz: @escaping () -> Void) sourcekit-lsp manipulates the function template to produce this (using Xcode placeholder syntax to avoid confusion with closure shorthand args):
foo(bar: <#Bar#>) {
<#Void#>
}
While this multi-line expansion may be appropriate for callback-based (Timer.scheduledTimer) or scope-defining (DispatchQueue.async, String.withUTF8) functions, it is strictly worse in my opinion for simple predicate-based calls. Consider someArray.filter: this expands to three lines with two placeholders:
someArray.filter { <#Foo#> in
<#Bool#>
}
But more often than not I was just going to type a short single-line expression like someArray.filter { $0.bar() == baz }, or even to use a key path: someArray.map(\.bar). Even for a callback it is not uncommon to use a named function reference rather than a literal: foo(bar: someBar, baz: handleBaz).
It is much more work now to correct the multi-line expanded form to the shorter version than it was to expand a callback-based method from foo(bar: <#Bar#>, <#() -> Void#>).
Proposed Change
Whether to expand trailing closures at all, let alone to multiple lines, is largely a stylistic decision; as such the language server should permit user control over it. A field should be added to [the configuration options][2] allowing this feature to be turned off (and, perhaps, to allow reducing its intensity: cf. https://github.com/swiftlang/sourcekit-lsp/issues/1788).
Description
Context
Change https://github.com/swiftlang/sourcekit-lsp/pull/1072 introduced automatic expansion of trailing closures. For example, when requesting completion for a call to the function
func foo(bar: Bar, baz: @escaping () -> Void)
sourcekit-lsp manipulates the function template to produce this (using Xcode placeholder syntax to avoid confusion with closure shorthand args):While this multi-line expansion may be appropriate for callback-based (
Timer.scheduledTimer
) or scope-defining (DispatchQueue.async
,String.withUTF8
) functions, it is strictly worse in my opinion for simple predicate-based calls. ConsidersomeArray.filter
: this expands to three lines with two placeholders:But more often than not I was just going to type a short single-line expression like
someArray.filter { $0.bar() == baz }
, or even to use a key path:someArray.map(\.bar)
. Even for a callback it is not uncommon to use a named function reference rather than a literal:foo(bar: someBar, baz: handleBaz)
.It is much more work now to correct the multi-line expanded form to the shorter version than it was to expand a callback-based method from
foo(bar: <#Bar#>, <#() -> Void#>)
.Proposed Change
Whether to expand trailing closures at all, let alone to multiple lines, is largely a stylistic decision; as such the language server should permit user control over it. A field should be added to [the configuration options][2] allowing this feature to be turned off (and, perhaps, to allow reducing its intensity: cf. https://github.com/swiftlang/sourcekit-lsp/issues/1788).
[2]: https://github.com/swiftlang/sourcekit-lsp/blob/f25055094789a27af9ecd3b965717bcf5008faa6/Documentation/Configuration%20File.md