Add new format rule for wrapping case bodies (#2476)

This commit is contained in:
Kim de Vos
2026-03-24 01:02:20 +01:00
committed by Cal Stephens
parent 93004fb971
commit d798a8a5e3
5 changed files with 313 additions and 0 deletions
+1
View File
@@ -141,6 +141,7 @@ let ruleRegistry: [String: FormatRule] = [
"wrap": .wrap,
"wrapArguments": .wrapArguments,
"wrapAttributes": .wrapAttributes,
"wrapCaseBodies": .wrapCaseBodies,
"wrapConditionalBodies": .wrapConditionalBodies,
"wrapEnumCases": .wrapEnumCases,
"wrapFunctionBodies": .wrapFunctionBodies,
+53
View File
@@ -0,0 +1,53 @@
//
// WrapCaseBodies.swift
// SwiftFormat
//
// Created by Kim de Vos on 3/23/26.
// Copyright © 2026 Nick Lockwood. All rights reserved.
//
import Foundation
public extension FormatRule {
static let wrapCaseBodies = FormatRule(
help: "Wrap the bodies of inline switch cases onto a new line.",
disabledByDefault: true,
sharedOptions: ["linebreaks", "indent"]
) { formatter in
formatter.forEach(.endOfScope("case")) { i, _ in
formatter.wrapCaseBody(at: i)
}
formatter.forEach(.endOfScope("default")) { i, _ in
formatter.wrapCaseBody(at: i)
}
} examples: {
"""
```diff
- case .foo: return bar
+ case .foo:
+ return bar
```
"""
}
}
extension Formatter {
func wrapCaseBody(at caseIndex: Int) {
guard let colonIndex = index(of: .startOfScope(":"), after: caseIndex),
var firstTokenIndex = index(of: .nonSpaceOrComment, after: colonIndex),
!tokens[firstTokenIndex].isLinebreak,
!tokens[firstTokenIndex].isEndOfScope
else { return }
insertLinebreak(at: firstTokenIndex)
if tokens[firstTokenIndex - 1].isSpace {
removeToken(at: firstTokenIndex - 1)
firstTokenIndex -= 1
}
let movedTokenIndex = firstTokenIndex + 1
let indent = currentIndentForLine(at: caseIndex) + options.indent
insertSpace(indent, at: movedTokenIndex)
}
}