forked from qt-creator/qt-creator
TextEditor: Fix quickfix formatting
... for e.g. function insertion. In some contexts, the insertion position is on the last line of some unrelated code (e.g. a preceding function implementation) and the inserted code starts with a newline. In that case, advance the position of the formatting cursor, so that we do not accidentally format the existing code. Fixes: QTCREATORBUG-30229 Change-Id: Id0be7f22e1797affa0602bb1d392a5e0802cbdcd Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -65,7 +65,7 @@ bool RefactoringFile::create(const QString &contents, bool reindent, bool openIn
|
|||||||
// Reindent the contents:
|
// Reindent the contents:
|
||||||
if (reindent) {
|
if (reindent) {
|
||||||
cursor.select(QTextCursor::Document);
|
cursor.select(QTextCursor::Document);
|
||||||
m_formattingCursors = {cursor};
|
m_formattingCursors = {{cursor, false}};
|
||||||
doFormatting();
|
doFormatting();
|
||||||
}
|
}
|
||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
@@ -298,26 +298,29 @@ void RefactoringFile::setupFormattingRanges(const QList<ChangeSet::EditOp> &repl
|
|||||||
switch (op.type()) {
|
switch (op.type()) {
|
||||||
case ChangeSet::EditOp::Replace:
|
case ChangeSet::EditOp::Replace:
|
||||||
case ChangeSet::EditOp::Insert:
|
case ChangeSet::EditOp::Insert:
|
||||||
case ChangeSet::EditOp::Remove:
|
case ChangeSet::EditOp::Remove: {
|
||||||
cursor.setKeepPositionOnInsert(true);
|
cursor.setKeepPositionOnInsert(true);
|
||||||
cursor.setPosition(op.pos1 + op.length1);
|
cursor.setPosition(op.pos1 + op.length1);
|
||||||
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
||||||
m_formattingCursors << cursor;
|
const bool advance = op.type() != ChangeSet::EditOp::Remove && !op.text().isEmpty()
|
||||||
|
&& op.text().front() == '\n';
|
||||||
|
m_formattingCursors << std::make_pair(cursor, advance);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ChangeSet::EditOp::Flip:
|
case ChangeSet::EditOp::Flip:
|
||||||
case ChangeSet::EditOp::Move:
|
case ChangeSet::EditOp::Move:
|
||||||
cursor.setKeepPositionOnInsert(true);
|
cursor.setKeepPositionOnInsert(true);
|
||||||
cursor.setPosition(op.pos1 + op.length1);
|
cursor.setPosition(op.pos1 + op.length1);
|
||||||
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
||||||
m_formattingCursors << cursor;
|
m_formattingCursors << std::make_pair(cursor, false);
|
||||||
cursor.setPosition(op.pos2 + op.length2);
|
cursor.setPosition(op.pos2 + op.length2);
|
||||||
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
||||||
m_formattingCursors << cursor;
|
m_formattingCursors << m_formattingCursors << std::make_pair(cursor, false);
|
||||||
break;
|
break;
|
||||||
case ChangeSet::EditOp::Copy:
|
case ChangeSet::EditOp::Copy:
|
||||||
cursor.setKeepPositionOnInsert(true);
|
cursor.setKeepPositionOnInsert(true);
|
||||||
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
||||||
m_formattingCursors << cursor;
|
m_formattingCursors << m_formattingCursors << std::make_pair(cursor, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,13 +351,15 @@ void RefactoringFile::doFormatting()
|
|||||||
QTC_ASSERT(document, return);
|
QTC_ASSERT(document, return);
|
||||||
QTC_ASSERT(indenter, return);
|
QTC_ASSERT(indenter, return);
|
||||||
|
|
||||||
Utils::sort(m_formattingCursors, [](const QTextCursor &tc1, const QTextCursor &tc2) {
|
for (auto &[formattingCursor, advance] : m_formattingCursors) {
|
||||||
return tc1.selectionStart() < tc2.selectionStart();
|
if (advance)
|
||||||
|
formattingCursor.setPosition(formattingCursor.position() + 1, QTextCursor::KeepAnchor);
|
||||||
|
}
|
||||||
|
Utils::sort(m_formattingCursors, [](const auto &tc1, const auto &tc2) {
|
||||||
|
return tc1.first.selectionStart() < tc2.first.selectionStart();
|
||||||
});
|
});
|
||||||
const int firstSelectedBlock = document->findBlock(m_formattingCursors.first().selectionStart())
|
|
||||||
.blockNumber();
|
|
||||||
static const QString clangFormatLineRemovalBlocker("// QTC_TEMP");
|
static const QString clangFormatLineRemovalBlocker("// QTC_TEMP");
|
||||||
for (const QTextCursor &formattingCursor : std::as_const(m_formattingCursors)) {
|
for (auto &[formattingCursor, _] : m_formattingCursors) {
|
||||||
const QTextBlock firstBlock = document->findBlock(formattingCursor.selectionStart());
|
const QTextBlock firstBlock = document->findBlock(formattingCursor.selectionStart());
|
||||||
const QTextBlock lastBlock = document->findBlock(formattingCursor.selectionEnd());
|
const QTextBlock lastBlock = document->findBlock(formattingCursor.selectionEnd());
|
||||||
QTextBlock b = firstBlock;
|
QTextBlock b = firstBlock;
|
||||||
@@ -368,7 +373,9 @@ void RefactoringFile::doFormatting()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QTextCursor &tc : std::as_const(m_formattingCursors))
|
const int firstSelectedBlock
|
||||||
|
= document->findBlock(m_formattingCursors.first().first.selectionStart()).blockNumber();
|
||||||
|
for (const auto &[tc, _] : std::as_const(m_formattingCursors))
|
||||||
indenter->autoIndent(tc, tabSettings);
|
indenter->autoIndent(tc, tabSettings);
|
||||||
|
|
||||||
for (QTextBlock b = document->findBlockByNumber(firstSelectedBlock);
|
for (QTextBlock b = document->findBlockByNumber(firstSelectedBlock);
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QTextDocument;
|
class QTextDocument;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -85,7 +87,10 @@ private:
|
|||||||
mutable QTextDocument *m_document = nullptr;
|
mutable QTextDocument *m_document = nullptr;
|
||||||
TextEditorWidget *m_editor = nullptr;
|
TextEditorWidget *m_editor = nullptr;
|
||||||
Utils::ChangeSet m_changes;
|
Utils::ChangeSet m_changes;
|
||||||
QList<QTextCursor> m_formattingCursors;
|
|
||||||
|
// The bool indicates whether to advance the start position.
|
||||||
|
QList<std::pair<QTextCursor, bool>> m_formattingCursors;
|
||||||
|
|
||||||
bool m_openEditor = false;
|
bool m_openEditor = false;
|
||||||
bool m_activateEditor = false;
|
bool m_activateEditor = false;
|
||||||
int m_editorCursorPosition = -1;
|
int m_editorCursorPosition = -1;
|
||||||
|
Reference in New Issue
Block a user