Created
May 1, 2018 22:04
-
-
Save castus/8bbb4ddc88822d1b4fd7b75e6a3d5418 to your computer and use it in GitHub Desktop.
Add custom rules to SwiftFormat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
extension FormatRules { | |
/// Linebreak after class, extension or struct | |
@objc public class func ststLinebreakAfterClassExtensionStruct(_ formatter: Formatter) { | |
guard formatter.options.removeBlankLines else { return } | |
formatter.forEach(.keyword) { i, token in | |
guard ["class", "extension", "struct"].contains(token.string), | |
let startOfScopeIndex = formatter.index(of: .startOfScope, after: i), | |
let lineBreakAfterStartOfScopeIndex = formatter.index(of: .linebreak, after: startOfScopeIndex), | |
let nextLineBreakAfterStartOfScopeIndex = formatter.index(of: .linebreak, after: lineBreakAfterStartOfScopeIndex) | |
else { | |
return | |
} | |
var hasOnlySpacesBetweenLineBreaks = true | |
for index in lineBreakAfterStartOfScopeIndex + 1 ..< nextLineBreakAfterStartOfScopeIndex { | |
if !formatter.tokens[index].isSpace { | |
hasOnlySpacesBetweenLineBreaks = false | |
break | |
} | |
} | |
if !hasOnlySpacesBetweenLineBreaks { | |
formatter.insertToken(.linebreak(formatter.options.linebreak), at: lineBreakAfterStartOfScopeIndex + 1) | |
return | |
} | |
} | |
} | |
/// Linebreak after guard | |
@objc public class func ststLinebreakAfterGuard(_ formatter: Formatter) { | |
guard formatter.options.removeBlankLines else { return } | |
formatter.forEach(.keyword) { i, token in | |
guard ["guard"].contains(token.string), | |
let startOfScopeIndex = formatter.index(of: .startOfScope, after: i), | |
let endOfScopeIndex = formatter.index(of: .endOfScope, after: startOfScopeIndex + 1), | |
let lineBreakAfterEndOfScopeIndex = formatter.index(of: .linebreak, after: endOfScopeIndex) | |
else { | |
return | |
} | |
formatter.insertToken(.linebreak(formatter.options.linebreak), at: lineBreakAfterEndOfScopeIndex + 1) | |
return | |
} | |
} | |
/// Linebreak after super | |
@objc public class func ststLinebreakAfterSuper(_ formatter: Formatter) { | |
guard formatter.options.removeBlankLines else { return } | |
formatter.forEach(.identifier) { i, token in | |
guard ["super"].contains(token.string), | |
let lineBreakAfterToken = formatter.index(of: .linebreak, after: i) else { | |
return | |
} | |
formatter.insertToken(.linebreak(formatter.options.linebreak), at: lineBreakAfterToken + 1) | |
return | |
} | |
} | |
/// Linebreak before return | |
@objc public class func ststLinebreakBeforeReturn(_ formatter: Formatter) { | |
guard formatter.options.removeBlankLines else { return } | |
formatter.forEach(.keyword) { i, token in | |
guard ["return"].contains(token.string), | |
let lineBreakBeforeToken = formatter.index(of: .linebreak, before: i) else { | |
return | |
} | |
var hasOnlySpacesBetweenStartOfScopeAndReturn = true | |
if let startOfScope = formatter.index(of: .startOfScope, before: lineBreakBeforeToken) { | |
for index in startOfScope + 1 ..< lineBreakBeforeToken { | |
if !formatter.tokens[index].isSpaceOrCommentOrLinebreak { | |
hasOnlySpacesBetweenStartOfScopeAndReturn = false | |
break | |
} | |
} | |
} | |
if !hasOnlySpacesBetweenStartOfScopeAndReturn { | |
formatter.insertToken(.linebreak(formatter.options.linebreak), at: lineBreakBeforeToken) | |
return | |
} | |
} | |
} | |
/// Linebreak at the beginning of a file | |
@objc public class func ststLinebreakAtTheBeginning(_ formatter: Formatter) { | |
if formatter.tokens[0].isLinebreak { | |
formatter.removeToken(at: 0) | |
} | |
formatter.insertToken(.linebreak(formatter.options.linebreak), at: 0) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment