diff --git a/Sources/SwiftFormatConfiguration/Configuration.swift b/Sources/SwiftFormatConfiguration/Configuration.swift index 8406f1002..7cfe659b7 100644 --- a/Sources/SwiftFormatConfiguration/Configuration.swift +++ b/Sources/SwiftFormatConfiguration/Configuration.swift @@ -26,6 +26,7 @@ public struct Configuration: Codable, Equatable { case tabWidth case indentation case respectsExistingLineBreaks + case lineBreakBeforeControlFlowBodies case lineBreakBeforeControlFlowKeywords case lineBreakBeforeEachArgument case lineBreakBeforeFuncBodies @@ -75,6 +76,8 @@ public struct Configuration: Codable, Equatable { /// MARK: Rule-specific configuration + public var lineBreakBeforeControlFlowBodies = false + /// Determines the line-breaking behavior for control flow keywords that follow a closing brace, /// like `else` and `catch`. /// @@ -201,6 +204,8 @@ public struct Configuration: Codable, Equatable { = try container.decodeIfPresent(Indent.self, forKey: .indentation) ?? .spaces(2) self.respectsExistingLineBreaks = try container.decodeIfPresent(Bool.self, forKey: .respectsExistingLineBreaks) ?? true + self.lineBreakBeforeControlFlowBodies + = try container.decodeIfPresent(Bool.self, forKey: .lineBreakBeforeControlFlowBodies) ?? false self.lineBreakBeforeControlFlowKeywords = try container.decodeIfPresent(Bool.self, forKey: .lineBreakBeforeControlFlowKeywords) ?? false self.lineBreakBeforeEachArgument @@ -242,6 +247,7 @@ public struct Configuration: Codable, Equatable { try container.encode(tabWidth, forKey: .tabWidth) try container.encode(indentation, forKey: .indentation) try container.encode(respectsExistingLineBreaks, forKey: .respectsExistingLineBreaks) + try container.encode(lineBreakBeforeControlFlowBodies, forKey: .lineBreakBeforeControlFlowBodies) try container.encode(lineBreakBeforeControlFlowKeywords, forKey: .lineBreakBeforeControlFlowKeywords) try container.encode(lineBreakBeforeEachArgument, forKey: .lineBreakBeforeEachArgument) try container.encode(lineBreakBeforeEachGenericRequirement, forKey: .lineBreakBeforeEachGenericRequirement) diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 8711f3f4f..1ba27a923 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -496,7 +496,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } } - arrangeBracesAndContents(of: node.elseBody?.as(CodeBlockSyntax.self), contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.elseBody?.as(CodeBlockSyntax.self), + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) return .visitChildren } @@ -535,7 +539,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0)) } - arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.body, + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) return .visitChildren } @@ -557,14 +565,22 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { after(condition.lastToken, tokens: .break(.close(mustBreak: false), size: 0)) } - arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.body, + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) return .visitChildren } override func visit(_ node: RepeatWhileStmtSyntax) -> SyntaxVisitorContinueKind { after(node.labelColon, tokens: .space) - arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.body, + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) if config.lineBreakBeforeControlFlowKeywords { before(node.whileKeyword, tokens: .break(.same), .open) @@ -584,7 +600,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { override func visit(_ node: DoStmtSyntax) -> SyntaxVisitorContinueKind { after(node.labelColon, tokens: .space) - arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.body, + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) return .visitChildren } @@ -607,7 +627,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } } - arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements) + arrangeBracesAndContents( + of: node.body, + contentsKeyPath: \.statements, + openBraceNewlineBehavior: config.lineBreakBeforeControlFlowBodies ? .hard : .elective + ) return .visitChildren }