diff options
author | Lorenz Haas <lykurg@gmail.com> | 2015-06-04 17:17:10 +0200 |
---|---|---|
committer | David Schulz <david.schulz@theqtcompany.com> | 2015-06-15 10:48:17 +0000 |
commit | b0b9401870aff268561a076b15aa90ffe3ca52e2 (patch) | |
tree | 0e2f5d9c5a6eb5700734a95699489191680bb582 /src | |
parent | a871e053b62240d2449d3ad7ca681ddbd1aedc86 (diff) | |
download | qt-creator-b0b9401870aff268561a076b15aa90ffe3ca52e2.tar.gz |
Beautifier: Support formatting specific lines of file with Uncrustify
It's now possible to format only a specific range of the current file.
The used tool, however, needs to support the formatting of fragments
like Uncrustify does with --frag.
Change-Id: I486a350b6301e4a087619b1e225f2a5c553ff7df
Reviewed-by: Jochen Becher <jochen_becher@gmx.de>
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/beautifier/beautifierplugin.cpp | 53 | ||||
-rw-r--r-- | src/plugins/beautifier/beautifierplugin.h | 10 | ||||
-rw-r--r-- | src/plugins/beautifier/uncrustify/uncrustify.cpp | 44 | ||||
-rw-r--r-- | src/plugins/beautifier/uncrustify/uncrustify.h | 4 | ||||
-rw-r--r-- | src/plugins/beautifier/uncrustify/uncrustifyconstants.h | 1 |
5 files changed, 86 insertions, 26 deletions
diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index c533aa59bd..cb258a2161 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -46,11 +46,13 @@ #include <coreplugin/icore.h> #include <coreplugin/messagemanager.h> #include <diffeditor/differ.h> +#include <texteditor/convenience.h> #include <texteditor/textdocument.h> #include <texteditor/textdocumentlayout.h> #include <texteditor/texteditor.h> #include <texteditor/texteditorconstants.h> #include <utils/fileutils.h> +#include <utils/qtcassert.h> #include <utils/QtConcurrentTools> #include <QAction> @@ -219,24 +221,28 @@ QString BeautifierPlugin::format(const QString &text, const Command &command, return QString(); } -void BeautifierPlugin::formatCurrentFile(const Command &command) +void BeautifierPlugin::formatCurrentFile(const Command &command, int startPos, int endPos) { - TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget(); - if (!widget) - return; - - const QString sourceData = widget->toPlainText(); - if (sourceData.isEmpty()) - return; - - QFutureWatcher<FormatTask> *watcher = new QFutureWatcher<FormatTask>; - connect(widget->textDocument(), &TextDocument::contentsChanged, - watcher, &QFutureWatcher<FormatTask>::cancel); - connect(watcher, SIGNAL(finished()), m_asyncFormatMapper, SLOT(map())); - m_asyncFormatMapper->setMapping(watcher, watcher); - const QString filePath = widget->textDocument()->filePath().toString(); - watcher->setFuture(QtConcurrent::run(&BeautifierPlugin::formatAsync, this, - FormatTask(widget, filePath, sourceData, command))); + QTC_ASSERT(startPos <= endPos, return); + + if (TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget()) { + if (const TextDocument *doc = widget->textDocument()) { + const QString sourceData = (startPos < 0) + ? widget->toPlainText() + : Convenience::textAt(widget->textCursor(), startPos, (endPos - startPos)); + if (sourceData.isEmpty()) + return; + const FormatTask task = FormatTask(widget, doc->filePath().toString(), sourceData, + command, startPos, endPos); + + QFutureWatcher<FormatTask> *watcher = new QFutureWatcher<FormatTask>; + connect(doc, &TextDocument::contentsChanged, + watcher, &QFutureWatcher<FormatTask>::cancel); + connect(watcher, SIGNAL(finished()), m_asyncFormatMapper, SLOT(map())); + m_asyncFormatMapper->setMapping(watcher, watcher); + watcher->setFuture(QtConcurrent::run(&BeautifierPlugin::formatAsync, this, task)); + } + } } void BeautifierPlugin::formatAsync(QFutureInterface<FormatTask> &future, FormatTask task) @@ -268,6 +274,11 @@ void BeautifierPlugin::formatCurrentFileContinue(QObject *watcher) return; } + if (task.formattedData.isEmpty()) { + showError(tr("Could not format file %1.").arg(task.filePath)); + return; + } + QPlainTextEdit *textEditor = task.editor; if (!textEditor) { showError(tr("File %1 was closed.").arg(task.filePath)); @@ -275,10 +286,14 @@ void BeautifierPlugin::formatCurrentFileContinue(QObject *watcher) } const QString sourceData = textEditor->toPlainText(); - const QString formattedData = task.formattedData; - if ((sourceData == formattedData) || formattedData.isEmpty()) + const QString formattedData = (task.startPos < 0) + ? task.formattedData + : QString(sourceData).replace(task.startPos, (task.endPos - task.startPos), + task.formattedData); + if (sourceData == formattedData) return; + // Since QTextCursor does not work properly with folded blocks, all blocks must be unfolded. // To restore the current state at the end, keep track of which block is folded. QList<int> foldedBlocks; diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h index f8d9517c21..3f7df9d7a4 100644 --- a/src/plugins/beautifier/beautifierplugin.h +++ b/src/plugins/beautifier/beautifierplugin.h @@ -50,19 +50,23 @@ class BeautifierAbstractTool; struct FormatTask { FormatTask(QPlainTextEdit *_editor, const QString &_filePath, const QString &_sourceData, - const Command &_command) : + const Command &_command, int _startPos = -1, int _endPos = 0) : editor(_editor), filePath(_filePath), sourceData(_sourceData), command(_command), + startPos(_startPos), + endPos(_endPos), timeout(false) {} QPointer<QPlainTextEdit> editor; QString filePath; QString sourceData; Command command; - QString formattedData; + int startPos; + int endPos; bool timeout; + QString formattedData; }; class BeautifierPlugin : public ExtensionSystem::IPlugin @@ -79,7 +83,7 @@ public: QString format(const QString &text, const Command &command, const QString &fileName, bool *timeout = 0); - void formatCurrentFile(const Command &command); + void formatCurrentFile(const Command &command, int startPos = -1, int endPos = 0); void formatAsync(QFutureInterface<FormatTask> &future, FormatTask task); static QString msgCannotGetConfigurationFile(const QString &command); diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index 594ee41784..b54d112275 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -38,7 +38,6 @@ #include "../beautifierconstants.h" #include "../beautifierplugin.h" -#include "../command.h" #include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actionmanager.h> @@ -51,6 +50,7 @@ #include <cppeditor/cppeditorconstants.h> #include <projectexplorer/projecttree.h> #include <projectexplorer/project.h> +#include <texteditor/texteditor.h> #include <utils/fileutils.h> #include <QAction> @@ -63,6 +63,8 @@ namespace Uncrustify { Uncrustify::Uncrustify(BeautifierPlugin *parent) : BeautifierAbstractTool(parent), m_beautifierPlugin(parent), + m_formatFile(nullptr), + m_formatRange(nullptr), m_settings(new UncrustifySettings) { } @@ -84,6 +86,12 @@ bool Uncrustify::initialize() menu->addAction(cmd); connect(m_formatFile, &QAction::triggered, this, &Uncrustify::formatFile); + m_formatRange = new QAction(BeautifierPlugin::msgFormatSelectedText(), this); + cmd = Core::ActionManager::registerAction(m_formatRange, + Constants::Uncrustify::ACTION_FORMATSELECTED); + menu->addAction(cmd); + connect(m_formatRange, &QAction::triggered, this, &Uncrustify::formatSelectedText); + Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); return true; @@ -91,7 +99,9 @@ bool Uncrustify::initialize() void Uncrustify::updateActions(Core::IEditor *editor) { - m_formatFile->setEnabled(editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID); + const bool enabled = (editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID); + m_formatFile->setEnabled(enabled); + m_formatRange->setEnabled(enabled); } QList<QObject *> Uncrustify::autoReleaseObjects() @@ -111,6 +121,32 @@ void Uncrustify::formatFile() } } +void Uncrustify::formatSelectedText() +{ + const QString cfgFileName = configurationFile(); + if (cfgFileName.isEmpty()) { + BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( + QLatin1String(Constants::Uncrustify::DISPLAY_NAME))); + return; + } + + TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + if (!widget) + return; + + QTextCursor tc = widget->textCursor(); + if (tc.hasSelection()) { + // Extend selection to full lines + const int posSelectionEnd = tc.selectionEnd(); + tc.movePosition(QTextCursor::StartOfLine); + const int startPos = tc.position(); + tc.setPosition(posSelectionEnd); + tc.movePosition(QTextCursor::EndOfLine); + const int endPos = tc.position(); + m_beautifierPlugin->formatCurrentFile(command(cfgFileName, true), startPos, endPos); + } +} + QString Uncrustify::configurationFile() const { if (m_settings->useCustomStyle()) @@ -140,7 +176,7 @@ QString Uncrustify::configurationFile() const return QString(); } -Command Uncrustify::command(const QString &cfgFile) const +Command Uncrustify::command(const QString &cfgFile, bool fragment) const { Command command; command.setExecutable(m_settings->command()); @@ -149,6 +185,8 @@ Command Uncrustify::command(const QString &cfgFile) const command.addOption(QLatin1String("cpp")); command.addOption(QLatin1String("-L")); command.addOption(QLatin1String("1-2")); + if (fragment) + command.addOption(QLatin1String("--frag")); command.addOption(QLatin1String("-c")); command.addOption(cfgFile); return command; diff --git a/src/plugins/beautifier/uncrustify/uncrustify.h b/src/plugins/beautifier/uncrustify/uncrustify.h index 64f6b08f98..070b2409b7 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.h +++ b/src/plugins/beautifier/uncrustify/uncrustify.h @@ -58,13 +58,15 @@ public: private slots: void formatFile(); + void formatSelectedText(); private: BeautifierPlugin *m_beautifierPlugin; QAction *m_formatFile; + QAction *m_formatRange; UncrustifySettings *m_settings; QString configurationFile() const; - Command command(const QString &cfgFile) const; + Command command(const QString &cfgFile, bool fragment = false) const; }; } // namespace Uncrustify diff --git a/src/plugins/beautifier/uncrustify/uncrustifyconstants.h b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h index c84c57f1f9..facfe28b52 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifyconstants.h +++ b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h @@ -37,6 +37,7 @@ namespace Uncrustify { const char DISPLAY_NAME[] = "Uncrustify"; const char ACTION_FORMATFILE[] = "Uncrustify.FormatFile"; +const char ACTION_FORMATSELECTED[] = "Uncrustify.FormatSelectedText"; const char MENU_ID[] = "Uncrustify.Menu"; const char OPTION_ID[] = "Uncrustify"; const char SETTINGS_NAME[] = "uncrustify"; |