如何强制clang-format将类实例化中的数组初始化放在单行?
问题
无法让clang-format将类实例化中的数组初始化格式化为单行。
基础代码:
class Foo { Foo(const std::vector<int>& a, const std::map<int, std::list<std::string>>& b); }
期望格式化结果:
void test() { Foo f({1, 2, 3}, {{0, {"toto"}}}); }
实际格式化结果:
void test() { Foo f({ 1, 2, 3 }, {{0, {"toto"}}}); }
推测嵌套括号是导致clang-format识别混乱的原因,去掉一层括号后代码可正常格式化:
void test() { Foo f({1, 2, 3}, {0, {"toto"}}); }
当前clang-format配置:
--- Language: Cpp AccessModifierOffset: -2 AlignAfterOpenBracket: Align AlignArrayOfStructures: Right AlignConsecutiveAssignments: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false PadOperators: true AlignConsecutiveBitFields: Enabled: true AcrossEmptyLines: false AcrossComments: false AlignCompound: false PadOperators: false AlignConsecutiveDeclarations: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false PadOperators: false AlignConsecutiveMacros: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false PadOperators: false AlignEscapedNewlines: Right AlignOperands: AlignAfterOperator AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortEnumsOnASingleLine: false AllowShortBlocksOnASingleLine: Empty AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Empty AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: MultiLine AttributeMacros: - __capability BinPackArguments: true BinPackParameters: true BraceWrapping: # not used if BreakBeforeBraces is not set to Custom AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: true AfterFunction: true AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true AfterUnion: true AfterExternBlock: true BeforeCatch: false BeforeElse: false BeforeLambdaBody: true BeforeWhile: false IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBinaryOperators: None BreakBeforeBraces: Allman BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeComma BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 0 CommentPragmas: "^ IWYU pragma:" QualifierAlignment: Left CompactNamespaces: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: false DisableFormat: false EmptyLineAfterAccessModifier: Never EmptyLineBeforeAccessModifier: LogicalBlock ExperimentalAutoDetectBinPacking: false PackConstructorInitializers: BinPack BasedOnStyle: "" ConstructorInitializerAllOnOneLineOrOnePerLine: false AllowAllConstructorInitializersOnNextLine: true FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH IfMacros: - KJ_IF_MAYBE IncludeBlocks: Preserve IncludeCategories: - Regex: '^"(llvm|llvm-c|clang|clang-c)/' Priority: 2 SortPriority: 0 CaseSensitive: false - Regex: '^(<|"(gtest|gmock|isl|json)/)' Priority: 3 SortPriority: 0 CaseSensitive: false - Regex: ".*" Priority: 1 SortPriority: 0 CaseSensitive: false IncludeIsMainRegex: "(Test)?$" IncludeIsMainSourceRegex: "" IndentAccessModifiers: false IndentCaseLabels: true IndentCaseBlocks: true IndentGotoLabels: true IndentPPDirectives: BeforeHash IndentExternBlock: AfterExternBlock IndentWidth: 4 IndentWrappedFunctionNames: false InsertTrailingCommas: None JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false LambdaBodyIndentation: Signature MacroBlockBegin: "" MacroBlockEnd: "" MaxEmptyLinesToKeep: 1 NamespaceIndentation: All ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 2 ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakOpenParenthesis: 0 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 1000 PenaltyIndentedWhitespace: 0 PointerAlignment: Left PPIndentWidth: -1 ReferenceAlignment: Pointer ReflowComments: true RemoveBracesLLVM: false RequiresClausePosition: OwnLine SeparateDefinitionBlocks: Leave ShortNamespaceLines: 1 SortIncludes: CaseSensitive SortJavaStaticImport: Before SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false SpaceBeforeAssignmentOperators: true SpaceBeforeCaseColon: false SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements SpaceBeforeParensOptions: AfterControlStatements: true AfterForeachMacros: true AfterFunctionDefinitionName: false AfterFunctionDeclarationName: false AfterIfMacros: true AfterOverloadedOperator: false AfterRequiresInClause: false AfterRequiresInExpression: false BeforeNonEmptyParentheses: false SpaceAroundPointerQualifiers: Default SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: Never SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInLineCommentPrefix: Minimum: 1 Maximum: -1 SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false BitFieldColonSpacing: Both Standard: Latest StatementAttributeLikeMacros: - Q_EMIT StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION TabWidth: 4 UseCRLF: false UseTab: Never WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE - BOOST_PP_STRINGIZE - NS_SWIFT_NAME - CF_SWIFT_NAME ...
解决方案
通过调整以下两个配置项,可实现期望的格式化效果:
修改
AlignAfterOpenBracket
将原配置的AlignAfterOpenBracket: Align改为AlignAfterOpenBracket: DontAlign。该配置控制括号打开后的对齐方式,Align会强制对齐嵌套括号内的内容,容易触发不必要换行;改为DontAlign后,短初始化列表会保持单行,同时参数列表仍会按预期换行对齐。提高
PenaltyBreakOpenParenthesis值
将PenaltyBreakOpenParenthesis: 0调整为PenaltyBreakOpenParenthesis: 1000。这个参数控制clang-format在括号后换行的惩罚权重,值越高,越不容易在括号内换行。
调整后的关键配置片段:
AlignAfterOpenBracket: DontAlign PenaltyBreakOpenParenthesis: 1000
重新格式化后,代码会变为期望的样式:
void test() { Foo f({1, 2, 3}, {{0, {"toto"}}}); }
若需保留部分括号对齐行为,也可尝试关闭Cpp11BracedListStyle(设置为false),但这会改变所有C++11风格花括号的格式化逻辑,需结合项目整体代码风格权衡。
内容的提问来源于stack exchange,提问作者Aimnor
相关产品推荐
相关产品推荐

