Working in a mixed environment of both vscode/vim with a team configured prettier configuration, this can leave clang-format and prettier fighting each other over the formatting of arrays, both simple arrays of elements.
This review aims to add some "control knobs" to the Json formatting in clang-format to help align the two tools so they can be used interchangeably.
This will allow simply arrays `[1, 2, 3]` to remain on a single line but will break those arrays based on context within that array.
Happy to change the name of the option (this is the third name I tried)
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D133589
@Mock
DataLoad loader;
+**BreakArrays** (``Boolean``) :versionbadge:`clang-format 16`
+ If ``true``, clang-format will always break after a Json array `[`
+ otherwise it will scan until the closing `]` to determine if it should add
+ newlines between elements (prettier compatible).
+
+ NOTE: This is currently only for formatting JSON.
+
+ .. code-block:: c++
+
+ true: false:
+ [ vs. [1, 2, 3, 4]
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+
**BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) :versionbadge:`clang-format 3.6`
The way to wrap binary operators.
/// \version 3.7
bool BinPackParameters;
+ /// If ``true``, clang-format will always break after a Json array `[`
+ /// otherwise it will scan until the closing `]` to determine if it should add
+ /// newlines between elements (prettier compatible).
+ ///
+ /// NOTE: This is currently only for formatting JSON.
+ /// \code
+ /// true: false:
+ /// [ vs. [1, 2, 3, 4]
+ /// 1,
+ /// 2,
+ /// 3,
+ /// 4
+ /// ]
+ /// \endcode
+ /// \version 16
+ bool BreakArrays;
+
/// The style of wrapping parameters on the same line (bin-packed) or
/// on one line each.
enum BinPackStyle : int8_t {
AttributeMacros == R.AttributeMacros &&
BinPackArguments == R.BinPackArguments &&
BinPackParameters == R.BinPackParameters &&
+ BreakArrays == R.BreakArrays &&
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
IO.mapOptional("BreakAfterJavaFieldAnnotations",
Style.BreakAfterJavaFieldAnnotations);
+ IO.mapOptional("BreakArrays", Style.BreakArrays);
IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
IO.mapOptional("ColumnLimit", Style.ColumnLimit);
IO.mapOptional("CommentPragmas", Style.CommentPragmas);
LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
+ LLVMStyle.BreakArrays = true;
LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
LLVMStyle.FixNamespaceComments = true;
LLVMStyle.ForEachMacros.push_back("foreach");
// }
if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
return true;
- // Always break after a JSON array opener.
- // [
- // ]
- if (Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
- !Right.is(tok::r_square)) {
- return true;
+ // Always break after a JSON array opener based on BreakArrays.
+ if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
+ Right.isNot(tok::r_square)) ||
+ Left.is(tok::comma)) {
+ if (Right.is(tok::l_brace))
+ return true;
+ // scan to the right if an we see an object or an array inside
+ // then break.
+ for (const auto *Tok = &Right; Tok; Tok = Tok->Next) {
+ if (Tok->isOneOf(tok::l_brace, tok::l_square))
+ return true;
+ if (Tok->isOneOf(tok::r_brace, tok::r_square))
+ break;
+ }
+ return Style.BreakArrays;
}
- // Always break after successive entries.
- // 1,
- // 2
- if (Left.is(tok::comma))
- return true;
}
// If the last token before a '}', ']', or ')' is a comma or a trailing
"]");
}
+TEST_F(FormatTestJson, JsonArrayOneLine) {
+ FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
+ Style.BreakArrays = false;
+ Style.SpacesInContainerLiterals = false;
+ verifyFormat("[]", Style);
+ verifyFormat("[1]", Style);
+ verifyFormat("[1, 2]", Style);
+ verifyFormat("[1, 2, 3]", Style);
+ verifyFormat("[1, 2, 3, 4]", Style);
+ verifyFormat("[1, 2, 3, 4, 5]", Style);
+
+ verifyFormat("[\n"
+ " 1,\n"
+ " 2,\n"
+ " {\n"
+ " A: 1\n"
+ " }\n"
+ "]",
+ Style);
+}
+
TEST_F(FormatTestJson, JsonNoStringSplit) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
Style.IndentWidth = 4;