galenelias updated this revision to Diff 537383. galenelias edited the summary of this revision. galenelias added a comment.
I re-wrote the alignment to stop using AlignTokens so that I can now handle all the edge cases that came up. Specifically: - Allowing empty case labels (implicit fall through) to not break the alignment, but only if they are sandwiched by short case statements. - Don't align the colon of a non-short case label that follows short case labels when using 'AlignCaseColons=true'. - Empty case labels will also now push out the alignment of the statements when using AlignCaseColons=false. Also, this now avoids having to add the `IgnoreNestedScopes` parameter to `AlignTokens` which didn't feel great. I refactored `AlignMacroSequence` so I could re-use the core aligning method, since it's the same logic I need, but I removed some of the dead code just to simplify things along the way. But even with that, this version is quite a bit more code (~100 lines vs. ~30 lines). CHANGES SINCE LAST ACTION https://reviews.llvm.org/D151761/new/ https://reviews.llvm.org/D151761 Files: clang/docs/ClangFormatStyleOptions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/WhitespaceManager.cpp clang/lib/Format/WhitespaceManager.h clang/unittests/Format/ConfigParseTest.cpp clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -19244,6 +19244,255 @@ BracedAlign); } +TEST_F(FormatTest, AlignConsecutiveShortCaseStatements) { + FormatStyle Alignment = getLLVMStyle(); + Alignment.AllowShortCaseLabelsOnASingleLine = true; + Alignment.AlignConsecutiveShortCaseStatements.Enabled = true; + + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "default: return \"default\";\n" + "}", + Alignment); + + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning:\n" + " return \"warning\";\n" + "}", + Alignment); + + // Empty case statements push out the alignment, but non-short case labels don't. + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::critical:\n" + "case log::warning:\n" + "case log::severe: return \"severe\";\n" + "case log::extra_severe:\n" + " // comment\n" + " return \"extra_severe\";\n" + "}", + Alignment); + + // Verify comments and empty lines break the alignment. + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "// comment\n" + "case log::critical: return \"critical\";\n" + "default: return \"default\";\n" + "\n" + "case log::severe: return \"severe\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "// comment\n" + "case log::critical: return \"critical\";\n" + "default: return \"default\";\n" + "\n" + "case log::severe: return \"severe\";\n" + "}", + Alignment); + + // Empty case statements don't break the alignment, and potentially push it out + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning:\n" + "case log::critical:\n" + "default: return \"default\";\n" + "}", + Alignment); + + // Implicit fallthrough cases can be aligned with either a comment or + // [[fallthrough]] + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: // fallthrough\n" + "case log::error: return \"error\";\n" + "case log::critical: /*fallthrough*/\n" + "case log::severe: return \"severe\";\n" + "case log::diag: [[fallthrough]];\n" + "default: return \"default\";\n" + "}", + Alignment); + + // Verify trailing comment that needs a reflow also gets aligned properly. + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: // fallthrough\n" + "case log::error: return \"error\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: //fallthrough\n" + "case log::error: return \"error\";\n" + "}", + Alignment); + + // Verify adjacent non-short case statements don't change the alignment, and + // properly break the set of consecutive statements. + verifyFormat("switch (level) {\n" + "case log::critical:\n" + " // comment\n" + " return \"critical\";\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "default:\n" + " // comment\n" + " return \"\";\n" + "case log::error: return \"error\";\n" + "case log::severe: return \"severe\";\n" + "case log::extra_critical:\n" + " // comment\n" + " return \"extra critical\";\n" + "}", + Alignment); + + Alignment.SpaceBeforeCaseColon = true; + verifyFormat("switch (level) {\n" + "case log::info : return \"info\";\n" + "case log::warning : return \"warning\";\n" + "default : return \"default\";\n" + "}", + Alignment); + Alignment.SpaceBeforeCaseColon = false; + + // Make sure we don't incorrectly align correctly across nested switch cases. + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "case log::other:\n" + " switch (sublevel) {\n" + " case log::info: return \"info\";\n" + " case log::warning: return \"warning\";\n" + " }\n" + " break;\n" + "case log::error: return \"error\";\n" + "default: return \"default\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "case log::warning: return \"warning\";\n" + "case log::other: switch (sublevel) {\n" + " case log::info: return \"info\";\n" + " case log::warning: return \"warning\";\n" + "}\n" + "break;\n" + "case log::error: return \"error\";\n" + "default: return \"default\";\n" + "}", + Alignment); + + Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = true; + + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "\n" + "case log::warning: return \"warning\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "\n" + "case log::warning: return \"warning\";\n" + "}", + Alignment); + + Alignment.AlignConsecutiveShortCaseStatements.AcrossComments = true; + + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "\n" + "/* block comment */\n" + "\n" + "// line comment\n" + "case log::warning: return \"warning\";\n" + "}", + "switch (level) {\n" + "case log::info: return \"info\";\n" + "\n" + "/* block comment */\n" + "\n" + "// line comment\n" + "case log::warning: return \"warning\";\n" + "}", + Alignment); + + Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = false; + + verifyFormat("switch (level) {\n" + "case log::info: return \"info\";\n" + "//\n" + "case log::warning: return \"warning\";\n" + "}", + Alignment); + + Alignment.AlignConsecutiveShortCaseStatements.AlignCaseColons = true; + + verifyFormat("switch (level) {\n" + "case log::info : return \"info\";\n" + "case log::warning: return \"warning\";\n" + "default : return \"default\";\n" + "}", + Alignment); + + // With AlignCaseColons, empty case statements don't break alignment of + // consecutive case statements (and are aligned). + verifyFormat("switch (level) {\n" + "case log::info : return \"info\";\n" + "case log::warning :\n" + "case log::critical:\n" + "default : return \"default\";\n" + "}", + Alignment); + + // Final non-short case labels shouldn't have their colon aligned + verifyFormat("switch (level) {\n" + "case log::info : return \"info\";\n" + "case log::warning :\n" + "case log::critical:\n" + "case log::severe : return \"severe\";\n" + "default:\n" + " // comment\n" + " return \"default\";\n" + "}", + Alignment); + + // Verify adjacent non-short case statements break the set of consecutive + // alignments and aren't aligned with adjacent non-short case statements if + // AlignCaseColons is set. + verifyFormat("switch (level) {\n" + "case log::critical:\n" + " // comment\n" + " return \"critical\";\n" + "case log::info : return \"info\";\n" + "case log::warning: return \"warning\";\n" + "default:\n" + " // comment\n" + " return \"\";\n" + "case log::error : return \"error\";\n" + "case log::severe: return \"severe\";\n" + "case log::extra_critical:\n" + " // comment\n" + " return \"extra critical\";\n" + "}", + Alignment); + + Alignment.SpaceBeforeCaseColon = true; + verifyFormat("switch (level) {\n" + "case log::info : return \"info\";\n" + "case log::warning : return \"warning\";\n" + "case log::error :\n" + "default : return \"default\";\n" + "}", + Alignment); +} + TEST_F(FormatTest, AlignWithLineBreaks) { auto Style = getLLVMStyleWithColumns(120); Index: clang/unittests/Format/ConfigParseTest.cpp =================================================================== --- clang/unittests/Format/ConfigParseTest.cpp +++ clang/unittests/Format/ConfigParseTest.cpp @@ -318,6 +318,7 @@ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields); CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros); CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations); + CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveShortCaseStatements); #undef CHECK_ALIGN_CONSECUTIVE Index: clang/lib/Format/WhitespaceManager.h =================================================================== --- clang/lib/Format/WhitespaceManager.h +++ clang/lib/Format/WhitespaceManager.h @@ -232,6 +232,9 @@ /// Align consecutive declarations over all \c Changes. void alignChainedConditionals(); + /// Align consecutive short case statements over all \c Changes. + void alignConsecutiveShortCaseStatements(); + /// Align trailing comments over all \c Changes. void alignTrailingComments(); Index: clang/lib/Format/WhitespaceManager.cpp =================================================================== --- clang/lib/Format/WhitespaceManager.cpp +++ clang/lib/Format/WhitespaceManager.cpp @@ -105,6 +105,7 @@ alignConsecutiveDeclarations(); alignConsecutiveBitFields(); alignConsecutiveAssignments(); + alignConsecutiveShortCaseStatements(); alignChainedConditionals(); alignTrailingComments(); alignEscapedNewlines(); @@ -663,14 +664,12 @@ // // We need to adjust the StartOfTokenColumn of each Change that is on a line // containing any matching token to be aligned and located after such token. -static void AlignMacroSequence( +static void AlignMatchingTokenSequence( unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn, - unsigned &MaxColumn, bool &FoundMatchOnLine, - std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches, + std::function<bool(const WhitespaceManager::Change &C)> Matches, SmallVector<WhitespaceManager::Change, 16> &Changes) { if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) { - - FoundMatchOnLine = false; + bool FoundMatchOnLine = false; int Shift = 0; for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) { @@ -681,8 +680,8 @@ // If this is the first matching token to be aligned, remember by how many // spaces it has to be shifted, so the rest of the changes on the line are - // shifted by the same amount - if (!FoundMatchOnLine && AlignMacrosMatches(Changes[I])) { + // shifted by the same amount. + if (!FoundMatchOnLine && Matches(Changes[I])) { FoundMatchOnLine = true; Shift = MinColumn - Changes[I].StartOfTokenColumn; Changes[I].Spaces += Shift; @@ -696,7 +695,6 @@ } MinColumn = 0; - MaxColumn = UINT_MAX; StartOfSequence = 0; EndOfSequence = 0; } @@ -735,7 +733,6 @@ }; unsigned MinColumn = 0; - unsigned MaxColumn = UINT_MAX; // Start and end of the token sequence we're processing. unsigned StartOfSequence = 0; @@ -763,8 +760,8 @@ !(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments); if (EmptyLineBreak || NoMatchBreak) { - AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn, - FoundMatchOnLine, AlignMacrosMatches, Changes); + AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, + AlignMacrosMatches, Changes); } // A new line starts, re-initialize line status tracking bools. @@ -784,18 +781,12 @@ StartOfSequence = I; unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn; - int LineLengthAfter = -Changes[I].Spaces; - for (unsigned j = I; j != E && Changes[j].NewlinesBefore == 0; ++j) - LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength; - unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter; - MinColumn = std::max(MinColumn, ChangeMinColumn); - MaxColumn = std::min(MaxColumn, ChangeMaxColumn); } EndOfSequence = I; - AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn, - FoundMatchOnLine, AlignMacrosMatches, Changes); + AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, + AlignMacrosMatches, Changes); } void WhitespaceManager::alignConsecutiveAssignments() { @@ -851,6 +842,111 @@ Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields); } +void WhitespaceManager::alignConsecutiveShortCaseStatements() { + if (!Style.AlignConsecutiveShortCaseStatements.Enabled || + !Style.AllowShortCaseLabelsOnASingleLine) { + return; + } + + auto Matches = [&](const Change &C) { + if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) { + return C.Tok->is(TT_CaseLabelColon); + } else { + // Ignore 'IsInsideToken' to allow matching trailing comments which + // need to be reflowed as that causes the token to appear in two + // different changes, which will cause incorrect alignment as we'll + // reflow early due to detecting multiple aligning tokens per line. + return (!C.IsInsideToken && C.Tok->Previous && + C.Tok->Previous->is(TT_CaseLabelColon)); + } + }; + + unsigned MinColumn = 0; + + // Empty case statements don't break the alignment, but don't necessarily + // match our predicate, so we need to track their column so they can push out + // our alignment. + unsigned MinEmptyCaseColumn = 0; + + // Start and end of the token sequence we're processing. + unsigned StartOfSequence = 0; + unsigned EndOfSequence = 0; + + // Whether a matching token has been found on the current line. + bool FoundMatchOnLine = false; + + bool LineIsComment = true; + bool LineIsEmptyCase = false; + + unsigned I = 0; + for (unsigned E = Changes.size(); I != E; ++I) { + if (Changes[I].NewlinesBefore != 0) { + // Whether to break the alignment sequence because of an empty line. + bool EmptyLineBreak = + (Changes[I].NewlinesBefore > 1) && + !Style.AlignConsecutiveShortCaseStatements.AcrossEmptyLines; + + // Whether to break the alignment sequence because of a line without a + // match. + bool NoMatchBreak = + !FoundMatchOnLine && + !(LineIsComment && + Style.AlignConsecutiveShortCaseStatements.AcrossComments) && + !LineIsEmptyCase; + + if (EmptyLineBreak || NoMatchBreak) { + AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, + Matches, Changes); + MinEmptyCaseColumn = 0; + } + + // A new line starts, re-initialize line status tracking bools. + FoundMatchOnLine = false; + LineIsComment = true; + LineIsEmptyCase = false; + } + + if (!Changes[I].Tok->is(tok::comment)) + LineIsComment = false; + + if (Changes[I].Tok->is(TT_CaseLabelColon)) { + LineIsEmptyCase = Changes[I].Tok->Next == nullptr || + Changes[I].Tok->Next->isTrailingComment(); + + if (LineIsEmptyCase) { + if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) { + MinEmptyCaseColumn = + std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn); + } else { + MinEmptyCaseColumn = + std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn + 2); + } + } + } + + if (!Matches(Changes[I])) + continue; + + if (LineIsEmptyCase) + continue; + + FoundMatchOnLine = true; + + if (StartOfSequence == 0) + StartOfSequence = I; + + EndOfSequence = I + 1; + + MinColumn = std::max(MinColumn, Changes[I].StartOfTokenColumn); + + // Allow empty case statements to push out our alignment. + MinColumn = std::max(MinColumn, MinEmptyCaseColumn); + } + + AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches, + Changes); +} + void WhitespaceManager::alignConsecutiveDeclarations() { if (!Style.AlignConsecutiveDeclarations.Enabled) return; Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -108,6 +108,7 @@ IO.mapOptional("AcrossComments", Value.AcrossComments); IO.mapOptional("AlignCompound", Value.AlignCompound); IO.mapOptional("PadOperators", Value.PadOperators); + IO.mapOptional("AlignCaseColons", Value.AlignCaseColons); } }; @@ -847,6 +848,8 @@ IO.mapOptional("AlignConsecutiveDeclarations", Style.AlignConsecutiveDeclarations); IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); + IO.mapOptional("AlignConsecutiveShortCaseStatements", + Style.AlignConsecutiveShortCaseStatements); IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); IO.mapOptional("AlignOperands", Style.AlignOperands); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); @@ -1321,6 +1324,7 @@ LLVMStyle.AlignConsecutiveBitFields = {}; LLVMStyle.AlignConsecutiveDeclarations = {}; LLVMStyle.AlignConsecutiveMacros = {}; + LLVMStyle.AlignConsecutiveShortCaseStatements = {}; LLVMStyle.AlignTrailingComments = {}; LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always; LLVMStyle.AlignTrailingComments.OverEmptyLines = 0; Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -241,10 +241,26 @@ /// bbb >>= 2; /// \endcode bool PadOperators; + /// Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + /// are aligned on the colon, or on the tokens after the colon. + /// \code + /// true: + /// case log::info : return "info:"; + /// case log::warning: return "warning:"; + /// default : return ""; + /// + /// false: + /// case log::info: return "info:"; + /// case log::warning: return "warning:"; + /// default: return ""; + /// \endcode + bool AlignCaseColons; bool operator==(const AlignConsecutiveStyle &R) const { return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines && AcrossComments == R.AcrossComments && - AlignCompound == R.AlignCompound && PadOperators == R.PadOperators; + AlignCompound == R.AlignCompound && + PadOperators == R.PadOperators && + AlignCaseColons == R.AlignCaseColons; } bool operator!=(const AlignConsecutiveStyle &R) const { return !(*this == R); @@ -295,6 +311,20 @@ /// \endcode /// \version 3.8 AlignConsecutiveStyle AlignConsecutiveDeclarations; + /// Style of aligning consecutive short case labels. + /// Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + /// + /// ``Consecutive`` will result in formattings like: + /// \code + /// case log::info: return "info:"; + /// case log::warning: return "warning:"; + /// default: return ""; + /// \endcode + /// + /// Empty case statements will currently break the alignment unless + /// ``AlignCaseColons`` is ``true``. + /// \version 17 + AlignConsecutiveStyle AlignConsecutiveShortCaseStatements; /// Different styles for aligning escaped newlines. enum EscapedNewlineAlignmentStyle : int8_t { @@ -4296,6 +4326,8 @@ AlignConsecutiveBitFields == R.AlignConsecutiveBitFields && AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignConsecutiveMacros == R.AlignConsecutiveMacros && + AlignConsecutiveShortCaseStatements == + R.AlignConsecutiveShortCaseStatements && AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -801,6 +801,8 @@ - Add ``BracedInitializerIndentWidth`` which can be used to configure the indentation level of the contents of braced init lists. - Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file. +- Add ``AlignConsecutiveShortCaseStatements`` which can be used to align case + labels in conjunction with ``AllowShortCaseLabelsOnASingleLine``. libclang -------- Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -408,6 +408,21 @@ a = 2; bbb >>= 2; + * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + are aligned on the colon, or on the tokens after the colon. + + .. code-block:: c++ + + true: + case log::info : return "info:"; + case log::warning: return "warning:"; + default : return ""; + + false: + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + .. _AlignConsecutiveBitFields: @@ -533,6 +548,21 @@ a = 2; bbb >>= 2; + * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + are aligned on the colon, or on the tokens after the colon. + + .. code-block:: c++ + + true: + case log::info : return "info:"; + case log::warning: return "warning:"; + default : return ""; + + false: + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + .. _AlignConsecutiveDeclarations: @@ -658,6 +688,21 @@ a = 2; bbb >>= 2; + * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + are aligned on the colon, or on the tokens after the colon. + + .. code-block:: c++ + + true: + case log::info : return "info:"; + case log::warning: return "warning:"; + default : return ""; + + false: + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + .. _AlignConsecutiveMacros: @@ -784,6 +829,164 @@ a = 2; bbb >>= 2; + * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + are aligned on the colon, or on the tokens after the colon. + + .. code-block:: c++ + + true: + case log::info : return "info:"; + case log::warning: return "warning:"; + default : return ""; + + false: + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + + +.. _AlignConsecutiveShortCaseStatements: + +**AlignConsecutiveShortCaseStatements** (``AlignConsecutiveStyle``) :versionbadge:`clang-format 17` :ref:`¶ <AlignConsecutiveShortCaseStatements>` + Style of aligning consecutive short case labels. + Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``. + + ``Consecutive`` will result in formattings like: + + .. code-block:: c++ + + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + + Empty case statements will currently break the alignment unless + ``AlignCaseColons`` is ``true``. + + Nested configuration flags: + + Alignment options. + + They can also be read as a whole for compatibility. The choices are: + - None + - Consecutive + - AcrossEmptyLines + - AcrossComments + - AcrossEmptyLinesAndComments + + For example, to align across empty lines and not across comments, either + of these work. + + .. code-block:: c++ + + AlignConsecutiveMacros: AcrossEmptyLines + + AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: false + + * ``bool Enabled`` Whether aligning is enabled. + + .. code-block:: c++ + + #define SHORT_NAME 42 + #define LONGER_NAME 0x007f + #define EVEN_LONGER_NAME (2) + #define foo(x) (x * x) + #define bar(y, z) (y + z) + + int a = 1; + int somelongname = 2; + double c = 3; + + int aaaa : 1; + int b : 12; + int ccc : 8; + + int aaaa = 12; + float b = 23; + std::string ccc; + + * ``bool AcrossEmptyLines`` Whether to align across empty lines. + + .. code-block:: c++ + + true: + int a = 1; + int somelongname = 2; + double c = 3; + + int d = 3; + + false: + int a = 1; + int somelongname = 2; + double c = 3; + + int d = 3; + + * ``bool AcrossComments`` Whether to align across comments. + + .. code-block:: c++ + + true: + int d = 3; + /* A comment. */ + double e = 4; + + false: + int d = 3; + /* A comment. */ + double e = 4; + + * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments + like ``+=`` are aligned along with ``=``. + + .. code-block:: c++ + + true: + a &= 2; + bbb = 2; + + false: + a &= 2; + bbb = 2; + + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment + operators are left-padded to the same length as long ones in order to + put all assignment operators to the right of the left hand side. + + .. code-block:: c++ + + true: + a >>= 2; + bbb = 2; + + a = 2; + bbb >>= 2; + + false: + a >>= 2; + bbb = 2; + + a = 2; + bbb >>= 2; + + * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels + are aligned on the colon, or on the tokens after the colon. + + .. code-block:: c++ + + true: + case log::info : return "info:"; + case log::warning: return "warning:"; + default : return ""; + + false: + case log::info: return "info:"; + case log::warning: return "warning:"; + default: return ""; + .. _AlignEscapedNewlines:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits