ClangFormat: Tweak dummy text for consecutive empty lines

If empty lines follow each other it makes sense to use
the empty comment as dummy text for all but the last one of them.

This prevents increasing indentation lengths after if (foo) when
there are multiple new empty lines inserted.

Change-Id: I4c948161b674b3af0a131bfb85e7a45a80ed3fb0
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ivan Donchevskii
2019-03-12 10:27:19 +01:00
parent 3017ee23e5
commit 5333331362
2 changed files with 75 additions and 10 deletions

View File

@@ -154,20 +154,31 @@ CharacterContext characterContext(const QTextBlock &currentBlock,
const QTextBlock &previousNonEmptyBlock)
{
const QString prevLineText = previousNonEmptyBlock.text().trimmed();
const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
if (prevLineText.endsWith(',')) {
const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
// We don't need to add comma in case it's the last argument.
if (firstNonWhitespaceChar == '}' || firstNonWhitespaceChar == ')')
return CharacterContext::LastAfterComma;
return CharacterContext::AfterComma;
}
if (prevLineText.endsWith(';') || prevLineText.endsWith('{') || prevLineText.endsWith('}'))
if (prevLineText.endsWith(';') || prevLineText.endsWith('{') || prevLineText.endsWith('}')
|| firstNonWhitespaceChar == QChar::Null) {
return CharacterContext::NewStatement;
}
return CharacterContext::Continuation;
}
bool nextBlockExistsAndEmpty(const QTextBlock &currentBlock)
{
QTextBlock nextBlock = currentBlock.next();
if (!nextBlock.isValid() || nextBlock.position() == currentBlock.position())
return false;
return nextBlock.text().trimmed().isEmpty();
}
// Add extra text in case of the empty line or the line starting with ')'.
// Track such extra pieces of text in isInsideModifiedLine().
int forceIndentWithExtraText(QByteArray &buffer,
@@ -192,10 +203,15 @@ int forceIndentWithExtraText(QByteArray &buffer,
&& blockText.at(firstNonWhitespace) == '}';
int extraLength = 0;
if (firstNonWhitespace < 0 || closingParenBlock || closingBraceBlock) {
QByteArray dummyText;
if (firstNonWhitespace < 0 && charContext != CharacterContext::Unknown
&& nextBlockExistsAndEmpty(block)) {
// If the next line is also empty it's safer to use a comment line.
dummyText = "//";
} else if (firstNonWhitespace < 0 || closingParenBlock || closingBraceBlock) {
if (charContext == CharacterContext::LastAfterComma) {
charContext = CharacterContext::AfterComma;
} else if (charContext == CharacterContext::Unknown) {
} else if (charContext == CharacterContext::Unknown || firstNonWhitespace >= 0) {
QTextBlock lastBlock = reverseFindLastEmptyBlock(block);
if (lastBlock.position() > 0)
lastBlock = lastBlock.previous();
@@ -204,7 +220,6 @@ int forceIndentWithExtraText(QByteArray &buffer,
charContext = characterContext(block, lastBlock);
}
QByteArray dummyText;
switch (charContext) {
case CharacterContext::Unknown:
QTC_ASSERT(false, return 0;);
@@ -223,11 +238,11 @@ int forceIndentWithExtraText(QByteArray &buffer,
dummyText = "&& a";
break;
}
buffer.insert(utf8Offset, dummyText);
extraLength += dummyText.length();
}
buffer.insert(utf8Offset, dummyText);
extraLength += dummyText.length();
if (secondTry) {
int nextLinePos = buffer.indexOf('\n', utf8Offset);
if (nextLinePos < 0)

View File

@@ -119,14 +119,14 @@ TEST_F(ClangFormat, IndentBasicFile)
TEST_F(ClangFormat, IndentEmptyLine)
{
insertLines({"int main",
insertLines({"int main()",
"{",
"",
"}"});
indenter.indent(cursor, QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("int main",
ASSERT_THAT(documentLines(), ElementsAre("int main()",
"{",
" ",
"}"));
@@ -441,6 +441,56 @@ TEST_F(ClangFormat, DoNotIndentClosingBraceAfterSemicolon)
"}"));
}
TEST_F(ClangFormat, SameIndentAfterSecondNewLineAfterIf)
{
insertLines({"if (a)",
" ",
""});
indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("if (a)",
" ",
" "));
}
TEST_F(ClangFormat, IndentAfterNewLineInsideIfWithFunctionCall)
{
insertLines({"if (foo()",
")"});
indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("if (foo()",
" )"));
}
TEST_F(ClangFormat, SameIndentAfterSecondNewLineInsideIfWithFunctionCall)
{
insertLines({"if (foo()",
" ",
")"});
indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("if (foo()",
" ",
" )"));
}
TEST_F(ClangFormat, SameIndentsOnNewLinesAfterComments)
{
insertLines({"namespace {} //comment",
"",
""});
indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("namespace {} //comment",
"",
""));
}
TEST_F(ClangFormat, IndentFunctionBodyButNotFormatBeforeIt)
{
insertLines({"int foo(int a, int b,",