From 61fc1fd45262a8f78c49bc2fb2a7777bdfa02845 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 30 Jun 2023 16:03:52 +0200 Subject: [PATCH] ClangFormat: remove identical prefix and suffix from replacement text To reduce the changes done to the document iterate from the start and back of the replacement text and check whether the document already contains the proposed changes. This also fixes the misplaced snippet part in the if else snippet. Change-Id: I4519ed101cc03e7c49b3a9b775087361c3fd158d Reviewed-by: Christian Kandeler Reviewed-by: --- .../clangformat/clangformatbaseindenter.cpp | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 76979bda123..cf04958d28a 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -382,16 +382,37 @@ Utils::Text::Replacements utf16Replacements(const QTextDocument *doc, continue; lineColUtf16.column = std::min(lineColUtf16.column, int(lineText.length())); - const int utf16Offset = Utils::Text::positionInText(doc, - lineColUtf16.line, - lineColUtf16.column + 1); - const int utf16Length = QString::fromUtf8( - utf8Buffer.mid(static_cast(replacement.getOffset()), - static_cast(replacement.getLength()))) - .size(); - convertedReplacements.emplace_back(utf16Offset, - utf16Length, - QString::fromStdString(replacement.getReplacementText().str())); + int utf16Offset = Utils::Text::positionInText(doc, + lineColUtf16.line, + lineColUtf16.column + 1); + int utf16Length = QString::fromUtf8( + utf8Buffer.mid(static_cast(replacement.getOffset()), + static_cast(replacement.getLength()))) + .size(); + + QString replacementText = QString::fromStdString(replacement.getReplacementText().str()); + auto sameCharAt = [&](int replacementOffset) { + if (replacementText.size() <= replacementOffset || replacementOffset < 0) + return false; + const QChar docChar = doc->characterAt(utf16Offset + replacementOffset); + const QChar replacementChar = replacementText.at(replacementOffset); + return docChar == replacementChar + || (docChar == QChar::ParagraphSeparator && replacementChar == '\n'); + }; + // remove identical prefix from replacement text + while (sameCharAt(0)) { + ++utf16Offset; + --utf16Length; + replacementText = replacementText.mid(1); + } + // remove identical suffix from replacement text + while (sameCharAt(utf16Length - 1)) { + --utf16Length; + replacementText.chop(1); + } + + if (!replacementText.isEmpty() || utf16Length > 0) + convertedReplacements.emplace_back(utf16Offset, utf16Length, replacementText); } return convertedReplacements;