Author: djasper Date: Mon May 11 08:35:40 2015 New Revision: 236992 URL: http://llvm.org/viewvc/llvm-project?rev=236992&view=rev Log: clang-format: Improve column layout.
Specifically, calculate the deviation between the shortest and longest element (which is used to prevent excessive whitespace) per column, not overall. This automatically handles the corner cases of a single column and a single row so that the actualy implementation becomes simpler. Before: vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa, 2, bbbbbbbbbbbbbbbbbbbbbb, 3, cccccccccccccccccccccc}; After: vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa, 2, bbbbbbbbbbbbbbbbbbbbbb, 3, cccccccccccccccccccccc}; Modified: cfe/trunk/lib/Format/FormatToken.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/FormatToken.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.cpp?rev=236992&r1=236991&r2=236992&view=diff ============================================================================== --- cfe/trunk/lib/Format/FormatToken.cpp (original) +++ cfe/trunk/lib/Format/FormatToken.cpp Mon May 11 08:35:40 2015 @@ -150,9 +150,6 @@ void CommaSeparatedList::precomputeForma // trailing comments which are otherwise ignored for column alignment. SmallVector<unsigned, 8> EndOfLineItemLength; - unsigned MinItemLength = Style.ColumnLimit; - unsigned MaxItemLength = 0; - for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) { // Skip comments on their own line. while (ItemBegin->HasUnescapedNewline && ItemBegin->isTrailingComment()) @@ -179,8 +176,6 @@ void CommaSeparatedList::precomputeForma ItemEnd = Commas[i]; // The comma is counted as part of the item when calculating the length. ItemLengths.push_back(CodePointsBetween(ItemBegin, ItemEnd)); - MinItemLength = std::min(MinItemLength, ItemLengths.back()); - MaxItemLength = std::max(MaxItemLength, ItemLengths.back()); // Consume trailing comments so the are included in EndOfLineItemLength. if (ItemEnd->Next && !ItemEnd->Next->HasUnescapedNewline && @@ -197,19 +192,17 @@ void CommaSeparatedList::precomputeForma // If this doesn't have a nested list, we require at least 6 elements in order // create a column layout. If it has a nested list, column layout ensures one - // list element per line. If the difference between the shortest and longest - // element is too large, column layout would create too much whitespace. + // list element per line. if (Commas.size() < 5 || Token->NestingLevel != 0) return; // We can never place more than ColumnLimit / 3 items in a row (because of the // spaces and the comma). - unsigned MaxColumns = - MaxItemLength - MinItemLength > 10 ? 1 : Style.ColumnLimit / 3; - for (unsigned Columns = 1; Columns <= MaxColumns; ++Columns) { + for (unsigned Columns = 1; Columns <= Style.ColumnLimit / 3; ++Columns) { ColumnFormat Format; Format.Columns = Columns; Format.ColumnSizes.resize(Columns); + std::vector<unsigned> MinSizeInColumn(Columns, UINT_MAX); Format.LineCount = 1; bool HasRowWithSufficientColumns = false; unsigned Column = 0; @@ -221,9 +214,10 @@ void CommaSeparatedList::precomputeForma } if (Column == Columns - 1) HasRowWithSufficientColumns = true; - unsigned length = + unsigned Length = (Column == Columns - 1) ? EndOfLineItemLength[i] : ItemLengths[i]; - Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], length); + Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], Length); + MinSizeInColumn[Column] = std::min(MinSizeInColumn[Column], Length); ++Column; } // If all rows are terminated early (e.g. by trailing comments), we don't @@ -231,9 +225,19 @@ void CommaSeparatedList::precomputeForma if (!HasRowWithSufficientColumns) break; Format.TotalWidth = Columns - 1; // Width of the N-1 spaces. - for (unsigned i = 0; i < Columns; ++i) { + + for (unsigned i = 0; i < Columns; ++i) Format.TotalWidth += Format.ColumnSizes[i]; - } + + // Don't use this Format, if the difference between the longest and shortest + // element in a column exceeds a threshold to avoid excessive spaces. + if ([&] { + for (unsigned i = 0; i < Columns - 1; ++i) + if (Format.ColumnSizes[i] - MinSizeInColumn[i] > 10) + return true; + return false; + }()) + continue; // Ignore layouts that are bound to violate the column limit. if (Format.TotalWidth > Style.ColumnLimit) Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=236992&r1=236991&r2=236992&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Mon May 11 08:35:40 2015 @@ -6305,6 +6305,11 @@ TEST_F(FormatTest, FormatsBracedListsInC " \"aaaaaaaaaaaa\",\n" " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n" "};"); + verifyFormat("vector<int> x = {1, 2, 3, 4, aaaaaaaaaaaaaaaaa, 6};"); + verifyFormat("vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa,\n" + " 2, bbbbbbbbbbbbbbbbbbbbbb,\n" + " 3, cccccccccccccccccccccc};", + getLLVMStyleWithColumns(60)); // Trailing commas. verifyFormat("vector<int> x = {\n" _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits