forked from qt-creator/qt-creator
TextEditor: Get rid of extra indent ranges in RefactoringFile
Having extra indent regions complicates the interface, the implementation and the calling code. Instead, derive the indent regions from the change set and let callers opt out for the relatively few cases where indentation is not desired. Change-Id: I49d2854830a51778534ef260fb5c9f2c7685554a Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "clangfixitoperation.h"
|
#include "clangfixitoperation.h"
|
||||||
|
|
||||||
#include <texteditor/refactoringchanges.h>
|
#include <cppeditor/cppmodelmanager.h>
|
||||||
|
#include <cppeditor/cpprefactoringchanges.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -46,7 +47,8 @@ static FileToFixits fixitsPerFile(const QList<ClangFixIt> &fixIts)
|
|||||||
|
|
||||||
void ClangFixItOperation::perform()
|
void ClangFixItOperation::perform()
|
||||||
{
|
{
|
||||||
const TextEditor::PlainRefactoringFileFactory refactoringChanges;
|
const CppEditor::CppRefactoringChanges refactoringChanges(
|
||||||
|
CppEditor::CppModelManager::snapshot());
|
||||||
const FileToFixits fileToFixIts = fixitsPerFile(fixIts);
|
const FileToFixits fileToFixIts = fixitsPerFile(fixIts);
|
||||||
|
|
||||||
for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) {
|
for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) {
|
||||||
|
|||||||
@@ -864,8 +864,6 @@ public:
|
|||||||
// Write header file
|
// Write header file
|
||||||
if (!headerChangeSet.isEmpty()) {
|
if (!headerChangeSet.isEmpty()) {
|
||||||
headerFile->setChangeSet(headerChangeSet);
|
headerFile->setChangeSet(headerChangeSet);
|
||||||
headerFile->appendIndentRange(Utils::ChangeSet::Range(m_insertPosDecl,
|
|
||||||
m_insertPosDecl + 1));
|
|
||||||
headerFile->setOpenEditor(true, m_insertPosDecl);
|
headerFile->setOpenEditor(true, m_insertPosDecl);
|
||||||
headerFile->apply();
|
headerFile->apply();
|
||||||
}
|
}
|
||||||
@@ -920,8 +918,6 @@ public:
|
|||||||
|
|
||||||
if (!implementationChangeSet.isEmpty()) {
|
if (!implementationChangeSet.isEmpty()) {
|
||||||
implementationFile->setChangeSet(implementationChangeSet);
|
implementationFile->setChangeSet(implementationChangeSet);
|
||||||
implementationFile->appendIndentRange(Utils::ChangeSet::Range(insertPos,
|
|
||||||
insertPos + 1));
|
|
||||||
implementationFile->apply();
|
implementationFile->apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -599,7 +599,6 @@ public:
|
|||||||
changes.insert(end, QLatin1String(")"));
|
changes.insert(end, QLatin1String(")"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(pattern));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -699,7 +698,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(declaration));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,7 +772,6 @@ public:
|
|||||||
changes.insert(end, QLatin1String("\n}"));
|
changes.insert(end, QLatin1String("\n}"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(ChangeSet::Range(start, end));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -848,7 +845,6 @@ public:
|
|||||||
changes.insert(insertPos, QLatin1String(";\n"));
|
changes.insert(insertPos, QLatin1String(";\n"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(pattern));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +920,6 @@ public:
|
|||||||
changes.insert(insertPos, QLatin1String(";\n"));
|
changes.insert(insertPos, QLatin1String(";\n"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(pattern));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,7 +1007,6 @@ public:
|
|||||||
changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
|
changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(pattern));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,7 +1035,6 @@ public:
|
|||||||
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(currentFile->range(pattern));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2405,7 +2398,6 @@ public:
|
|||||||
+ values.join(QLatin1String(":\nbreak;\ncase "))
|
+ values.join(QLatin1String(":\nbreak;\ncase "))
|
||||||
+ QLatin1String(":\nbreak;"));
|
+ QLatin1String(":\nbreak;"));
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(ChangeSet::Range(start, start + 1));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2542,14 +2534,12 @@ public:
|
|||||||
QTC_ASSERT(loc.isValid(), return);
|
QTC_ASSERT(loc.isValid(), return);
|
||||||
|
|
||||||
CppRefactoringFilePtr targetFile = refactoring.cppFile(m_targetFilePath);
|
CppRefactoringFilePtr targetFile = refactoring.cppFile(m_targetFilePath);
|
||||||
int targetPosition1 = targetFile->position(loc.line(), loc.column());
|
int targetPosition = targetFile->position(loc.line(), loc.column());
|
||||||
int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1);
|
|
||||||
|
|
||||||
ChangeSet target;
|
ChangeSet target;
|
||||||
target.insert(targetPosition1, loc.prefix() + m_decl);
|
target.insert(targetPosition, loc.prefix() + m_decl);
|
||||||
targetFile->setChangeSet(target);
|
targetFile->setChangeSet(target);
|
||||||
targetFile->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1));
|
targetFile->setOpenEditor(true, targetPosition);
|
||||||
targetFile->setOpenEditor(true, targetPosition1);
|
|
||||||
targetFile->apply();
|
targetFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2708,8 +2698,7 @@ public:
|
|||||||
DeclaratorAST *declAST,
|
DeclaratorAST *declAST,
|
||||||
Declaration *decl,
|
Declaration *decl,
|
||||||
const FilePath &targetFilePath,
|
const FilePath &targetFilePath,
|
||||||
ChangeSet *changeSet = nullptr,
|
ChangeSet *changeSet = nullptr)
|
||||||
QList<ChangeSet::Range> *indentRanges = nullptr)
|
|
||||||
{
|
{
|
||||||
CppRefactoringChanges refactoring(op->snapshot());
|
CppRefactoringChanges refactoring(op->snapshot());
|
||||||
if (!loc.isValid())
|
if (!loc.isValid())
|
||||||
@@ -2736,10 +2725,6 @@ public:
|
|||||||
ChangeSet * const target = changeSet ? changeSet : &localChangeSet;
|
ChangeSet * const target = changeSet ? changeSet : &localChangeSet;
|
||||||
target->replace(targetPos - 1, targetPos, QLatin1String("\n {\n\n}")); // replace ';'
|
target->replace(targetPos - 1, targetPos, QLatin1String("\n {\n\n}")); // replace ';'
|
||||||
const ChangeSet::Range indentRange(targetPos, targetPos + 4);
|
const ChangeSet::Range indentRange(targetPos, targetPos + 4);
|
||||||
if (indentRanges)
|
|
||||||
indentRanges->append(indentRange);
|
|
||||||
else
|
|
||||||
targetFile->appendIndentRange(indentRange);
|
|
||||||
|
|
||||||
if (!changeSet) {
|
if (!changeSet) {
|
||||||
targetFile->setChangeSet(*target);
|
targetFile->setChangeSet(*target);
|
||||||
@@ -2819,10 +2804,6 @@ public:
|
|||||||
ChangeSet * const target = changeSet ? changeSet : &localChangeSet;
|
ChangeSet * const target = changeSet ? changeSet : &localChangeSet;
|
||||||
target->insert(targetPos, loc.prefix() + defText + loc.suffix());
|
target->insert(targetPos, loc.prefix() + defText + loc.suffix());
|
||||||
const ChangeSet::Range indentRange(targetPos2, targetPos);
|
const ChangeSet::Range indentRange(targetPos2, targetPos);
|
||||||
if (indentRanges)
|
|
||||||
indentRanges->append(indentRange);
|
|
||||||
else
|
|
||||||
targetFile->appendIndentRange(indentRange);
|
|
||||||
|
|
||||||
if (!changeSet) {
|
if (!changeSet) {
|
||||||
targetFile->setChangeSet(*target);
|
targetFile->setChangeSet(*target);
|
||||||
@@ -2995,12 +2976,10 @@ private:
|
|||||||
QTC_ASSERT(loc.isValid(), return);
|
QTC_ASSERT(loc.isValid(), return);
|
||||||
|
|
||||||
CppRefactoringFilePtr targetFile = refactoring.cppFile(filePath);
|
CppRefactoringFilePtr targetFile = refactoring.cppFile(filePath);
|
||||||
const int targetPosition1 = targetFile->position(loc.line(), loc.column());
|
const int targetPosition = targetFile->position(loc.line(), loc.column());
|
||||||
const int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1);
|
|
||||||
ChangeSet target;
|
ChangeSet target;
|
||||||
target.insert(targetPosition1, loc.prefix() + decl + ";\n");
|
target.insert(targetPosition, loc.prefix() + decl + ";\n");
|
||||||
targetFile->setChangeSet(target);
|
targetFile->setChangeSet(target);
|
||||||
targetFile->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1));
|
|
||||||
targetFile->apply();
|
targetFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3558,7 +3537,7 @@ private:
|
|||||||
SimpleDeclarationAST *m_decl = nullptr;
|
SimpleDeclarationAST *m_decl = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<FilePath, QPair<ChangeSet, QList<ChangeSet::Range>>> changeSets;
|
QHash<FilePath, ChangeSet> changeSets;
|
||||||
for (const MemberFunctionImplSetting &setting : std::as_const(settings)) {
|
for (const MemberFunctionImplSetting &setting : std::as_const(settings)) {
|
||||||
DeclFinder finder(currentFile().data(), setting.func);
|
DeclFinder finder(currentFile().data(), setting.func);
|
||||||
finder.accept(m_classAST);
|
finder.accept(m_classAST);
|
||||||
@@ -3572,17 +3551,14 @@ private:
|
|||||||
currentFile()->lineAndColumn(currentFile()->endOf(finder.decl()), &line, &column);
|
currentFile()->lineAndColumn(currentFile()->endOf(finder.decl()), &line, &column);
|
||||||
loc = InsertionLocation(filePath(), QString(), QString(), line, column);
|
loc = InsertionLocation(filePath(), QString(), QString(), line, column);
|
||||||
}
|
}
|
||||||
auto &changeSet = changeSets[targetFilePath];
|
ChangeSet &changeSet = changeSets[targetFilePath];
|
||||||
InsertDefOperation::insertDefinition(
|
InsertDefOperation::insertDefinition(
|
||||||
this, loc, setting.defPos, finder.decl()->declarator_list->value,
|
this, loc, setting.defPos, finder.decl()->declarator_list->value,
|
||||||
setting.func->asDeclaration(),targetFilePath,
|
setting.func->asDeclaration(),targetFilePath, &changeSet);
|
||||||
&changeSet.first, &changeSet.second);
|
|
||||||
}
|
}
|
||||||
for (auto it = changeSets.cbegin(); it != changeSets.cend(); ++it) {
|
for (auto it = changeSets.cbegin(); it != changeSets.cend(); ++it) {
|
||||||
const CppRefactoringFilePtr file = refactoring.cppFile(it.key());
|
const CppRefactoringFilePtr file = refactoring.cppFile(it.key());
|
||||||
for (const ChangeSet::Range &r : it.value().second)
|
file->setChangeSet(it.value());
|
||||||
file->appendIndentRange(r);
|
|
||||||
file->setChangeSet(it.value().first);
|
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3763,11 +3739,9 @@ protected:
|
|||||||
const InsertionLocation &loc,
|
const InsertionLocation &loc,
|
||||||
const QString &text)
|
const QString &text)
|
||||||
{
|
{
|
||||||
int targetPosition1 = file->position(loc.line(), loc.column());
|
int targetPosition = file->position(loc.line(), loc.column());
|
||||||
int targetPosition2 = qMax(0, file->position(loc.line(), 1) - 1);
|
|
||||||
ChangeSet &changeSet = file == m_headerFile ? m_headerFileChangeSet : m_sourceFileChangeSet;
|
ChangeSet &changeSet = file == m_headerFile ? m_headerFileChangeSet : m_sourceFileChangeSet;
|
||||||
changeSet.insert(targetPosition1, loc.prefix() + text + loc.suffix());
|
changeSet.insert(targetPosition, loc.prefix() + text + loc.suffix());
|
||||||
file->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FullySpecifiedType makeConstRef(FullySpecifiedType type)
|
FullySpecifiedType makeConstRef(FullySpecifiedType type)
|
||||||
@@ -5190,7 +5164,6 @@ public:
|
|||||||
change.insert(position, funcDef);
|
change.insert(position, funcDef);
|
||||||
change.replace(m_extractionStart, m_extractionEnd, funcCall);
|
change.replace(m_extractionStart, m_extractionEnd, funcCall);
|
||||||
currentFile->setChangeSet(change);
|
currentFile->setChangeSet(change);
|
||||||
currentFile->appendIndentRange(ChangeSet::Range(position, position + 1));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
|
|
||||||
QTextCursor tc = currentFile->document()->find(QLatin1String("{"), position);
|
QTextCursor tc = currentFile->document()->find(QLatin1String("{"), position);
|
||||||
@@ -5199,7 +5172,6 @@ public:
|
|||||||
change.clear();
|
change.clear();
|
||||||
change.insert(position, extract + '\n');
|
change.insert(position, extract + '\n');
|
||||||
currentFile->setChangeSet(change);
|
currentFile->setChangeSet(change);
|
||||||
currentFile->appendReindentRange(ChangeSet::Range(position, position + 1));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
|
|
||||||
// Write declaration, if necessary.
|
// Write declaration, if necessary.
|
||||||
@@ -5213,7 +5185,6 @@ public:
|
|||||||
position = declFile->position(location.line(), location.column());
|
position = declFile->position(location.line(), location.column());
|
||||||
change.insert(position, location.prefix() + funcDecl + location.suffix());
|
change.insert(position, location.prefix() + funcDecl + location.suffix());
|
||||||
declFile->setChangeSet(change);
|
declFile->setChangeSet(change);
|
||||||
declFile->appendIndentRange(ChangeSet::Range(position, position + 1));
|
|
||||||
declFile->apply();
|
declFile->apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6579,7 +6550,6 @@ public:
|
|||||||
|
|
||||||
// insert definition at new position
|
// insert definition at new position
|
||||||
m_toFileChangeSet.insert(insertPos, funcDef);
|
m_toFileChangeSet.insert(insertPos, funcDef);
|
||||||
m_toFile->appendIndentRange(ChangeSet::Range(insertPos, insertPos + funcDef.size()));
|
|
||||||
m_toFile->setOpenEditor(true, insertPos);
|
m_toFile->setOpenEditor(true, insertPos);
|
||||||
|
|
||||||
// remove definition from fromFile
|
// remove definition from fromFile
|
||||||
@@ -6605,6 +6575,7 @@ public:
|
|||||||
}
|
}
|
||||||
if (!m_fromFileChangeSet.isEmpty()) {
|
if (!m_fromFileChangeSet.isEmpty()) {
|
||||||
m_fromFile->setChangeSet(m_fromFileChangeSet);
|
m_fromFile->setChangeSet(m_fromFileChangeSet);
|
||||||
|
m_fromFile->skipFormatting();
|
||||||
m_fromFile->apply();
|
m_fromFile->apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6836,7 +6807,6 @@ private:
|
|||||||
if (m_toFilePath == m_fromFilePath)
|
if (m_toFilePath == m_fromFilePath)
|
||||||
toTarget.remove(m_fromRange);
|
toTarget.remove(m_fromRange);
|
||||||
toFile->setChangeSet(toTarget);
|
toFile->setChangeSet(toTarget);
|
||||||
toFile->appendIndentRange(m_toRange);
|
|
||||||
toFile->setOpenEditor(true, m_toRange.start);
|
toFile->setOpenEditor(true, m_toRange.start);
|
||||||
toFile->apply();
|
toFile->apply();
|
||||||
if (m_toFilePath != m_fromFilePath) {
|
if (m_toFilePath != m_fromFilePath) {
|
||||||
@@ -7649,6 +7619,13 @@ private:
|
|||||||
CppRefactoringChanges refactoring(snapshot());
|
CppRefactoringChanges refactoring(snapshot());
|
||||||
CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath());
|
CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath());
|
||||||
currentFile->setChangeSet(m_changes);
|
currentFile->setChangeSet(m_changes);
|
||||||
|
|
||||||
|
// It would probably be unexpected to users if we were to re-format here, though
|
||||||
|
// an argument could also be made for doing it, especially if "format instead of indent"
|
||||||
|
// is enabled, as a difference in line length might trigger a different ClangFormat
|
||||||
|
// re-flowing.
|
||||||
|
currentFile->skipFormatting();
|
||||||
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8426,9 +8403,11 @@ private:
|
|||||||
processIncludes(refactoring, filePath());
|
processIncludes(refactoring, filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &file : std::as_const(m_changes))
|
for (auto &file : std::as_const(m_changes)) {
|
||||||
|
file->skipFormatting();
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief refactorFile remove using namespace xyz in the given file and rewrite types
|
* @brief refactorFile remove using namespace xyz in the given file and rewrite types
|
||||||
|
|||||||
@@ -36,16 +36,6 @@ public:
|
|||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
static std::unique_ptr<TextEditor::Indenter> createIndenter(const FilePath &filePath,
|
|
||||||
QTextDocument *textDocument)
|
|
||||||
{
|
|
||||||
TextEditor::ICodeStylePreferencesFactory *factory
|
|
||||||
= TextEditor::TextEditorSettings::codeStyleFactory(Constants::CPP_SETTINGS_ID);
|
|
||||||
std::unique_ptr<TextEditor::Indenter> indenter(factory->createIndenter(textDocument));
|
|
||||||
indenter->setFileName(filePath);
|
|
||||||
return indenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot)
|
CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot)
|
||||||
: m_data(new CppRefactoringChangesData(snapshot))
|
: m_data(new CppRefactoringChangesData(snapshot))
|
||||||
{
|
{
|
||||||
@@ -89,19 +79,16 @@ CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPo
|
|||||||
{
|
{
|
||||||
const Snapshot &snapshot = data->m_snapshot;
|
const Snapshot &snapshot = data->m_snapshot;
|
||||||
m_cppDocument = snapshot.document(filePath);
|
m_cppDocument = snapshot.document(filePath);
|
||||||
enableFormatting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath)
|
CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath)
|
||||||
: RefactoringFile(document, filePath)
|
: RefactoringFile(document, filePath)
|
||||||
{
|
{
|
||||||
enableFormatting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor)
|
CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor)
|
||||||
: RefactoringFile(editor)
|
: RefactoringFile(editor)
|
||||||
{
|
{
|
||||||
enableFormatting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document::Ptr CppRefactoringFile::cppDocument() const
|
Document::Ptr CppRefactoringFile::cppDocument() const
|
||||||
@@ -253,6 +240,11 @@ void CppRefactoringFile::fileChanged()
|
|||||||
CppModelManager::updateSourceFiles({filePath()});
|
CppModelManager::updateSourceFiles({filePath()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id CppRefactoringFile::indenterId() const
|
||||||
|
{
|
||||||
|
return Constants::CPP_SETTINGS_ID;
|
||||||
|
}
|
||||||
|
|
||||||
int CppRefactoringFile::tokenIndexForPosition(const std::vector<CPlusPlus::Token> &tokens,
|
int CppRefactoringFile::tokenIndexForPosition(const std::vector<CPlusPlus::Token> &tokens,
|
||||||
int pos, int startIndex) const
|
int pos, int startIndex) const
|
||||||
{
|
{
|
||||||
@@ -281,28 +273,4 @@ CppRefactoringChangesData::CppRefactoringChangesData(const Snapshot &snapshot)
|
|||||||
, m_workingCopy(CppModelManager::workingCopy())
|
, m_workingCopy(CppModelManager::workingCopy())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CppRefactoringFile::indentSelection(const QTextCursor &selection,
|
|
||||||
const TextEditor::TextDocument *textDocument) const
|
|
||||||
{
|
|
||||||
if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat
|
|
||||||
textDocument->indenter()->indent(selection, QChar::Null, textDocument->tabSettings());
|
|
||||||
} else {
|
|
||||||
const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument);
|
|
||||||
auto indenter = createIndenter(filePath(), selection.document());
|
|
||||||
indenter->indent(selection, QChar::Null, tabSettings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppRefactoringFile::reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextEditor::TextDocument *textDocument) const
|
|
||||||
{
|
|
||||||
if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat
|
|
||||||
textDocument->indenter()->reindent(selection, textDocument->tabSettings());
|
|
||||||
} else {
|
|
||||||
const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument);
|
|
||||||
auto indenter = createIndenter(filePath(), selection.document());
|
|
||||||
indenter->reindent(selection, tabSettings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace CppEditor
|
} // namespace CppEditor
|
||||||
|
|||||||
@@ -55,11 +55,7 @@ private:
|
|||||||
explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor);
|
explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor);
|
||||||
|
|
||||||
void fileChanged() override;
|
void fileChanged() override;
|
||||||
void indentSelection(const QTextCursor &selection,
|
Utils::Id indenterId() const override;
|
||||||
const TextEditor::TextDocument *textDocument) const override;
|
|
||||||
virtual void reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextEditor::TextDocument *textDocument) const override;
|
|
||||||
|
|
||||||
|
|
||||||
int tokenIndexForPosition(const std::vector<CPlusPlus::Token> &tokens, int pos,
|
int tokenIndexForPosition(const std::vector<CPlusPlus::Token> &tokens, int pos,
|
||||||
int startIndex) const;
|
int startIndex) const;
|
||||||
|
|||||||
@@ -91,8 +91,6 @@ bool applyTextEdits(const Client *client,
|
|||||||
return true;
|
return true;
|
||||||
const RefactoringFilePtr file = client->createRefactoringFile(filePath);
|
const RefactoringFilePtr file = client->createRefactoringFile(filePath);
|
||||||
file->setChangeSet(editsToChangeSet(edits, file->document()));
|
file->setChangeSet(editsToChangeSet(edits, file->document()));
|
||||||
for (const TextEdit &edit : edits)
|
|
||||||
file->appendIndentRange(convertRange(file->document(), edit.range()));
|
|
||||||
return file->apply();
|
return file->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "devicesupport/devicesettingspage.h"
|
#include "devicesupport/devicesettingspage.h"
|
||||||
#include "devicesupport/sshsettings.h"
|
#include "devicesupport/sshsettings.h"
|
||||||
#include "devicesupport/sshsettingspage.h"
|
#include "devicesupport/sshsettingspage.h"
|
||||||
|
#include "editorconfiguration.h"
|
||||||
#include "editorsettingspropertiespage.h"
|
#include "editorsettingspropertiespage.h"
|
||||||
#include "environmentaspect.h"
|
#include "environmentaspect.h"
|
||||||
#include "filesinallprojectsfind.h"
|
#include "filesinallprojectsfind.h"
|
||||||
@@ -116,6 +117,7 @@
|
|||||||
#include <extensionsystem/pluginspec.h>
|
#include <extensionsystem/pluginspec.h>
|
||||||
|
|
||||||
#include <texteditor/findinfiles.h>
|
#include <texteditor/findinfiles.h>
|
||||||
|
#include <texteditor/tabsettings.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/texteditorconstants.h>
|
#include <texteditor/texteditorconstants.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
@@ -833,6 +835,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
|||||||
IWizardFactory::registerFeatureProvider(new KitFeatureProvider);
|
IWizardFactory::registerFeatureProvider(new KitFeatureProvider);
|
||||||
IWizardFactory::registerFactoryCreator([] { return new SimpleProjectWizard; });
|
IWizardFactory::registerFactoryCreator([] { return new SimpleProjectWizard; });
|
||||||
|
|
||||||
|
TextEditor::TabSettings::setRetriever([](const FilePath &filePath) {
|
||||||
|
return actualTabSettings(filePath, nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
ProjectManager *sessionManager = &dd->m_sessionManager;
|
ProjectManager *sessionManager = &dd->m_sessionManager;
|
||||||
connect(sessionManager, &ProjectManager::projectAdded,
|
connect(sessionManager, &ProjectManager::projectAdded,
|
||||||
this, &ProjectExplorerPlugin::fileListChanged);
|
this, &ProjectExplorerPlugin::fileListChanged);
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ public:
|
|||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
changes.replace(start, end, replacement);
|
changes.replace(start, end, replacement);
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(Range(start, end + 1));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
|
|
||||||
Core::IVersionControl *versionControl = Core::VcsManager::findVersionControlForDirectory(
|
Core::IVersionControl *versionControl = Core::VcsManager::findVersionControlForDirectory(
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ public:
|
|||||||
QLatin1String("\n"));
|
QLatin1String("\n"));
|
||||||
|
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(Range(currentFile->startOf(_objectInitializer->lbraceToken),
|
|
||||||
currentFile->startOf(_objectInitializer->rbraceToken)));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -123,7 +121,6 @@ public:
|
|||||||
const int insertLoc = _message.location.begin() - _message.location.startColumn + 1;
|
const int insertLoc = _message.location.begin() - _message.location.startColumn + 1;
|
||||||
changes.insert(insertLoc, QString::fromLatin1("// %1\n").arg(_message.suppressionString()));
|
changes.insert(insertLoc, QString::fromLatin1("// %1\n").arg(_message.suppressionString()));
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(Range(insertLoc, insertLoc + 1));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ public:
|
|||||||
" sourceComponent: %1\n"
|
" sourceComponent: %1\n"
|
||||||
"}\n").arg(componentId, loaderId));
|
"}\n").arg(componentId, loaderId));
|
||||||
currentFile->setChangeSet(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->appendIndentRange(Range(objDefStart, objDefEnd));
|
|
||||||
currentFile->apply();
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -860,9 +860,6 @@ void QmlOutlineModel::reparentNodes(QmlOutlineItem *targetItem, int row, QList<Q
|
|||||||
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot);
|
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot);
|
||||||
TextEditor::RefactoringFilePtr file = refactoring.file(m_semanticInfo.document->fileName());
|
TextEditor::RefactoringFilePtr file = refactoring.file(m_semanticInfo.document->fileName());
|
||||||
file->setChangeSet(changeSet);
|
file->setChangeSet(changeSet);
|
||||||
for (const Utils::ChangeSet::Range &range : std::as_const(changedRanges)) {
|
|
||||||
file->appendIndentRange(range);
|
|
||||||
}
|
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "qmljsrefactoringchanges.h"
|
#include "qmljsrefactoringchanges.h"
|
||||||
|
|
||||||
#include "qmljsqtstylecodeformatter.h"
|
#include "qmljsqtstylecodeformatter.h"
|
||||||
#include "qmljsmodelmanager.h"
|
#include "qmljsmodelmanager.h"
|
||||||
#include "qmljsindenter.h"
|
#include "qmljsindenter.h"
|
||||||
|
#include "qmljstoolsconstants.h"
|
||||||
|
|
||||||
#include <qmljs/parser/qmljsast_p.h>
|
#include <qmljs/parser/qmljsast_p.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
@@ -139,44 +141,9 @@ void QmlJSRefactoringFile::fileChanged()
|
|||||||
m_data->m_modelManager->updateSourceFiles({filePath()}, true);
|
m_data->m_modelManager->updateSourceFiles({filePath()}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlJSRefactoringFile::indentSelection(const QTextCursor &selection,
|
Utils::Id QmlJSRefactoringFile::indenterId() const
|
||||||
const TextEditor::TextDocument *textDocument) const
|
|
||||||
{
|
{
|
||||||
// ### shares code with QmlJSTextEditor::indent
|
return Constants::QML_JS_SETTINGS_ID;
|
||||||
QTextDocument *doc = selection.document();
|
|
||||||
|
|
||||||
QTextBlock block = doc->findBlock(selection.selectionStart());
|
|
||||||
const QTextBlock end = doc->findBlock(selection.selectionEnd()).next();
|
|
||||||
|
|
||||||
const TextEditor::TabSettings &tabSettings =
|
|
||||||
ProjectExplorer::actualTabSettings(filePath(), textDocument);
|
|
||||||
CreatorCodeFormatter codeFormatter(tabSettings);
|
|
||||||
codeFormatter.updateStateUntil(block);
|
|
||||||
do {
|
|
||||||
int depth = codeFormatter.indentFor(block);
|
|
||||||
if (depth != -1) {
|
|
||||||
if (QStringView(block.text()).trimmed().isEmpty()) {
|
|
||||||
// we do not want to indent empty lines (as one is indentent when pressing tab
|
|
||||||
// assuming that the user will start writing something), and get rid of that
|
|
||||||
// space if one had pressed tab in an empty line just before refactoring.
|
|
||||||
// If depth == -1 (inside a multiline string for example) leave the spaces.
|
|
||||||
depth = 0;
|
|
||||||
}
|
|
||||||
tabSettings.indentLine(block, depth);
|
|
||||||
}
|
|
||||||
codeFormatter.updateLineStateChange(block);
|
|
||||||
block = block.next();
|
|
||||||
} while (block.isValid() && block != end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlJSRefactoringFile::reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextEditor::TextDocument *textDocument) const
|
|
||||||
{
|
|
||||||
const TextEditor::TabSettings &tabSettings =
|
|
||||||
ProjectExplorer::actualTabSettings(filePath(), textDocument);
|
|
||||||
|
|
||||||
QmlJSEditor::Internal::Indenter indenter(selection.document());
|
|
||||||
indenter.reindent(selection, tabSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlJSTools
|
} // namespace QmlJSTools
|
||||||
|
|||||||
@@ -40,10 +40,7 @@ private:
|
|||||||
QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, QmlJS::Document::Ptr document);
|
QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, QmlJS::Document::Ptr document);
|
||||||
|
|
||||||
void fileChanged() override;
|
void fileChanged() override;
|
||||||
void indentSelection(const QTextCursor &selection,
|
Utils::Id indenterId() const override;
|
||||||
const TextEditor::TextDocument *textDocument) const override;
|
|
||||||
void reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextEditor::TextDocument *textDocument) const override;
|
|
||||||
|
|
||||||
mutable QmlJS::Document::Ptr m_qmljsDocument;
|
mutable QmlJS::Document::Ptr m_qmljsDocument;
|
||||||
QSharedPointer<QmlJSRefactoringChangesData> m_data;
|
QSharedPointer<QmlJSRefactoringChangesData> m_data;
|
||||||
|
|||||||
@@ -595,6 +595,7 @@ FilePaths BaseFileFind::replaceAll(const QString &text, const SearchResultItems
|
|||||||
changeSet.replace(start, end, replacement);
|
changeSet.replace(start, end, replacement);
|
||||||
}
|
}
|
||||||
file->setChangeSet(changeSet);
|
file->setChangeSet(changeSet);
|
||||||
|
file->skipFormatting();
|
||||||
file->apply();
|
file->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
#include "refactoringchanges.h"
|
#include "refactoringchanges.h"
|
||||||
|
|
||||||
|
#include "icodestylepreferencesfactory.h"
|
||||||
#include "textdocument.h"
|
#include "textdocument.h"
|
||||||
#include "texteditor.h"
|
#include "texteditor.h"
|
||||||
#include "texteditortr.h"
|
#include "texteditortr.h"
|
||||||
|
#include "texteditorsettings.h"
|
||||||
|
#include "textindenter.h"
|
||||||
|
|
||||||
#include <coreplugin/dialogs/readonlyfilesdialog.h>
|
#include <coreplugin/dialogs/readonlyfilesdialog.h>
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
@@ -21,6 +24,8 @@
|
|||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -60,7 +65,8 @@ 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);
|
||||||
indentSelection(cursor, nullptr);
|
m_formattingCursors = {cursor};
|
||||||
|
doFormatting();
|
||||||
}
|
}
|
||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
|
|
||||||
@@ -198,22 +204,6 @@ void RefactoringFile::setChangeSet(const ChangeSet &changeSet)
|
|||||||
m_changes = changeSet;
|
m_changes = changeSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefactoringFile::appendIndentRange(const Range &range)
|
|
||||||
{
|
|
||||||
if (m_filePath.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_indentRanges.append(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefactoringFile::appendReindentRange(const Range &range)
|
|
||||||
{
|
|
||||||
if (m_filePath.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_reindentRanges.append(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefactoringFile::setOpenEditor(bool activate, int pos)
|
void RefactoringFile::setOpenEditor(bool activate, int pos)
|
||||||
{
|
{
|
||||||
m_openEditor = true;
|
m_openEditor = true;
|
||||||
@@ -249,7 +239,7 @@ bool RefactoringFile::apply()
|
|||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
// apply changes, if any
|
// apply changes, if any
|
||||||
if (!m_indentRanges.isEmpty() || !m_changes.isEmpty()) {
|
if (!m_changes.isEmpty()) {
|
||||||
QTextDocument *doc = mutableDocument();
|
QTextDocument *doc = mutableDocument();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
QTextCursor c = cursor();
|
QTextCursor c = cursor();
|
||||||
@@ -258,24 +248,12 @@ bool RefactoringFile::apply()
|
|||||||
else
|
else
|
||||||
c.beginEditBlock();
|
c.beginEditBlock();
|
||||||
|
|
||||||
sort(m_indentRanges);
|
|
||||||
sort(m_reindentRanges);
|
|
||||||
|
|
||||||
// build indent selections now, applying the changeset will change locations
|
|
||||||
const RefactoringSelections &indentSelections = rangesToSelections(doc, m_indentRanges);
|
|
||||||
m_indentRanges.clear();
|
|
||||||
const RefactoringSelections &reindentSelections
|
|
||||||
= rangesToSelections(doc, m_reindentRanges);
|
|
||||||
m_reindentRanges.clear();
|
|
||||||
|
|
||||||
// apply changes
|
// apply changes
|
||||||
setupFormattingRanges(m_changes.operationList());
|
setupFormattingRanges(m_changes.operationList());
|
||||||
m_changes.apply(&c);
|
m_changes.apply(&c);
|
||||||
m_changes.clear();
|
m_changes.clear();
|
||||||
|
|
||||||
// Do indentation and formatting.
|
// Do indentation and formatting.
|
||||||
indentOrReindent(indentSelections, Indent);
|
|
||||||
indentOrReindent(reindentSelections, Reindent);
|
|
||||||
doFormatting();
|
doFormatting();
|
||||||
|
|
||||||
c.endEditBlock();
|
c.endEditBlock();
|
||||||
@@ -308,27 +286,16 @@ bool RefactoringFile::apply()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefactoringFile::indentOrReindent(const RefactoringSelections &ranges,
|
|
||||||
RefactoringFile::IndentType indent)
|
|
||||||
{
|
|
||||||
TextDocument * document = m_editor ? m_editor->textDocument() : nullptr;
|
|
||||||
for (const auto &[position, anchor]: ranges) {
|
|
||||||
QTextCursor selection(anchor);
|
|
||||||
selection.setPosition(position.position(), QTextCursor::KeepAnchor);
|
|
||||||
if (indent == Indent)
|
|
||||||
indentSelection(selection, document);
|
|
||||||
else
|
|
||||||
reindentSelection(selection, document);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefactoringFile::setupFormattingRanges(const QList<ChangeSet::EditOp> &replaceList)
|
void RefactoringFile::setupFormattingRanges(const QList<ChangeSet::EditOp> &replaceList)
|
||||||
{
|
{
|
||||||
if (!m_editor || !m_formattingEnabled)
|
if (!m_formattingEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QTextDocument * const doc = m_editor ? m_editor->document() : m_document;
|
||||||
|
QTC_ASSERT(doc, return);
|
||||||
|
|
||||||
for (const ChangeSet::EditOp &op : replaceList) {
|
for (const ChangeSet::EditOp &op : replaceList) {
|
||||||
QTextCursor cursor = m_editor->textCursor();
|
QTextCursor cursor(doc);
|
||||||
switch (op.type) {
|
switch (op.type) {
|
||||||
case ChangeSet::EditOp::Unset:
|
case ChangeSet::EditOp::Unset:
|
||||||
break;
|
break;
|
||||||
@@ -361,55 +328,54 @@ void RefactoringFile::setupFormattingRanges(const QList<ChangeSet::EditOp> &repl
|
|||||||
|
|
||||||
void RefactoringFile::doFormatting()
|
void RefactoringFile::doFormatting()
|
||||||
{
|
{
|
||||||
if (m_formattingCursors.empty() || !m_editor)
|
if (m_formattingCursors.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RangesInLines formattingRanges;
|
QTextDocument *document = nullptr;
|
||||||
|
Indenter *indenter = nullptr;
|
||||||
|
std::unique_ptr<Indenter> indenterOwner;
|
||||||
|
TabSettings tabSettings;
|
||||||
|
if (m_editor) {
|
||||||
|
document = m_editor->document();
|
||||||
|
indenter = m_editor->textDocument()->indenter();
|
||||||
|
tabSettings = m_editor->textDocument()->tabSettings();
|
||||||
|
} else {
|
||||||
|
document = m_document;
|
||||||
|
ICodeStylePreferencesFactory * const factory
|
||||||
|
= TextEditorSettings::codeStyleFactory(indenterId());
|
||||||
|
indenterOwner.reset(factory ? factory->createIndenter(document)
|
||||||
|
: new TextIndenter(document));
|
||||||
|
indenter = indenterOwner.get();
|
||||||
|
tabSettings = TabSettings::settingsForFile(filePath());
|
||||||
|
}
|
||||||
|
QTC_ASSERT(document, return);
|
||||||
|
QTC_ASSERT(indenter, return);
|
||||||
|
|
||||||
QTextCursor cursor = m_editor->textCursor();
|
Utils::sort(m_formattingCursors, [](const QTextCursor &tc1, const QTextCursor &tc2) {
|
||||||
auto lineForPosition = [&](int pos) {
|
return tc1.selectionStart() < tc2.selectionStart();
|
||||||
cursor.setPosition(pos);
|
});
|
||||||
return cursor.blockNumber() + 1;
|
const int firstSelectedBlock = document->findBlock(m_formattingCursors.first().selectionStart())
|
||||||
};
|
.blockNumber();
|
||||||
QList<int> affectedLines;
|
static const QString clangFormatLineRemovalBlocker("// QTC_TEMP");
|
||||||
for (const QTextCursor &formattingCursor : std::as_const(m_formattingCursors)) {
|
for (const QTextCursor &formattingCursor : std::as_const(m_formattingCursors)) {
|
||||||
int startLine = lineForPosition(formattingCursor.selectionStart());
|
const QTextBlock firstBlock = document->findBlock(formattingCursor.selectionStart());
|
||||||
int endLine = lineForPosition(formattingCursor.selectionEnd());
|
const QTextBlock lastBlock = document->findBlock(formattingCursor.selectionEnd());
|
||||||
for (int line = startLine; line <= endLine; ++line) {
|
QTextBlock b = firstBlock;
|
||||||
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("");
|
|
||||||
for (const RangeInLines &r : std::as_const(formattingRanges)) {
|
|
||||||
QTextBlock b = m_editor->document()->findBlockByNumber(r.startLine - 1);
|
|
||||||
while (true) {
|
while (true) {
|
||||||
QTC_ASSERT(b.isValid(), break);
|
QTC_ASSERT(b.isValid(), break);
|
||||||
if (b.text().simplified().isEmpty())
|
if (b.text().simplified().isEmpty())
|
||||||
QTextCursor(b).insertText(clangFormatLineRemovalBlocker);
|
QTextCursor(b).insertText(clangFormatLineRemovalBlocker);
|
||||||
if (b.blockNumber() == r.endLine - 1)
|
if (b == lastBlock)
|
||||||
break;
|
break;
|
||||||
b = b.next();
|
b = b.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: The proper solution seems to be to call formatOrIndent() here (and not
|
for (const QTextCursor &tc : std::as_const(m_formattingCursors))
|
||||||
// use hardcoded indent regions anymore), but that would require intrusive changes
|
indenter->autoIndent(tc, tabSettings);
|
||||||
// to the C++ quickfixes and tests, where we rely on the built-in indenter behavior.
|
|
||||||
m_editor->textDocument()->indenter()->format(formattingRanges,
|
|
||||||
Indenter::FormattingMode::Settings);
|
|
||||||
|
|
||||||
for (QTextBlock b = m_editor->document()->findBlockByNumber(
|
for (QTextBlock b = document->findBlockByNumber(firstSelectedBlock);
|
||||||
formattingRanges.front().startLine - 1); b.isValid(); b = b.next()) {
|
b.isValid(); b = b.next()) {
|
||||||
QString blockText = b.text();
|
QString blockText = b.text();
|
||||||
if (blockText.remove(clangFormatLineRemovalBlocker) == b.text())
|
if (blockText.remove(clangFormatLineRemovalBlocker) == b.text())
|
||||||
continue;
|
continue;
|
||||||
@@ -420,20 +386,6 @@ void RefactoringFile::doFormatting()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefactoringFile::indentSelection(const QTextCursor &selection,
|
|
||||||
const TextDocument *textDocument) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(selection)
|
|
||||||
Q_UNUSED(textDocument)
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefactoringFile::reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextDocument *textDocument) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(selection)
|
|
||||||
Q_UNUSED(textDocument)
|
|
||||||
}
|
|
||||||
|
|
||||||
TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int column)
|
TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int column)
|
||||||
{
|
{
|
||||||
EditorManager::OpenEditorFlags flags = EditorManager::IgnoreNavigationHistory;
|
EditorManager::OpenEditorFlags flags = EditorManager::IgnoreNavigationHistory;
|
||||||
@@ -450,23 +402,6 @@ TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int colum
|
|||||||
return TextEditorWidget::fromEditor(editor);
|
return TextEditorWidget::fromEditor(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefactoringSelections RefactoringFile::rangesToSelections(QTextDocument *document,
|
|
||||||
const QList<Range> &ranges)
|
|
||||||
{
|
|
||||||
RefactoringSelections selections;
|
|
||||||
|
|
||||||
for (const Range &range : ranges) {
|
|
||||||
QTextCursor start(document);
|
|
||||||
start.setPosition(range.start);
|
|
||||||
start.setKeepPositionOnInsert(true);
|
|
||||||
QTextCursor end(document);
|
|
||||||
end.setPosition(qMin(range.end, document->characterCount() - 1));
|
|
||||||
selections.push_back({start, end});
|
|
||||||
}
|
|
||||||
|
|
||||||
return selections;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefactoringFileFactory::~RefactoringFileFactory() = default;
|
RefactoringFileFactory::~RefactoringFileFactory() = default;
|
||||||
|
|
||||||
RefactoringFilePtr PlainRefactoringFileFactory::file(const Utils::FilePath &filePath) const
|
RefactoringFilePtr PlainRefactoringFileFactory::file(const Utils::FilePath &filePath) const
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#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>
|
||||||
|
#include <utils/id.h>
|
||||||
#include <utils/textfileformat.h>
|
#include <utils/textfileformat.h>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -55,12 +56,13 @@ public:
|
|||||||
|
|
||||||
Utils::ChangeSet changeSet() const;
|
Utils::ChangeSet changeSet() const;
|
||||||
void setChangeSet(const Utils::ChangeSet &changeSet);
|
void setChangeSet(const Utils::ChangeSet &changeSet);
|
||||||
void appendIndentRange(const Range &range);
|
|
||||||
void appendReindentRange(const Range &range);
|
|
||||||
void setOpenEditor(bool activate = false, int pos = -1);
|
void setOpenEditor(bool activate = false, int pos = -1);
|
||||||
bool apply();
|
bool apply();
|
||||||
bool create(const QString &contents, bool reindent, bool openInEditor);
|
bool create(const QString &contents, bool reindent, bool openInEditor);
|
||||||
|
|
||||||
|
// TODO: Per EditOp?
|
||||||
|
void skipFormatting() { m_formattingEnabled = false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// users may only get const access to RefactoringFiles created through
|
// users may only get const access to RefactoringFiles created through
|
||||||
// this constructor, because it can't be used to apply changes
|
// this constructor, because it can't be used to apply changes
|
||||||
@@ -70,25 +72,15 @@ protected:
|
|||||||
RefactoringFile(const Utils::FilePath &filePath);
|
RefactoringFile(const Utils::FilePath &filePath);
|
||||||
|
|
||||||
void invalidate() { m_filePath.clear(); }
|
void invalidate() { m_filePath.clear(); }
|
||||||
void enableFormatting() { m_formattingEnabled = true; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void fileChanged() {} // derived classes may want to clear language specific extra data
|
virtual void fileChanged() {} // derived classes may want to clear language specific extra data
|
||||||
virtual void indentSelection(const QTextCursor &selection,
|
virtual Utils::Id indenterId() const { return {} ;}
|
||||||
const TextDocument *textDocument) const;
|
|
||||||
virtual void reindentSelection(const QTextCursor &selection,
|
|
||||||
const TextDocument *textDocument) const;
|
|
||||||
|
|
||||||
enum IndentType {Indent, Reindent};
|
|
||||||
void indentOrReindent(const RefactoringSelections &ranges, IndentType indent);
|
|
||||||
|
|
||||||
void setupFormattingRanges(const QList<Utils::ChangeSet::EditOp> &replaceList);
|
void setupFormattingRanges(const QList<Utils::ChangeSet::EditOp> &replaceList);
|
||||||
void doFormatting();
|
void doFormatting();
|
||||||
|
|
||||||
TextEditorWidget *openEditor(bool activate, int line, int column);
|
TextEditorWidget *openEditor(bool activate, int line, int column);
|
||||||
static RefactoringSelections rangesToSelections(QTextDocument *document,
|
|
||||||
const QList<Range> &ranges);
|
|
||||||
|
|
||||||
QTextDocument *mutableDocument() const;
|
QTextDocument *mutableDocument() const;
|
||||||
|
|
||||||
Utils::FilePath m_filePath;
|
Utils::FilePath m_filePath;
|
||||||
@@ -96,14 +88,12 @@ 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<Range> m_indentRanges;
|
|
||||||
QList<Range> m_reindentRanges;
|
|
||||||
QList<QTextCursor> m_formattingCursors;
|
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;
|
bool m_formattingEnabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT RefactoringFileFactory
|
class TEXTEDITOR_EXPORT RefactoringFileFactory
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "tabsettings.h"
|
#include "tabsettings.h"
|
||||||
|
|
||||||
|
#include "icodestylepreferences.h"
|
||||||
|
#include "texteditorsettings.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
@@ -347,4 +350,15 @@ bool TabSettings::equals(const TabSettings &ts) const
|
|||||||
&& m_continuationAlignBehavior == ts.m_continuationAlignBehavior;
|
&& m_continuationAlignBehavior == ts.m_continuationAlignBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TabSettings::Retriever g_retriever = [](const FilePath &) {
|
||||||
|
return TextEditorSettings::codeStyle()->tabSettings();
|
||||||
|
};
|
||||||
|
|
||||||
|
void TabSettings::setRetriever(const Retriever &retriever) { g_retriever = retriever; }
|
||||||
|
|
||||||
|
TabSettings TabSettings::settingsForFile(const Utils::FilePath &filePath)
|
||||||
|
{
|
||||||
|
return g_retriever(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
#include "texteditor_global.h"
|
#include "texteditor_global.h"
|
||||||
|
|
||||||
#include <utils/store.h>
|
#include <utils/filepath.h>
|
||||||
#include <utils/qtcsettings.h>
|
#include <utils/qtcsettings.h>
|
||||||
|
#include <utils/store.h>
|
||||||
|
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
|
||||||
// Tab settings: Data type the GeneralSettingsPage acts on
|
// Tab settings: Data type the GeneralSettingsPage acts on
|
||||||
@@ -71,6 +74,10 @@ public:
|
|||||||
ContinuationAlignBehavior m_continuationAlignBehavior = ContinuationAlignWithSpaces;
|
ContinuationAlignBehavior m_continuationAlignBehavior = ContinuationAlignWithSpaces;
|
||||||
|
|
||||||
bool equals(const TabSettings &ts) const;
|
bool equals(const TabSettings &ts) const;
|
||||||
|
|
||||||
|
using Retriever = std::function<TabSettings(const Utils::FilePath &)>;
|
||||||
|
static void setRetriever(const Retriever &retriever);
|
||||||
|
static TabSettings settingsForFile(const Utils::FilePath &filePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
|||||||
Reference in New Issue
Block a user