Skip to content

Commit 2107603

Browse files
authored
Merge pull request #204 from MPLew-is/indented-case
Allow indenting case statements relative to the containing switch block
2 parents f4367f0 + 6a91b91 commit 2107603

File tree

4 files changed

+441
-3
lines changed

4 files changed

+441
-3
lines changed

Sources/SwiftFormatConfiguration/Configuration.swift

+25
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public struct Configuration: Codable, Equatable {
3333
case indentConditionalCompilationBlocks
3434
case lineBreakAroundMultilineExpressionChainComponents
3535
case fileScopedDeclarationPrivacy
36+
case indentSwitchCaseLabels
3637
case rules
3738
}
3839

@@ -120,6 +121,27 @@ public struct Configuration: Codable, Equatable {
120121
/// declarations whose effective access level is private to the containing file.
121122
public var fileScopedDeclarationPrivacy = FileScopedDeclarationPrivacyConfiguration()
122123

124+
/// Determines if `case` statements should be indented compared to the containing `switch` block.
125+
///
126+
/// When `false`, the correct form is:
127+
/// ```swift
128+
/// switch someValue {
129+
/// case someCase:
130+
/// someStatement
131+
/// ...
132+
/// }
133+
/// ```
134+
///
135+
/// When `true`, the correct form is:
136+
/// ```swift
137+
/// switch someValue {
138+
/// case someCase:
139+
/// someStatement
140+
/// ...
141+
/// }
142+
///```
143+
public var indentSwitchCaseLabels = false
144+
123145
/// Constructs a Configuration with all default values.
124146
public init() {
125147
self.version = highestSupportedConfigurationVersion
@@ -176,6 +198,8 @@ public struct Configuration: Codable, Equatable {
176198
try container.decodeIfPresent(
177199
FileScopedDeclarationPrivacyConfiguration.self, forKey: .fileScopedDeclarationPrivacy)
178200
?? FileScopedDeclarationPrivacyConfiguration()
201+
self.indentSwitchCaseLabels
202+
= try container.decodeIfPresent(Bool.self, forKey: .indentSwitchCaseLabels) ?? false
179203

180204
// If the `rules` key is not present at all, default it to the built-in set
181205
// so that the behavior is the same as if the configuration had been
@@ -203,6 +227,7 @@ public struct Configuration: Codable, Equatable {
203227
lineBreakAroundMultilineExpressionChainComponents,
204228
forKey: .lineBreakAroundMultilineExpressionChainComponents)
205229
try container.encode(fileScopedDeclarationPrivacy, forKey: .fileScopedDeclarationPrivacy)
230+
try container.encode(indentSwitchCaseLabels, forKey: .indentSwitchCaseLabels)
206231
try container.encode(rules, forKey: .rules)
207232
}
208233

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

+20-3
Original file line numberDiff line numberDiff line change
@@ -644,10 +644,27 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
644644
}
645645

646646
override func visit(_ node: SwitchCaseSyntax) -> SyntaxVisitorContinueKind {
647-
before(node.firstToken, tokens: .break(.same, newlines: .soft))
647+
// If switch/case labels were configured to be indented, use an `open` break; otherwise, use
648+
// the default `same` break.
649+
let openBreak: Token
650+
if config.indentSwitchCaseLabels {
651+
openBreak = .break(.open, newlines: .elective)
652+
} else {
653+
openBreak = .break(.same, newlines: .soft)
654+
}
655+
before(node.firstToken, tokens: openBreak)
656+
648657
after(node.unknownAttr?.lastToken, tokens: .space)
649658
after(node.label.lastToken, tokens: .break(.reset, size: 0), .break(.open), .open)
650-
after(node.lastToken, tokens: .break(.close, size: 0), .close)
659+
660+
// If switch/case labels were configured to be indented, insert an extra `close` break after the
661+
// case body to match the `open` break above
662+
var afterLastTokenTokens: [Token] = [.break(.close, size: 0), .close]
663+
if config.indentSwitchCaseLabels {
664+
afterLastTokenTokens.append(.break(.close, size: 0))
665+
}
666+
after(node.lastToken, tokens: afterLastTokenTokens)
667+
651668
return .visitChildren
652669
}
653670

@@ -2028,7 +2045,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
20282045
}
20292046
return .visitChildren
20302047
}
2031-
2048+
20322049
override func visit(_ node: SameTypeRequirementSyntax) -> SyntaxVisitorContinueKind {
20332050
before(node.equalityToken, tokens: .break)
20342051
after(node.equalityToken, tokens: .space)

0 commit comments

Comments
 (0)