summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLorenz Haas <lykurg@gmail.com>2015-06-04 17:17:10 +0200
committerDavid Schulz <david.schulz@theqtcompany.com>2015-06-15 10:48:17 +0000
commitb0b9401870aff268561a076b15aa90ffe3ca52e2 (patch)
tree0e2f5d9c5a6eb5700734a95699489191680bb582 /src
parenta871e053b62240d2449d3ad7ca681ddbd1aedc86 (diff)
downloadqt-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.cpp53
-rw-r--r--src/plugins/beautifier/beautifierplugin.h10
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustify.cpp44
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustify.h4
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustifyconstants.h1
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";