diff --git a/src/libs/utils/textutils.h b/src/libs/utils/textutils.h index ae088a54ca7..d10f974dbec 100644 --- a/src/libs/utils/textutils.h +++ b/src/libs/utils/textutils.h @@ -36,6 +36,23 @@ QT_FORWARD_DECLARE_CLASS(QTextCursor) namespace Utils { namespace Text { +struct Replacement +{ + Replacement() = default; + Replacement(int offset, int length, const QString &text) + : offset(offset) + , length(length) + , text(text) + {} + + int offset = -1; + int length = -1; + QString text; + + bool isValid() const { return offset >= 0 && length >= 0; } +}; +using Replacements = std::vector; + // line is 1-based, column is 1-based QTCREATOR_UTILS_EXPORT bool convertPosition(const QTextDocument *document, int pos, diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 95c11bcd621..547c4490877 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -311,11 +311,11 @@ bool isInsideDummyTextInLine(const QString &originalLine, const QString &modifie || !modifiedLine.startsWith(originalLine)); } -TextEditor::Replacements utf16Replacements(const QTextDocument *doc, - const QByteArray &utf8Buffer, - const clang::tooling::Replacements &replacements) +Utils::Text::Replacements utf16Replacements(const QTextDocument *doc, + const QByteArray &utf8Buffer, + const clang::tooling::Replacements &replacements) { - TextEditor::Replacements convertedReplacements; + Utils::Text::Replacements convertedReplacements; convertedReplacements.reserve(replacements.size()); for (const clang::tooling::Replacement &replacement : replacements) { @@ -349,14 +349,14 @@ TextEditor::Replacements utf16Replacements(const QTextDocument *doc, return convertedReplacements; } -void applyReplacements(QTextDocument *doc, const TextEditor::Replacements &replacements) +void applyReplacements(QTextDocument *doc, const Utils::Text::Replacements &replacements) { if (replacements.empty()) return; int fullOffsetShift = 0; QTextCursor editCursor(doc); - for (const TextEditor::Replacement &replacement : replacements) { + for (const Utils::Text::Replacement &replacement : replacements) { editCursor.setPosition(replacement.offset + fullOffsetShift); editCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, @@ -376,7 +376,7 @@ QString selectedLines(QTextDocument *doc, const QTextBlock &startBlock, const QT - startBlock.position() - 1)); } -int indentationForBlock(const TextEditor::Replacements &toReplace, +int indentationForBlock(const Utils::Text::Replacements &toReplace, const QByteArray &buffer, const QTextBlock ¤tBlock) { @@ -385,7 +385,7 @@ int indentationForBlock(const TextEditor::Replacements &toReplace, currentBlock.blockNumber() + 1); auto replacementIt = std::find_if(toReplace.begin(), toReplace.end(), - [utf8Offset](const TextEditor::Replacement &replacement) { + [utf8Offset](const Utils::Text::Replacement &replacement) { return replacement.offset == utf8Offset - 1; }); if (replacementIt == toReplace.end()) @@ -442,21 +442,21 @@ ClangFormatBaseIndenter::ClangFormatBaseIndenter(QTextDocument *doc) : TextEditor::Indenter(doc) {} -TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer, - const QTextBlock &startBlock, - const QTextBlock &endBlock, - int cursorPositionInEditor, - ReplacementsToKeep replacementsToKeep, - const QChar &typedChar, - bool secondTry) const +Utils::Text::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer, + const QTextBlock &startBlock, + const QTextBlock &endBlock, + int cursorPositionInEditor, + ReplacementsToKeep replacementsToKeep, + const QChar &typedChar, + bool secondTry) const { - QTC_ASSERT(replacementsToKeep != ReplacementsToKeep::All, return TextEditor::Replacements()); + QTC_ASSERT(replacementsToKeep != ReplacementsToKeep::All, return Utils::Text::Replacements()); clang::format::FormatStyle style = styleForFile(); QByteArray originalBuffer = buffer; int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, startBlock.blockNumber() + 1); - QTC_ASSERT(utf8Offset >= 0, return TextEditor::Replacements();); + QTC_ASSERT(utf8Offset >= 0, return Utils::Text::Replacements();); int utf8Length = selectedLines(m_doc, startBlock, endBlock).toUtf8().size(); int rangeStart = 0; @@ -511,11 +511,11 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer return utf16Replacements(m_doc, buffer, filtered); } -TextEditor::Replacements ClangFormatBaseIndenter::format( +Utils::Text::Replacements ClangFormatBaseIndenter::format( const TextEditor::RangesInLines &rangesInLines) { if (rangesInLines.empty()) - return TextEditor::Replacements(); + return Utils::Text::Replacements(); const QByteArray buffer = m_doc->toPlainText().toUtf8(); std::vector ranges; @@ -541,7 +541,7 @@ TextEditor::Replacements ClangFormatBaseIndenter::format( auto changedCode = clang::tooling::applyAllReplacements(buffer.data(), clangReplacements); QTC_ASSERT(changedCode, { qDebug() << QString::fromStdString(llvm::toString(changedCode.takeError())); - return TextEditor::Replacements(); + return Utils::Text::Replacements(); }); ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges); @@ -553,21 +553,21 @@ TextEditor::Replacements ClangFormatBaseIndenter::format( &status); clangReplacements = clangReplacements.merge(formatReplacements); - const TextEditor::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements); + const Utils::Text::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements); applyReplacements(m_doc, toReplace); return toReplace; } -TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock, - const QTextBlock &endBlock, - const QChar &typedChar, - int cursorPositionInEditor) +Utils::Text::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock, + const QTextBlock &endBlock, + const QChar &typedChar, + int cursorPositionInEditor) { if (typedChar != QChar::Null && cursorPositionInEditor > 0 && m_doc->characterAt(cursorPositionInEditor - 1) == typedChar && doNotIndentInContext(m_doc, cursorPositionInEditor - 1)) { - return TextEditor::Replacements(); + return Utils::Text::Replacements(); } startBlock = reverseFindLastEmptyBlock(startBlock); @@ -650,10 +650,10 @@ int ClangFormatBaseIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings & /*tabSettings*/, int cursorPositionInEditor) { - TextEditor::Replacements toReplace = indentsFor(block, - block, - QChar::Null, - cursorPositionInEditor); + Utils::Text::Replacements toReplace = indentsFor(block, + block, + QChar::Null, + cursorPositionInEditor); if (toReplace.empty()) return -1; @@ -669,10 +669,10 @@ TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks( TextEditor::IndentationForBlock ret; if (blocks.isEmpty()) return ret; - TextEditor::Replacements toReplace = indentsFor(blocks.front(), - blocks.back(), - QChar::Null, - cursorPositionInEditor); + Utils::Text::Replacements toReplace = indentsFor(blocks.front(), + blocks.back(), + QChar::Null, + cursorPositionInEditor); const QByteArray buffer = m_doc->toPlainText().toUtf8(); for (const QTextBlock &block : blocks) diff --git a/src/plugins/clangformat/clangformatbaseindenter.h b/src/plugins/clangformat/clangformatbaseindenter.h index 9f58dd590b2..00dc3e9c7a6 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.h +++ b/src/plugins/clangformat/clangformatbaseindenter.h @@ -53,7 +53,7 @@ public: void autoIndent(const QTextCursor &cursor, const TextEditor::TabSettings &tabSettings, int cursorPositionInEditor = -1) override; - TextEditor::Replacements format(const TextEditor::RangesInLines &rangesInLines) override; + Utils::Text::Replacements format(const TextEditor::RangesInLines &rangesInLines) override; void indentBlock(const QTextBlock &block, const QChar &typedChar, @@ -78,17 +78,17 @@ private: const QTextBlock &endBlock, const QChar &typedChar, int cursorPositionInEditor); - TextEditor::Replacements indentsFor(QTextBlock startBlock, - const QTextBlock &endBlock, - const QChar &typedChar, - int cursorPositionInEditor); - TextEditor::Replacements replacements(QByteArray buffer, - const QTextBlock &startBlock, - const QTextBlock &endBlock, - int cursorPositionInEditor, - ReplacementsToKeep replacementsToKeep, - const QChar &typedChar = QChar::Null, - bool secondTry = false) const; + Utils::Text::Replacements indentsFor(QTextBlock startBlock, + const QTextBlock &endBlock, + const QChar &typedChar, + int cursorPositionInEditor); + Utils::Text::Replacements replacements(QByteArray buffer, + const QTextBlock &startBlock, + const QTextBlock &endBlock, + int cursorPositionInEditor, + ReplacementsToKeep replacementsToKeep, + const QChar &typedChar = QChar::Null, + bool secondTry = false) const; }; } // namespace ClangFormat diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp index e32553f9760..345a40d8543 100644 --- a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp +++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp @@ -150,7 +150,7 @@ void FixitsRefactoringFile::format(TextEditor::Indenter &indenter, const int end = doc->findBlock(op.pos + op.length).blockNumber() + 1; ranges.push_back({start, end}); } - const Replacements replacements = indenter.format(ranges); + const Text::Replacements replacements = indenter.format(ranges); if (replacements.empty()) return; @@ -201,7 +201,7 @@ void FixitsRefactoringFile::shiftAffectedReplacements(const ReplacementOperation } bool FixitsRefactoringFile::hasIntersection(const QString &fileName, - const Replacements &replacements, + const Text::Replacements &replacements, int startIndex) const { for (int i = startIndex; i < m_replacementOperations.size(); ++i) { @@ -212,7 +212,7 @@ bool FixitsRefactoringFile::hasIntersection(const QString &fileName, // Usually the number of replacements is from 1 to 3. if (std::any_of(replacements.begin(), replacements.end(), - [¤t](const Replacement &replacement) { + [¤t](const Text::Replacement &replacement) { return replacement.offset + replacement.length > current.pos && replacement.offset < current.pos + current.length; })) { @@ -224,7 +224,7 @@ bool FixitsRefactoringFile::hasIntersection(const QString &fileName, } void FixitsRefactoringFile::shiftAffectedReplacements(const QString &fileName, - const Replacements &replacements, + const Text::Replacements &replacements, int startIndex) { for (int i = startIndex; i < m_replacementOperations.size(); ++i) { diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.h b/src/plugins/clangtools/clangfixitsrefactoringchanges.h index cf715b34872..e4692b22cc7 100644 --- a/src/plugins/clangtools/clangfixitsrefactoringchanges.h +++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.h @@ -72,10 +72,10 @@ private: const ReplacementOperations &operationsForFile, int firstOperationIndex); void shiftAffectedReplacements(const QString &fileName, - const TextEditor::Replacements &replacements, + const Utils::Text::Replacements &replacements, int startIndex); bool hasIntersection(const QString &fileName, - const TextEditor::Replacements &replacements, + const Utils::Text::Replacements &replacements, int startIndex) const; QString m_filePath; diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h index f7f2d1da3a2..7248d1721c9 100644 --- a/src/plugins/texteditor/indenter.h +++ b/src/plugins/texteditor/indenter.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -43,21 +44,6 @@ class TabSettings; using IndentationForBlock = QMap; -class Replacement -{ -public: - Replacement(int offset, int length, const QString &text) - : offset(offset) - , length(length) - , text(text) - {} - int offset; - int length; - QString text; -}; - -using Replacements = std::vector; - class RangeInLines { public: @@ -100,9 +86,9 @@ public: } // By default just calls indent with default settings. - virtual Replacements format(const RangesInLines & /*rangesInLines*/) + virtual Utils::Text::Replacements format(const RangesInLines & /*rangesInLines*/) { - return Replacements(); + return Utils::Text::Replacements(); } virtual bool formatOnSave() const { return false; }