forked from qt-creator/qt-creator
CppEditor: Format code inserted by quickfixes
Task-number: QTCREATORBUG-10807 Task-number: QTCREATORBUG-19158 Change-Id: Ieac52e1a1a10afad91fea56290e7dcfd1d302e7f Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -334,10 +334,8 @@ void ChangeSet::apply_helper()
|
|||||||
{
|
{
|
||||||
// convert all ops to replace
|
// convert all ops to replace
|
||||||
QList<EditOp> replaceList;
|
QList<EditOp> replaceList;
|
||||||
{
|
while (!m_operationList.isEmpty())
|
||||||
while (!m_operationList.isEmpty())
|
convertToReplace(m_operationList.takeFirst(), &replaceList);
|
||||||
convertToReplace(m_operationList.takeFirst(), &replaceList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute replaces
|
// execute replaces
|
||||||
if (m_cursor)
|
if (m_cursor)
|
||||||
|
@@ -75,15 +75,20 @@ CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPo
|
|||||||
{
|
{
|
||||||
const Snapshot &snapshot = this->data()->m_snapshot;
|
const Snapshot &snapshot = this->data()->m_snapshot;
|
||||||
m_cppDocument = snapshot.document(filePath);
|
m_cppDocument = snapshot.document(filePath);
|
||||||
|
m_formattingEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath)
|
CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath)
|
||||||
: RefactoringFile(document, filePath)
|
: RefactoringFile(document, filePath)
|
||||||
{ }
|
{
|
||||||
|
m_formattingEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor)
|
CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor)
|
||||||
: RefactoringFile(editor)
|
: RefactoringFile(editor)
|
||||||
{ }
|
{
|
||||||
|
m_formattingEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
Document::Ptr CppRefactoringFile::cppDocument() const
|
Document::Ptr CppRefactoringFile::cppDocument() const
|
||||||
{
|
{
|
||||||
|
@@ -340,12 +340,15 @@ bool RefactoringFile::apply()
|
|||||||
RefactoringChanges::rangesToSelections(doc, m_reindentRanges);
|
RefactoringChanges::rangesToSelections(doc, m_reindentRanges);
|
||||||
m_reindentRanges.clear();
|
m_reindentRanges.clear();
|
||||||
|
|
||||||
// apply changes and reindent
|
// apply changes
|
||||||
|
setupFormattingRanges(m_changes.operationList());
|
||||||
m_changes.apply(&c);
|
m_changes.apply(&c);
|
||||||
m_changes.clear();
|
m_changes.clear();
|
||||||
|
|
||||||
|
// Do indentation and formatting.
|
||||||
indentOrReindent(indentSelections, Indent);
|
indentOrReindent(indentSelections, Indent);
|
||||||
indentOrReindent(reindentSelections, Reindent);
|
indentOrReindent(reindentSelections, Reindent);
|
||||||
|
doFormatting();
|
||||||
|
|
||||||
c.endEditBlock();
|
c.endEditBlock();
|
||||||
|
|
||||||
@@ -391,6 +394,98 @@ void RefactoringFile::indentOrReindent(const RefactoringSelections &ranges,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RefactoringFile::setupFormattingRanges(const QList<ChangeSet::EditOp> &replaceList)
|
||||||
|
{
|
||||||
|
if (!m_editor || !m_formattingEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const ChangeSet::EditOp &op : replaceList) {
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
switch (op.type) {
|
||||||
|
case ChangeSet::EditOp::Unset:
|
||||||
|
break;
|
||||||
|
case ChangeSet::EditOp::Replace:
|
||||||
|
case ChangeSet::EditOp::Insert:
|
||||||
|
case ChangeSet::EditOp::Remove:
|
||||||
|
cursor.setKeepPositionOnInsert(true);
|
||||||
|
cursor.setPosition(op.pos1 + op.length1);
|
||||||
|
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
||||||
|
m_formattingCursors << cursor;
|
||||||
|
break;
|
||||||
|
case ChangeSet::EditOp::Flip:
|
||||||
|
case ChangeSet::EditOp::Move:
|
||||||
|
cursor.setKeepPositionOnInsert(true);
|
||||||
|
cursor.setPosition(op.pos1 + op.length1);
|
||||||
|
cursor.setPosition(op.pos1, QTextCursor::KeepAnchor);
|
||||||
|
m_formattingCursors << cursor;
|
||||||
|
cursor.setPosition(op.pos2 + op.length2);
|
||||||
|
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
||||||
|
m_formattingCursors << cursor;
|
||||||
|
break;
|
||||||
|
case ChangeSet::EditOp::Copy:
|
||||||
|
cursor.setKeepPositionOnInsert(true);
|
||||||
|
cursor.setPosition(op.pos2, QTextCursor::KeepAnchor);
|
||||||
|
m_formattingCursors << cursor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RefactoringFile::doFormatting()
|
||||||
|
{
|
||||||
|
if (m_formattingCursors.empty() || !m_editor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RangesInLines formattingRanges;
|
||||||
|
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
auto lineForPosition = [&](int pos) {
|
||||||
|
cursor.setPosition(pos);
|
||||||
|
return cursor.blockNumber() + 1;
|
||||||
|
};
|
||||||
|
QList<int> affectedLines;
|
||||||
|
for (const QTextCursor &formattingCursor : std::as_const(m_formattingCursors)) {
|
||||||
|
int startLine = lineForPosition(formattingCursor.selectionStart());
|
||||||
|
int endLine = lineForPosition(formattingCursor.selectionEnd());
|
||||||
|
for (int line = startLine; line <= endLine; ++line) {
|
||||||
|
const auto it = std::lower_bound(affectedLines.begin(), affectedLines.end(), line);
|
||||||
|
if (it == affectedLines.end() || *it > line)
|
||||||
|
affectedLines.insert(it, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int line : std::as_const(affectedLines)) {
|
||||||
|
if (!formattingRanges.empty() && formattingRanges.back().endLine == line - 1)
|
||||||
|
formattingRanges.back().endLine = line;
|
||||||
|
else
|
||||||
|
formattingRanges.push_back({line, line});
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QString clangFormatLineRemovalBlocker("// QTC_TEMP");
|
||||||
|
for (const RangeInLines &r : std::as_const(formattingRanges)) {
|
||||||
|
QTextBlock b = m_editor->document()->findBlockByNumber(r.startLine - 1);
|
||||||
|
while (true) {
|
||||||
|
QTC_ASSERT(b.isValid(), break);
|
||||||
|
if (b.text().simplified().isEmpty())
|
||||||
|
QTextCursor(b).insertText(clangFormatLineRemovalBlocker);
|
||||||
|
if (b.blockNumber() == r.endLine)
|
||||||
|
break;
|
||||||
|
b = b.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_editor->textDocument()->indenter()->format(formattingRanges);
|
||||||
|
for (QTextBlock b = m_editor->document()->findBlockByNumber(
|
||||||
|
formattingRanges.front().startLine - 1); b.isValid(); b = b.next()) {
|
||||||
|
QString blockText = b.text();
|
||||||
|
if (blockText.remove(clangFormatLineRemovalBlocker) == b.text())
|
||||||
|
continue;
|
||||||
|
QTextCursor c(b);
|
||||||
|
c.select(QTextCursor::LineUnderCursor);
|
||||||
|
c.removeSelectedText();
|
||||||
|
c.insertText(blockText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RefactoringFile::fileChanged()
|
void RefactoringFile::fileChanged()
|
||||||
{
|
{
|
||||||
if (!m_filePath.isEmpty())
|
if (!m_filePath.isEmpty())
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "indenter.h"
|
||||||
|
|
||||||
#include <texteditor/texteditor_global.h>
|
#include <texteditor/texteditor_global.h>
|
||||||
#include <utils/changeset.h>
|
#include <utils/changeset.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
@@ -75,6 +77,9 @@ protected:
|
|||||||
enum IndentType {Indent, Reindent};
|
enum IndentType {Indent, Reindent};
|
||||||
void indentOrReindent(const RefactoringSelections &ranges, IndentType indent);
|
void indentOrReindent(const RefactoringSelections &ranges, IndentType indent);
|
||||||
|
|
||||||
|
void setupFormattingRanges(const QList<Utils::ChangeSet::EditOp> &replaceList);
|
||||||
|
void doFormatting();
|
||||||
|
|
||||||
Utils::FilePath m_filePath;
|
Utils::FilePath m_filePath;
|
||||||
QSharedPointer<RefactoringChangesData> m_data;
|
QSharedPointer<RefactoringChangesData> m_data;
|
||||||
mutable Utils::TextFileFormat m_textFileFormat;
|
mutable Utils::TextFileFormat m_textFileFormat;
|
||||||
@@ -83,10 +88,12 @@ protected:
|
|||||||
Utils::ChangeSet m_changes;
|
Utils::ChangeSet m_changes;
|
||||||
QList<Range> m_indentRanges;
|
QList<Range> m_indentRanges;
|
||||||
QList<Range> m_reindentRanges;
|
QList<Range> m_reindentRanges;
|
||||||
|
QList<QTextCursor> 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;
|
||||||
bool m_appliedOnce = false;
|
bool m_appliedOnce = false;
|
||||||
|
bool m_formattingEnabled = false;
|
||||||
|
|
||||||
friend class RefactoringChanges; // access to constructor
|
friend class RefactoringChanges; // access to constructor
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user