Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: Line break for each multiline chain expression #543

Open
valentin-mille opened this issue Jun 20, 2023 · 6 comments
Open

Request: Line break for each multiline chain expression #543

valentin-mille opened this issue Jun 20, 2023 · 6 comments

Comments

@valentin-mille
Copy link

valentin-mille commented Jun 20, 2023

Is it plan to add line break for each multiline chain expression? It may be really helpful for SwiftUI view modifiers. For example with :

👉 The input view I want to format
import SwiftUI

struct OkFormattedView: View {
	
	var body: some View {
		VStack {
			Text("Hello, world!" )
		}.padding().background(.red).frame(maxWidth: .infinity, maxHeight: .infinity)
	}
}
❌ The result with the .swift-format configuration file (see below)
import SwiftUI

struct OkFormattedView: View {

	var body: some View {
		VStack {
			Text("Hello, world!")
		}
		.padding().background(.red).frame(maxWidth: .infinity, maxHeight: .infinity)
	}
}
✅ The expected result with the feature request
import SwiftUI

struct OkFormattedView: View {

	var body: some View {
		VStack {
			Text("Hello, world!")
		}
		.padding()
		.background(.red)
		.frame(maxWidth: .infinity, maxHeight: .infinity)
	}
}
.swift-format config used
{
  "version" : 1,
  "lineLength" : 120,
  "indentation" : {
    "tabs" : 1
  },
  "tabWidth" : 4,
  "maximumBlankLines" : 1,
  "respectsExistingLineBreaks" : true,
  "lineBreakBeforeControlFlowKeywords" : false,
  "lineBreakBeforeEachArgument" : true,
  "lineBreakBeforeEachGenericRequirement" : false,
  "prioritizeKeepingFunctionOutputTogether" : false,
  "indentConditionalCompilationBlocks" : false,
  "lineBreakAroundMultilineExpressionChainComponents" : true,
  "fileScopedDeclarationPrivacy" : {
    "accessLevel" : "private"
  },
  "indentSwitchCaseLabels" : false,
  "rules" : {
    "AllPublicDeclarationsHaveDocumentation" : false,
    "AlwaysUseLowerCamelCase" : true,
    "AmbiguousTrailingClosureOverload" : true,
    "BeginDocumentationCommentWithOneLineSummary" : false,
    "DoNotUseSemicolons" : true,
    "DontRepeatTypeInStaticProperties" : true,
    "FileScopedDeclarationPrivacy" : true,
    "FullyIndirectEnum" : true,
    "GroupNumericLiterals" : true,
    "IdentifiersMustBeASCII" : true,
    "NeverForceUnwrap" : false,
    "NeverUseForceTry" : false,
    "NeverUseImplicitlyUnwrappedOptionals" : false,
    "NoAccessLevelOnExtensionDeclaration" : false,
    "NoAssignmentInExpressions" : true,
    "NoBlockComments" : true,
    "NoCasesWithOnlyFallthrough" : true,
    "NoEmptyTrailingClosureParentheses" : true,
    "NoLabelsInCasePatterns" : true,
    "NoLeadingUnderscores" : false,
    "NoParensAroundConditions" : true,
    "NoVoidReturnOnFunctionSignature" : true,
    "OneCasePerLine" : true,
    "OneVariableDeclarationPerLine" : true,
    "OnlyOneTrailingClosureArgument" : true,
    "OrderedImports" : true,
    "ReturnVoidInsteadOfEmptyTuple" : true,
    "UseEarlyExits" : false,
    "UseLetInEveryBoundCaseVariable" : true,
    "UseShorthandTypeNames" : true,
    "UseSingleLinePropertyGetter" : true,
    "UseSynthesizedInitializer" : true,
    "UseTripleSlashForDocumentationComments" : true,
    "UseWhereClausesInForLoops" : false,
    "ValidateDocumentationComments" : false
  },
  "spacesAroundRangeFormationOperators" : false,
}
@allevato
Copy link
Member

This sounds like an interesting idea. I don't think we'd want it in member chains in general (e.g., a.b.c.d), and I don't want to try to detect things like "this is a SwiftUI context", but maybe we could say that if the chain contains function calls, we always break after each function call?

@allevato
Copy link
Member

Actually, can you try setting lineBreakAroundMultilineExpressionChainComponents in your configuration and see if that works for you?

@valentin-mille
Copy link
Author

valentin-mille commented Jun 24, 2023

I agree with your point @allevato. We don't need to analyze the context to know if we are in SwiftUI or UIKit. Applying it to every chain function call may be relevant, even in Swift (e.g. Combine code could be an excellent example with chained subscribers).

In my previous message, lineBreakAroundMultilineExpressionChainComponents was set to true and just broke the line of the first chaining expression. Setting it to false doesn't format the chain expression. It may be better to break each multiline expression when the option is true or create another option for that specific case (to not change existing configuration behavior). Please refer to my previous message for more details about the configuration and the results.

@kuglee
Copy link

kuglee commented Jun 29, 2023

This would be great to have.

@HassanTaleb90
Copy link
Contributor

Interesting

@ahoppen
Copy link
Contributor

ahoppen commented Apr 23, 2024

Tracked in Apple’s issue tracker as rdar://126948253

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants