Skip to content

Commit d989c24

Browse files
authored
[clang-format] Add RemoveEmptyLinesInUnwrappedLines option (#112325)
Fixes #111340.
1 parent 67f576f commit d989c24

File tree

7 files changed

+138
-3
lines changed

7 files changed

+138
-3
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5505,6 +5505,31 @@ the configuration (without a prefix: ``Auto``).
55055505
}
55065506
}
55075507

5508+
.. _RemoveEmptyLinesInUnwrappedLines:
5509+
5510+
**RemoveEmptyLinesInUnwrappedLines** (``Boolean``) :versionbadge:`clang-format 20` :ref:`<RemoveEmptyLinesInUnwrappedLines>`
5511+
Remove empty lines within unwrapped lines.
5512+
5513+
.. code-block:: c++
5514+
5515+
false: true:
5516+
5517+
int c vs. int c = a + b;
5518+
5519+
= a + b;
5520+
5521+
enum : unsigned vs. enum : unsigned {
5522+
AA = 0,
5523+
{ BB
5524+
AA = 0, } myEnum;
5525+
BB
5526+
} myEnum;
5527+
5528+
while ( vs. while (true) {
5529+
}
5530+
true) {
5531+
}
5532+
55085533
.. _RemoveParentheses:
55095534

55105535
**RemoveParentheses** (``RemoveParenthesesStyle``) :versionbadge:`clang-format 17` :ref:`<RemoveParentheses>`

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,10 @@ clang-format
699699
- Adds ``BreakBinaryOperations`` option.
700700
- Adds ``TemplateNames`` option.
701701
- Adds ``AlignFunctionDeclarations`` option to ``AlignConsecutiveDeclarations``.
702-
- Adds ``IndentOnly`` suboption to ``ReflowComments`` to fix the indentation of multi-line comments
703-
without touching their contents, renames ``false`` to ``Never``, and ``true`` to ``Always``.
702+
- Adds ``IndentOnly`` suboption to ``ReflowComments`` to fix the indentation of
703+
multi-line comments without touching their contents, renames ``false`` to
704+
``Never``, and ``true`` to ``Always``.
705+
- Adds ``RemoveEmptyLinesInUnwrappedLines`` option.
704706

705707
libclang
706708
--------

clang/include/clang/Format/Format.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,6 +3938,29 @@ struct FormatStyle {
39383938
/// \version 14
39393939
bool RemoveBracesLLVM;
39403940

3941+
/// Remove empty lines within unwrapped lines.
3942+
/// \code
3943+
/// false: true:
3944+
///
3945+
/// int c vs. int c = a + b;
3946+
///
3947+
/// = a + b;
3948+
///
3949+
/// enum : unsigned vs. enum : unsigned {
3950+
/// AA = 0,
3951+
/// { BB
3952+
/// AA = 0, } myEnum;
3953+
/// BB
3954+
/// } myEnum;
3955+
///
3956+
/// while ( vs. while (true) {
3957+
/// }
3958+
/// true) {
3959+
/// }
3960+
/// \endcode
3961+
/// \version 20
3962+
bool RemoveEmptyLinesInUnwrappedLines;
3963+
39413964
/// Types of redundant parentheses to remove.
39423965
enum RemoveParenthesesStyle : int8_t {
39433966
/// Do not remove parentheses.
@@ -5232,6 +5255,8 @@ struct FormatStyle {
52325255
RawStringFormats == R.RawStringFormats &&
52335256
ReferenceAlignment == R.ReferenceAlignment &&
52345257
RemoveBracesLLVM == R.RemoveBracesLLVM &&
5258+
RemoveEmptyLinesInUnwrappedLines ==
5259+
R.RemoveEmptyLinesInUnwrappedLines &&
52355260
RemoveParentheses == R.RemoveParentheses &&
52365261
RemoveSemicolon == R.RemoveSemicolon &&
52375262
RequiresClausePosition == R.RequiresClausePosition &&

clang/lib/Format/Format.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,8 @@ template <> struct MappingTraits<FormatStyle> {
11041104
IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
11051105
IO.mapOptional("ReflowComments", Style.ReflowComments);
11061106
IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
1107+
IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
1108+
Style.RemoveEmptyLinesInUnwrappedLines);
11071109
IO.mapOptional("RemoveParentheses", Style.RemoveParentheses);
11081110
IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
11091111
IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
@@ -1582,6 +1584,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
15821584
LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
15831585
LLVMStyle.ReflowComments = FormatStyle::RCS_Always;
15841586
LLVMStyle.RemoveBracesLLVM = false;
1587+
LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false;
15851588
LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave;
15861589
LLVMStyle.RemoveSemicolon = false;
15871590
LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine;

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5509,8 +5509,10 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
55095509
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
55105510
const FormatToken &Right) const {
55115511
const FormatToken &Left = *Right.Previous;
5512-
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
5512+
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
5513+
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
55135514
return true;
5515+
}
55145516

55155517
if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
55165518
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&

clang/unittests/Format/ConfigParseTest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
184184
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
185185
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
186186
CHECK_PARSE_BOOL(RemoveBracesLLVM);
187+
CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines);
187188
CHECK_PARSE_BOOL(RemoveSemicolon);
188189
CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
189190
CHECK_PARSE_BOOL(SpacesInSquareBrackets);

clang/unittests/Format/FormatTest.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28135,6 +28135,83 @@ TEST_F(FormatTest, BreakBinaryOperations) {
2813528135
Style);
2813628136
}
2813728137

28138+
TEST_F(FormatTest, RemovesEmptyLinesInUnwrappedLines) {
28139+
auto Style = getLLVMStyle();
28140+
Style.RemoveEmptyLinesInUnwrappedLines = true;
28141+
28142+
verifyFormat("int c = a + b;",
28143+
"int c\n"
28144+
"\n"
28145+
" = a + b;",
28146+
Style);
28147+
28148+
verifyFormat("enum : unsigned { AA = 0, BB } myEnum;",
28149+
"enum : unsigned\n"
28150+
"\n"
28151+
"{\n"
28152+
" AA = 0,\n"
28153+
" BB\n"
28154+
"} myEnum;",
28155+
Style);
28156+
28157+
verifyFormat("class B : public E {\n"
28158+
"private:\n"
28159+
"};",
28160+
"class B : public E\n"
28161+
"\n"
28162+
"{\n"
28163+
"private:\n"
28164+
"};",
28165+
Style);
28166+
28167+
verifyFormat(
28168+
"struct AAAAAAAAAAAAAAA test[3] = {{56, 23, \"hello\"}, {7, 5, \"!!\"}};",
28169+
"struct AAAAAAAAAAAAAAA test[3] = {{56,\n"
28170+
"\n"
28171+
" 23, \"hello\"},\n"
28172+
" {7, 5, \"!!\"}};",
28173+
Style);
28174+
28175+
verifyFormat("int myFunction(int aaaaaaaaaaaaa, int ccccccccccccc, int d);",
28176+
"int myFunction(\n"
28177+
"\n"
28178+
" int aaaaaaaaaaaaa,\n"
28179+
"\n"
28180+
" int ccccccccccccc, int d);",
28181+
Style);
28182+
28183+
verifyFormat("switch (e) {\n"
28184+
"case 1:\n"
28185+
" return e;\n"
28186+
"case 2:\n"
28187+
" return 2;\n"
28188+
"}",
28189+
"switch (\n"
28190+
"\n"
28191+
" e) {\n"
28192+
"case 1:\n"
28193+
" return e;\n"
28194+
"case 2:\n"
28195+
" return 2;\n"
28196+
"}",
28197+
Style);
28198+
28199+
verifyFormat("while (true) {\n"
28200+
"}",
28201+
"while (\n"
28202+
"\n"
28203+
" true) {\n"
28204+
"}",
28205+
Style);
28206+
28207+
verifyFormat("void loooonFunctionIsVeryLongButNotAsLongAsJavaTypeNames(\n"
28208+
" std::map<int, std::string> *outputMap);",
28209+
"void loooonFunctionIsVeryLongButNotAsLongAsJavaTypeNames\n"
28210+
"\n"
28211+
" (std::map<int, std::string> *outputMap);",
28212+
Style);
28213+
}
28214+
2813828215
} // namespace
2813928216
} // namespace test
2814028217
} // namespace format

0 commit comments

Comments
 (0)