mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-05-17 10:30:35 +00:00
97 lines
3.5 KiB
Swift
97 lines
3.5 KiB
Swift
//
|
|
// ConsistentSwitchCaseSpacing.swift
|
|
// SwiftFormat
|
|
//
|
|
// Created by Cal Stephens on 2/1/24.
|
|
// Copyright © 2024 Nick Lockwood. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public extension FormatRule {
|
|
static let consistentSwitchCaseSpacing = FormatRule(
|
|
help: "Ensures consistent spacing among all of the cases in a switch statement.",
|
|
orderAfter: [.blankLineAfterSwitchCase]
|
|
) { formatter in
|
|
formatter.forEach(.keyword("switch")) { switchIndex, _ in
|
|
guard let switchCases = formatter.switchStatementBranchesWithSpacingInfo(at: switchIndex) else { return }
|
|
|
|
// When counting the switch cases, exclude the last case (which should never have a trailing blank line).
|
|
let countWithTrailingBlankLine = switchCases.filter { $0.isFollowedByBlankLine && !$0.isLastCase }.count
|
|
let countWithoutTrailingBlankLine = switchCases.filter { !$0.isFollowedByBlankLine && !$0.isLastCase }.count
|
|
|
|
// We want the spacing to be consistent for all switch cases,
|
|
// so use whichever formatting is used for the majority of cases.
|
|
var allCasesShouldHaveBlankLine = countWithTrailingBlankLine >= countWithoutTrailingBlankLine
|
|
|
|
// When the `blankLinesBetweenChainedFunctions` rule is enabled, and there is a switch case
|
|
// that is required to span multiple lines, then all cases must span multiple lines.
|
|
// (Since if this rule removed the blank line from that case, it would contradict the other rule)
|
|
if formatter.options.enabledRules.contains(FormatRule.blankLineAfterSwitchCase.name),
|
|
switchCases.contains(where: { $0.spansMultipleLines && !$0.isLastCase })
|
|
{
|
|
allCasesShouldHaveBlankLine = true
|
|
}
|
|
|
|
for switchCase in switchCases.reversed() {
|
|
if !switchCase.isFollowedByBlankLine, allCasesShouldHaveBlankLine, !switchCase.isLastCase {
|
|
switchCase.insertTrailingBlankLine(using: formatter)
|
|
}
|
|
|
|
if switchCase.isFollowedByBlankLine, !allCasesShouldHaveBlankLine || switchCase.isLastCase {
|
|
switchCase.removeTrailingBlankLine(using: formatter)
|
|
}
|
|
}
|
|
}
|
|
} examples: {
|
|
#"""
|
|
```diff
|
|
func handle(_ action: SpaceshipAction) {
|
|
switch action {
|
|
case .engageWarpDrive:
|
|
navigationComputer.destination = targetedDestination
|
|
await warpDrive.spinUp()
|
|
warpDrive.activate()
|
|
|
|
case .enableArtificialGravity:
|
|
artificialGravityEngine.enable(strength: .oneG)
|
|
+
|
|
case let .scanPlanet(planet):
|
|
scanner.target = planet
|
|
scanner.scanAtmosphere()
|
|
scanner.scanBiosphere()
|
|
scanner.scanForArtificialLife()
|
|
|
|
case .handleIncomingEnergyBlast:
|
|
energyShields.engage()
|
|
}
|
|
}
|
|
```
|
|
|
|
```diff
|
|
var name: PlanetType {
|
|
switch self {
|
|
case .mercury:
|
|
"Mercury"
|
|
-
|
|
case .venus:
|
|
"Venus"
|
|
case .earth:
|
|
"Earth"
|
|
case .mars:
|
|
"Mars"
|
|
-
|
|
case .jupiter:
|
|
"Jupiter"
|
|
case .saturn:
|
|
"Saturn"
|
|
case .uranus:
|
|
"Uranus"
|
|
case .neptune:
|
|
"Neptune"
|
|
}
|
|
```
|
|
"""#
|
|
}
|
|
}
|