forked from qt-creator/qt-creator
ClangFormat: Try to add ')' in case of no indentation
clang-format has problems with unfinished () blocks. In case when the first formatting try failed it makes sense to try again after appending ')' to the end of the line. In case it does not solve the initial issue it does not make it worse anyways. Examples where this approach helps: if (a<press CR> or if (a <press CR>&& b Change-Id: Iacc35af79a7b19c1d512d141423d7549788a1a22 Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -163,32 +163,46 @@ int previousEmptyLinesLength(const QTextBlock ¤tBlock)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modifyToIndentEmptyLines(QByteArray &buffer, int offset, int &length, const QTextBlock &block)
|
void modifyToIndentEmptyLines(
|
||||||
|
QByteArray &buffer, int offset, int &length, const QTextBlock &block, bool secondTry)
|
||||||
{
|
{
|
||||||
const QString blockText = block.text().trimmed();
|
const QString blockText = block.text().trimmed();
|
||||||
const bool closingParenBlock = blockText.startsWith(')');
|
const bool closingParenBlock = blockText.startsWith(')');
|
||||||
if (!blockText.isEmpty() && !closingParenBlock)
|
if (blockText.isEmpty() || closingParenBlock) {
|
||||||
return;
|
//This extra text works for the most cases.
|
||||||
|
QByteArray dummyText("a;");
|
||||||
|
|
||||||
//This extra text works for the most cases.
|
// Search for previous character
|
||||||
QByteArray extraText("a;");
|
QTextBlock prevBlock = block.previous();
|
||||||
|
bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
|
||||||
// Search for previous character
|
while (prevBlockIsEmpty) {
|
||||||
QTextBlock prevBlock = block.previous();
|
prevBlock = prevBlock.previous();
|
||||||
while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty())
|
prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
|
||||||
prevBlock = prevBlock.previous();
|
}
|
||||||
if (prevBlock.text().endsWith(','))
|
|
||||||
extraText = "int a,";
|
|
||||||
|
|
||||||
if (closingParenBlock) {
|
|
||||||
if (prevBlock.text().endsWith(','))
|
if (prevBlock.text().endsWith(','))
|
||||||
extraText = "int a";
|
dummyText = "int a";
|
||||||
else
|
|
||||||
extraText = "&& a";
|
if (closingParenBlock) {
|
||||||
|
if (prevBlock.text().endsWith(','))
|
||||||
|
dummyText = "int a";
|
||||||
|
else
|
||||||
|
dummyText = "&& a";
|
||||||
|
}
|
||||||
|
|
||||||
|
length += dummyText.length();
|
||||||
|
buffer.insert(offset, dummyText);
|
||||||
}
|
}
|
||||||
|
|
||||||
length += extraText.length();
|
if (secondTry) {
|
||||||
buffer.insert(offset, extraText);
|
int nextLinePos = buffer.indexOf('\n', offset);
|
||||||
|
if (nextLinePos > 0) {
|
||||||
|
// If first try was not successful try to put ')' in the end of the line to close possibly
|
||||||
|
// unclosed parentheses.
|
||||||
|
// TODO: Does it help to add different endings depending on the context?
|
||||||
|
buffer.insert(nextLinePos, ')');
|
||||||
|
length += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int kMaxLinesFromCurrentBlock = 200;
|
static const int kMaxLinesFromCurrentBlock = 200;
|
||||||
@@ -253,11 +267,13 @@ QtReplacements replacements(const Utils::FileName &fileName,
|
|||||||
int utf8Length,
|
int utf8Length,
|
||||||
const QTextBlock &block,
|
const QTextBlock &block,
|
||||||
const QChar &typedChar = QChar::Null,
|
const QChar &typedChar = QChar::Null,
|
||||||
bool onlyIndention = true)
|
bool onlyIndention = true,
|
||||||
|
bool secondTry = false)
|
||||||
{
|
{
|
||||||
FormatStyle style = styleForFile(fileName);
|
FormatStyle style = styleForFile(fileName);
|
||||||
|
|
||||||
int blockOffsetUtf8 = utf8Offset;
|
int originalOffsetUtf8 = utf8Offset;
|
||||||
|
int originalLengthUtf8 = utf8Length;
|
||||||
QByteArray originalBuffer = buffer;
|
QByteArray originalBuffer = buffer;
|
||||||
|
|
||||||
int extraOffset = 0;
|
int extraOffset = 0;
|
||||||
@@ -282,27 +298,40 @@ QtReplacements replacements(const Utils::FileName &fileName,
|
|||||||
|
|
||||||
adjustFormatStyleForLineBreak(style);
|
adjustFormatStyleForLineBreak(style);
|
||||||
if (typedChar == QChar::Null)
|
if (typedChar == QChar::Null)
|
||||||
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block);
|
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset),
|
std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset),
|
||||||
static_cast<unsigned int>(utf8Length)}};
|
static_cast<unsigned int>(utf8Length)}};
|
||||||
FormattingAttemptStatus status;
|
FormattingAttemptStatus status;
|
||||||
|
|
||||||
ClangReplacements replacements = reformat(style,
|
ClangReplacements clangReplacements = reformat(style,
|
||||||
buffer.data(),
|
buffer.data(),
|
||||||
ranges,
|
ranges,
|
||||||
fileName.toString().toStdString(),
|
fileName.toString().toStdString(),
|
||||||
&status);
|
&status);
|
||||||
|
|
||||||
if (!status.FormatComplete)
|
if (!status.FormatComplete)
|
||||||
QtReplacements();
|
QtReplacements();
|
||||||
|
|
||||||
const ClangReplacements filtered = filteredReplacements(replacements,
|
const ClangReplacements filtered = filteredReplacements(clangReplacements,
|
||||||
utf8Offset,
|
utf8Offset,
|
||||||
extraOffset,
|
extraOffset,
|
||||||
onlyIndention);
|
onlyIndention);
|
||||||
return utf16Replacements(block, blockOffsetUtf8, originalBuffer, filtered);
|
|
||||||
|
const bool canTryAgain = onlyIndention && typedChar == QChar::Null && !secondTry;
|
||||||
|
if (canTryAgain && filtered.empty()) {
|
||||||
|
return replacements(fileName,
|
||||||
|
originalBuffer,
|
||||||
|
originalOffsetUtf8,
|
||||||
|
originalLengthUtf8,
|
||||||
|
block,
|
||||||
|
typedChar,
|
||||||
|
onlyIndention,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return utf16Replacements(block, originalOffsetUtf8, originalBuffer, filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyReplacements(const QTextBlock &block, const QtReplacements &replacements)
|
void applyReplacements(const QTextBlock &block, const QtReplacements &replacements)
|
||||||
|
|||||||
Reference in New Issue
Block a user