Skip to content

Commit f8f8032

Browse files
committed
Add lineBreakBeforeControlFlowBodies configuration option
1 parent 6484579 commit f8f8032

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

Sources/SwiftFormatConfiguration/Configuration.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public struct Configuration: Codable, Equatable {
2626
case tabWidth
2727
case indentation
2828
case respectsExistingLineBreaks
29+
case lineBreakBeforeControlFlowBodies
2930
case lineBreakBeforeControlFlowKeywords
3031
case lineBreakBeforeEachArgument
3132
case lineBreakBeforeFuncBodies
@@ -75,6 +76,14 @@ public struct Configuration: Codable, Equatable {
7576

7677
/// MARK: Rule-specific configuration
7778

79+
/// Determines the line-breaking behavior for bodies of control flow keywords, like `if` and
80+
/// `for`.
81+
///
82+
/// If true, a line break will be added after the opening brace of these bodies, forcing them
83+
/// onto their own lines. If false (the default), these bodies will be laid out on the same line
84+
/// as the keyword, with line breaks only being added when the line length would be exceeded.
85+
public var lineBreakBeforeControlFlowBodies = false
86+
7887
/// Determines the line-breaking behavior for control flow keywords that follow a closing brace,
7988
/// like `else` and `catch`.
8089
///
@@ -201,6 +210,8 @@ public struct Configuration: Codable, Equatable {
201210
= try container.decodeIfPresent(Indent.self, forKey: .indentation) ?? .spaces(2)
202211
self.respectsExistingLineBreaks
203212
= try container.decodeIfPresent(Bool.self, forKey: .respectsExistingLineBreaks) ?? true
213+
self.lineBreakBeforeControlFlowBodies
214+
= try container.decodeIfPresent(Bool.self, forKey: .lineBreakBeforeControlFlowBodies) ?? false
204215
self.lineBreakBeforeControlFlowKeywords
205216
= try container.decodeIfPresent(Bool.self, forKey: .lineBreakBeforeControlFlowKeywords) ?? false
206217
self.lineBreakBeforeEachArgument
@@ -242,6 +253,7 @@ public struct Configuration: Codable, Equatable {
242253
try container.encode(tabWidth, forKey: .tabWidth)
243254
try container.encode(indentation, forKey: .indentation)
244255
try container.encode(respectsExistingLineBreaks, forKey: .respectsExistingLineBreaks)
256+
try container.encode(lineBreakBeforeControlFlowBodies, forKey: .lineBreakBeforeControlFlowBodies)
245257
try container.encode(lineBreakBeforeControlFlowKeywords, forKey: .lineBreakBeforeControlFlowKeywords)
246258
try container.encode(lineBreakBeforeEachArgument, forKey: .lineBreakBeforeEachArgument)
247259
try container.encode(lineBreakBeforeEachGenericRequirement, forKey: .lineBreakBeforeEachGenericRequirement)

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
498498
}
499499
}
500500

501-
arrangeBracesAndContents(of: node.elseBody?.as(CodeBlockSyntax.self), contentsKeyPath: \.statements)
501+
arrangeBracesAndContents(
502+
of: node.elseBody?.as(CodeBlockSyntax.self),
503+
contentsKeyPath: \.statements,
504+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
505+
)
502506

503507
return .visitChildren
504508
}
@@ -537,7 +541,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
537541
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
538542
}
539543

540-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
544+
arrangeBracesAndContents(
545+
of: node.body,
546+
contentsKeyPath: \.statements,
547+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
548+
)
541549

542550
return .visitChildren
543551
}
@@ -559,14 +567,22 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
559567
after(condition.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
560568
}
561569

562-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
570+
arrangeBracesAndContents(
571+
of: node.body,
572+
contentsKeyPath: \.statements,
573+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
574+
)
563575

564576
return .visitChildren
565577
}
566578

567579
override func visit(_ node: RepeatWhileStmtSyntax) -> SyntaxVisitorContinueKind {
568580
after(node.labelColon, tokens: .space)
569-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
581+
arrangeBracesAndContents(
582+
of: node.body,
583+
contentsKeyPath: \.statements,
584+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
585+
)
570586

571587
if config.lineBreakBeforeControlFlowKeywords {
572588
before(node.whileKeyword, tokens: .break(.same), .open)
@@ -586,7 +602,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
586602

587603
override func visit(_ node: DoStmtSyntax) -> SyntaxVisitorContinueKind {
588604
after(node.labelColon, tokens: .space)
589-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
605+
arrangeBracesAndContents(
606+
of: node.body,
607+
contentsKeyPath: \.statements,
608+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
609+
)
590610
return .visitChildren
591611
}
592612

@@ -609,7 +629,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
609629
}
610630
}
611631

612-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
632+
arrangeBracesAndContents(
633+
of: node.body,
634+
contentsKeyPath: \.statements,
635+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
636+
)
613637

614638
return .visitChildren
615639
}

0 commit comments

Comments
 (0)