Skip to content

Commit 2feea58

Browse files
committed
Add lineBreakBeforeControlFlowBodies configuration option
1 parent 6484579 commit 2feea58

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

Sources/SwiftFormatConfiguration/Configuration.swift

+12
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

+35-7
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
476476
after(condition.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
477477
}
478478

479-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
479+
arrangeBracesAndContents(
480+
of: node.body,
481+
contentsKeyPath: \.statements,
482+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
483+
)
480484

481485
if let elseKeyword = node.elseKeyword {
482486
// Add a token before the else keyword. Breaking before `else` is explicitly allowed when
@@ -498,7 +502,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
498502
}
499503
}
500504

501-
arrangeBracesAndContents(of: node.elseBody?.as(CodeBlockSyntax.self), contentsKeyPath: \.statements)
505+
arrangeBracesAndContents(
506+
of: node.elseBody?.as(CodeBlockSyntax.self),
507+
contentsKeyPath: \.statements,
508+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
509+
)
502510

503511
return .visitChildren
504512
}
@@ -537,7 +545,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
537545
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
538546
}
539547

540-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
548+
arrangeBracesAndContents(
549+
of: node.body,
550+
contentsKeyPath: \.statements,
551+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
552+
)
541553

542554
return .visitChildren
543555
}
@@ -559,14 +571,22 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
559571
after(condition.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
560572
}
561573

562-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
574+
arrangeBracesAndContents(
575+
of: node.body,
576+
contentsKeyPath: \.statements,
577+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
578+
)
563579

564580
return .visitChildren
565581
}
566582

567583
override func visit(_ node: RepeatWhileStmtSyntax) -> SyntaxVisitorContinueKind {
568584
after(node.labelColon, tokens: .space)
569-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
585+
arrangeBracesAndContents(
586+
of: node.body,
587+
contentsKeyPath: \.statements,
588+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
589+
)
570590

571591
if config.lineBreakBeforeControlFlowKeywords {
572592
before(node.whileKeyword, tokens: .break(.same), .open)
@@ -586,7 +606,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
586606

587607
override func visit(_ node: DoStmtSyntax) -> SyntaxVisitorContinueKind {
588608
after(node.labelColon, tokens: .space)
589-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
609+
arrangeBracesAndContents(
610+
of: node.body,
611+
contentsKeyPath: \.statements,
612+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
613+
)
590614
return .visitChildren
591615
}
592616

@@ -609,7 +633,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
609633
}
610634
}
611635

612-
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
636+
arrangeBracesAndContents(
637+
of: node.body,
638+
contentsKeyPath: \.statements,
639+
openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective
640+
)
613641

614642
return .visitChildren
615643
}

0 commit comments

Comments
 (0)