# Line-Wrapping for Swift ###### tags: `Swift Styles` `Line-wrapping` > Terminology note: Line-wrapping is the activity of dividing code into multiple lines that might otherwise legally occupy a single line. For the purposes of Swift style, many declarations (such as type declarations and function declarations) and other expressions (like function calls) can be partitioned into breakable units that are separated by unbreakable delimiting token sequences. As an example, consider the following complex function declaration, which needs to be line-wrapped: ``` swift public func index<Elements: Collection, Element>(of element: Element, in collection: Elements) -> Elements.Index? where Elements.Element == Element, Element: Equatable { // ... } ``` ## Rules (TL, DR) 1. If the entire declaration, statement, or expression fits on one line, then do that. 2. Comma-delimited lists are only laid out in one direction: horizontally or vertically. In other words, all elements must fit on the same line, or each element must be on its own line. A horizontally-oriented list does not contain any line breaks, even before the first element or after the last element. Except in control flow statements, a vertically-oriented list contains a line break before the first element and after each element. 3. A continuation line starting with an unbreakable token sequence is indented at the same level as the original line. 4. When an open curly brace ({) follows a line-wrapped declaration or expression, it is on the same line as the final continuation line. ## Rules in simple word 1. If statements fit into a single line without breaking the line limit(150 characters), you can keep it in a single line or multiple lines if read better. 2. If statements don't fit into a single line, which should split it into multiple lines. 3. Break those *breakable* elements into multiple lines, who are usually separated by a comma(`,`), for example, function parameters, tuple elements, class/struct generic and their constraints. ```swift public func index<Elements: Collection, Element>(of element: Element, in collection: Elements) -> Elements.Index? where Elements.Element == Element, Element: Equatable { // ... } // Partially breaks breakable elements as it does not exceeds line limit. public func index<Elements: Collection, Element>( // Breaking function elements into multiple-lines of element: Element, in collection: Elements ) -> Elements.Index? where Elements.Element == Element, Element: Equatable { // As far as in character limits for current in elements { // ... } } // Fully breaks breakable elements. public func index< Elements: Collection, // Breaks class generic types for better readability. Element >( of element: Element, // Breaking function elements into multiple-lines. in collection: Elements ) -> Elements.Index? where Elements.Element == Element, // Breaking generic constraints into multiple-lines for readability Element: Equatable { for current in elements { // ... } } ``` ## Example ### Fits to one line? Do it in one line, however, you can wrap it if it reads better. Please see the correct examples. - **if** statement ```swift if aBooleanValueReturnedOptionalThing() && aDifferentBooleanValueReturned() { doSomething() } if aBooleanValueReturnedOptionalThing() && aDifferentBooleanValueReturned() { // Note: aBooleanValueReturnedOptionalThing and aDifferentBooleanValueReturned are alinged vertically, // as they are syntactically parallel elements. (Optional) doSomething() } ``` ```swift if let value = aValueReturned(), let value2 = aDifferentValueReturned() { doSomething() } if let value = aValueReturned(), let value2 = aDifferentValueReturned() { // Note: value and value2 are alinged vertically, as they are syntactically parallel elements. (Optional) doSomething() } ``` - **guard** statement ```swift guard let value = aValueReturned(), let value2 = aDifferentValueReturned() else { doSomething() } guard let value = aValueReturned(), let value2 = aDifferentValueReturned() else { // Note: value and value2 are alinged vertically, as they are syntactically parallel elements. (Optional) doSomething() } ``` - **for** statement ```swift for element in collection where element.meetsConditions() { doSomething() } for element in collection where element.meetsConditions() { doSomething() } ``` - Function calls ```swift let index = index(of: elementVariableName, in: aCollectionOfElements) // Note, demostrating Rule #2. // Rule #2. Comma-delimited lists(function parameters, in this example) are only laid out in one direction: // horizontally (example above, horizaontally fits parameters in one line) // or vertically(this one, once parameters wrapped in new line, all rest parameters are wrapped in a new line). // In other words, all elements must fit on the same line, or each element must be on its own line. let index = index( of: elementVariableName, in: aCollectionOfElements ) // or, note the trailing brace let index = index( of: elementVariableName, in: aCollectionOfElements) ``` - Function declaration ```swift public func index<Element>(of element: Element, in collection: Elements) -> Elements.Index? where Element: Equatable { for current in elements { // ... } } public func index<Element>( of element: Element, in collection: Elements ) -> Elements.Index? where Element: Equatable { for current in elements { // ... } } ``` - Type and Extension Declarations ```swift class MyClass<Element>: MySuperclass, MyProtocol, SomeoneElsesProtocol, SomeFrameworkProtocol where Element:Equatable { // ... } class MyClass<Element>: MySuperclass, MyProtocol, SomeoneElsesProtocol, SomeFrameworkProtocol where Element:Equatable { // ... } ``` ### Does not fit to one line? Wraps every *breakable(e.g. function parameters, tuple elements, generic types, type constraints)* elemnt into all different line - **if** statement ```swift if aBooleanValueReturnedByAVeryLongOptionalThing() && aDifferentBooleanValueReturnedByAVeryLongOptionalThing() && yetAnotherBooleanValueThatContributesToTheWrapping() { // Note: same rule applies here that elements are vertically aligned.(Optional) doSomething() } ``` ```swift if let value = aValueReturnedByAVeryLongOptionalThing(), let value2 = aDifferentValueReturnedByAVeryLongOptionalThingThatForcesTheBraceToBeWrapped() { doSomething() } ``` - Function calls ```swift let index = index( of: veryLongElementVariableName, in: aCollectionOfElementsThatAlsoHappensToHaveALongName ) ``` - Type and Extension Declarations ```swift class MyContainer<BaseCollection>: MyContainerSuperclass, MyContainerProtocol, SomeoneElsesContainerProtocol, SomeFrameworkContainerProtocol where BaseCollection: Collection, BaseCollection.Element: Equatable, BaseCollection.Element: SomeOtherProtocolOnlyUsedToForceLineWrapping { // ... } ```