Beautifier: Add new class Command and option to format text via piping

The tool's formatting command is now enclosed in Command. For the
formatting itself it can be defined whether to use a temporary file or
the pipe.
Additionally, settings can return the current tool's version - if
needed.

Change-Id: I0e242c3e8016ed77cad92cc97a19fe3384dda858
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Lorenz Haas
2014-05-11 19:59:46 +02:00
committed by David Schulz
parent af5b3246cf
commit ca433d9b2f
14 changed files with 351 additions and 64 deletions

View File

@@ -44,7 +44,8 @@ namespace Beautifier {
namespace Internal {
AbstractSettings::AbstractSettings(const QString &name, const QString &ending)
: m_name(name)
: m_version(0)
, m_name(name)
, m_ending(ending)
, m_styleDir(Core::ICore::userResourcePath() + QLatin1Char('/')
+ QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/')
@@ -135,6 +136,18 @@ void AbstractSettings::setCommand(const QString &command)
return;
m_command = command;
updateVersion();
}
int AbstractSettings::version() const
{
return m_version;
}
void AbstractSettings::updateVersion()
{
// If a beautifier needs to know the current tool's version, reimplement and store the version
// in m_version.
}
QStringList AbstractSettings::options()

View File

@@ -67,6 +67,8 @@ public:
QString command() const;
void setCommand(const QString &command);
int version() const;
virtual void updateVersion();
QStringList options();
QString documentation(const QString &option) const;
@@ -74,6 +76,7 @@ public:
protected:
QMap<QString, QString> m_styles;
QMap<QString, QVariant> m_settings;
int m_version;
void readDocumentation();

View File

@@ -27,6 +27,8 @@
**
****************************************************************************/
// Tested with version 2.01, 2.02, 2.02.1, 2.03 and 2.04
#include "artisticstyle.h"
#include "artisticstyleconstants.h"
@@ -35,6 +37,7 @@
#include "../beautifierconstants.h"
#include "../beautifierplugin.h"
#include "../command.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -136,11 +139,19 @@ void ArtisticStyle::formatFile()
BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile(
QLatin1String(Constants::ArtisticStyle::DISPLAY_NAME)));
} else {
BeautifierPlugin::formatCurrentFile(QStringList()
<< m_settings->command()
<< QLatin1String("-q")
<< QLatin1String("--options=") + cfgFileName
<< QLatin1String("%file"));
Command command;
command.setExecutable(m_settings->command());
command.addOption(QLatin1String("-q"));
command.addOption(QLatin1String("--options=") + cfgFileName);
if (m_settings->version() > ArtisticStyleSettings::Version_2_03) {
command.setProcessing(Command::PipeProcessing);
command.setPipeAddsNewline(true);
} else {
command.addOption(QLatin1String("%file"));
}
BeautifierPlugin::formatCurrentFile(command);
}
}

View File

@@ -39,6 +39,7 @@
#include <QFile>
#include <QFileInfo>
#include <QProcess>
#include <QtConcurrent>
#include <QTextDocument> // Qt::escape() in Qt 4
#include <QXmlStreamWriter>
@@ -57,6 +58,8 @@ ArtisticStyleSettings::ArtisticStyleSettings() :
AbstractSettings(QLatin1String(Constants::ArtisticStyle::SETTINGS_NAME),
QLatin1String(".astyle"))
{
connect(&m_versionWatcher, SIGNAL(finished()), this, SLOT(helperSetVersion()));
setCommand(QLatin1String("astyle"));
m_settings.insert(QLatin1String(kUseOtherFiles), QVariant(true));
m_settings.insert(QLatin1String(kUseHomeFile), QVariant(false));
@@ -65,6 +68,40 @@ ArtisticStyleSettings::ArtisticStyleSettings() :
read();
}
void ArtisticStyleSettings::updateVersion()
{
if (m_versionFuture.isRunning())
m_versionFuture.cancel();
m_versionFuture = QtConcurrent::run(this, &ArtisticStyleSettings::helperUpdateVersion);
m_versionWatcher.setFuture(m_versionFuture);
}
int ArtisticStyleSettings::helperUpdateVersion() const
{
QProcess process;
process.start(command(), QStringList() << QLatin1String("--version"));
if (!process.waitForFinished()) {
process.kill();
return 0;
}
// The version in Artistic Style is printed like "Artistic Style Version 2.04"
const QString version = QString::fromUtf8(process.readAllStandardError()).trimmed();
const QRegExp rx(QLatin1String("([2-9]{1})\\.([0-9]{2})(\\.[1-9]{1})?$"));
if (rx.indexIn(version) != -1) {
const int major = rx.cap(1).toInt() * 100;
const int minor = rx.cap(2).toInt();
return major + minor;
}
return 0;
}
void ArtisticStyleSettings::helperSetVersion()
{
m_version = m_versionWatcher.result();
}
bool ArtisticStyleSettings::useOtherFiles() const
{
return m_settings.value(QLatin1String(kUseOtherFiles)).toBool();

View File

@@ -34,15 +34,26 @@
#include <utils/qtcoverride.h>
#include <QFuture>
#include <QFutureWatcher>
namespace Beautifier {
namespace Internal {
namespace ArtisticStyle {
class ArtisticStyleSettings : public AbstractSettings
class ArtisticStyleSettings : public QObject, public AbstractSettings
{
Q_OBJECT
public:
enum ArtisticStyleVersion {
Version_2_03 = 203
};
ArtisticStyleSettings();
void updateVersion() QTC_OVERRIDE;
bool useOtherFiles() const;
void setUseOtherFiles(bool useOtherFiles);
@@ -57,6 +68,14 @@ public:
QString documentationFilePath() const QTC_OVERRIDE;
void createDocumentationFile() const QTC_OVERRIDE;
private slots:
void helperSetVersion();
private:
QFuture<int> m_versionFuture;
QFutureWatcher<int> m_versionWatcher;
int helperUpdateVersion() const;
};
} // namespace ArtisticStyle

View File

@@ -7,6 +7,7 @@ HEADERS += \
beautifierabstracttool.h \
beautifierconstants.h \
beautifierplugin.h \
command.h \
configurationdialog.h \
configurationeditor.h \
configurationpanel.h \
@@ -26,6 +27,7 @@ HEADERS += \
SOURCES += \
abstractsettings.cpp \
beautifierplugin.cpp \
command.cpp \
configurationdialog.cpp \
configurationeditor.cpp \
configurationpanel.cpp \

View File

@@ -22,6 +22,8 @@ QtcPlugin {
"beautifierconstants.h",
"beautifierplugin.cpp",
"beautifierplugin.h",
"command.cpp",
"command.h",
"configurationdialog.cpp",
"configurationdialog.h",
"configurationdialog.ui",

View File

@@ -30,6 +30,8 @@
#include "beautifierplugin.h"
#include "beautifierconstants.h"
#include "command.h"
#include "artisticstyle/artisticstyle.h"
#include "clangformat/clangformat.h"
#include "uncrustify/uncrustify.h"
@@ -116,14 +118,17 @@ void BeautifierPlugin::updateActions(Core::IEditor *editor)
m_tools.at(i)->updateActions(editor);
}
QString BeautifierPlugin::format(const QString &text, QStringList command, const QString &fileName)
QString BeautifierPlugin::format(const QString &text, const Command &command, const QString &fileName)
{
if (command.isEmpty())
const QString executable = command.executable();
if (executable.isEmpty())
return QString();
switch (command.processing()) {
case Command::FileProcessing: {
// Save text to temporary file
QFileInfo fi(fileName);
Utils::TempFileSaver sourceFile(fi.absolutePath() + QLatin1String("/qtc_beautifier_XXXXXXXX.")
Utils::TempFileSaver sourceFile(QDir::tempPath() + QLatin1String("/qtc_beautifier_XXXXXXXX.")
+ fi.suffix());
sourceFile.setAutoRemove(true);
sourceFile.write(text.toUtf8());
@@ -135,16 +140,16 @@ QString BeautifierPlugin::format(const QString &text, QStringList command, const
// Format temporary file
QProcess process;
command.replaceInStrings(QLatin1String("%file"), sourceFile.fileName());
const QString processProgram = command.takeFirst();
process.start(processProgram, command);
QStringList options = command.options();
options.replaceInStrings(QLatin1String("%file"), sourceFile.fileName());
process.start(executable, options);
if (!process.waitForFinished()) {
showError(tr("Cannot call %1 or some other error occurred.").arg(processProgram));
showError(tr("Cannot call %1 or some other error occurred.").arg(executable));
return QString();
}
const QByteArray output = process.readAllStandardError();
if (!output.isEmpty())
showError(processProgram + QLatin1String(": ") + QString::fromLocal8Bit(output));
showError(executable + QLatin1String(": ") + QString::fromUtf8(output));
// Read text back
Utils::FileReader reader;
@@ -154,9 +159,42 @@ QString BeautifierPlugin::format(const QString &text, QStringList command, const
return QString();
}
return QString::fromUtf8(reader.data());
} break;
case Command::PipeProcessing: {
QProcess process;
QStringList options = command.options();
options.replaceInStrings(QLatin1String("%file"), fileName);
process.start(executable, options);
if (!process.waitForStarted()) {
showError(tr("Cannot call %1 or some other error occurred.").arg(executable));
return QString();
}
process.write(text.toUtf8());
process.closeWriteChannel();
if (!process.waitForFinished()) {
showError(tr("Cannot call %1 or some other error occurred.").arg(executable));
return QString();
}
const QByteArray error = process.readAllStandardError();
if (!error.isEmpty()) {
showError(executable + QLatin1String(": ") + QString::fromUtf8(error));
return QString();
}
void BeautifierPlugin::formatCurrentFile(QStringList command)
if (command.pipeAddsNewline()) {
QString formatted = QString::fromUtf8(process.readAllStandardOutput());
formatted.remove(QRegExp(QLatin1String("(\\r\\n|\\n)$")));
return formatted;
}
return QString::fromUtf8(process.readAllStandardOutput());
}
}
return QString();
}
void BeautifierPlugin::formatCurrentFile(const Command &command)
{
QPlainTextEdit *textEditor = 0;
if (TextEditor::BaseTextEditor *editor

View File

@@ -39,6 +39,7 @@ namespace Beautifier {
namespace Internal {
class BeautifierAbstractTool;
class Command;
class BeautifierPlugin : public ExtensionSystem::IPlugin
{
@@ -52,8 +53,8 @@ public:
void extensionsInitialized() QTC_OVERRIDE;
ShutdownFlag aboutToShutdown() QTC_OVERRIDE;
static QString format(const QString &text, QStringList command, const QString &fileName);
static void formatCurrentFile(QStringList command);
static QString format(const QString &text, const Command &command, const QString &fileName);
static void formatCurrentFile(const Command &command);
static void showError(const QString &error);
static QString msgCannotGetConfigurationFile(const QString &command);

View File

@@ -27,6 +27,8 @@
**
****************************************************************************/
// Tested with version 3.3, 3.4 and 3.4.1
#include "clangformat.h"
#include "clangformatconstants.h"
@@ -125,22 +127,24 @@ void ClangFormat::formatSelectedText()
}
}
QStringList ClangFormat::command(int offset, int length) const
Command ClangFormat::command(int offset, int length) const
{
QStringList command;
command << m_settings->command();
command << QLatin1String("-i");
Command command;
command.setExecutable(m_settings->command());
command.setProcessing(Command::PipeProcessing);
if (m_settings->usePredefinedStyle()) {
command << QLatin1String("-style=") + m_settings->predefinedStyle();
command.addOption(QLatin1String("-style=") + m_settings->predefinedStyle());
} else {
command << QLatin1String("-style={") + m_settings->style(
m_settings->customStyle()).remove(QLatin1Char('\n')) + QLatin1String("}");
command.addOption(QLatin1String("-style={")
+ m_settings->style(m_settings->customStyle()).remove(QLatin1Char('\n'))
+ QLatin1String("}"));
}
if (offset != -1) {
command << QLatin1String("-offset=") + QString::number(offset);
command << QLatin1String("-length=") + QString::number(length);
command.addOption(QLatin1String("-offset=") + QString::number(offset));
command.addOption(QLatin1String("-length=") + QString::number(length));
}
command << QLatin1String("%file");
return command;
}

View File

@@ -31,6 +31,7 @@
#define BEAUTIFIER_CLANGFORMAT_H
#include "../beautifierabstracttool.h"
#include "../command.h"
#include <utils/qtcoverride.h>
@@ -61,7 +62,7 @@ private:
QAction *m_formatFile;
QAction *m_formatRange;
ClangFormatSettings *m_settings;
QStringList command(int offset = -1, int length = -1) const;
Command command(int offset = -1, int length = -1) const;
};
} // namespace ClangFormat

View File

@@ -0,0 +1,82 @@
/**************************************************************************
**
** Copyright (c) 2014 Lorenz Haas
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "command.h"
namespace Beautifier {
namespace Internal {
Command::Command()
: m_processing(FileProcessing)
, m_pipeAddsNewline(false)
{
}
QString Command::executable() const
{
return m_executable;
}
void Command::setExecutable(const QString &executable)
{
m_executable = executable;
}
QStringList Command::options() const
{
return m_options;
}
void Command::addOption(const QString &option)
{
m_options << option;
}
Command::Processing Command::processing() const
{
return m_processing;
}
void Command::setProcessing(const Processing &processing)
{
m_processing = processing;
}
bool Command::pipeAddsNewline() const
{
return m_pipeAddsNewline;
}
void Command::setPipeAddsNewline(bool pipeAddsNewline)
{
m_pipeAddsNewline = pipeAddsNewline;
}
} // namespace Internal
} // namespace Beautifier

View File

@@ -0,0 +1,71 @@
/**************************************************************************
**
** Copyright (c) 2014 Lorenz Haas
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef BEAUTIFIER_COMMAND_H
#define BEAUTIFIER_COMMAND_H
#include <QString>
#include <QStringList>
namespace Beautifier {
namespace Internal {
class Command
{
public:
enum Processing {
FileProcessing,
PipeProcessing
};
Command();
QString executable() const;
void setExecutable(const QString &executable);
QStringList options() const;
void addOption(const QString &option);
Processing processing() const;
void setProcessing(const Processing &processing);
bool pipeAddsNewline() const;
void setPipeAddsNewline(bool pipeAddsNewline);
private:
QString m_executable;
QStringList m_options;
Processing m_processing;
bool m_pipeAddsNewline;
};
} // namespace Internal
} // namespace Beautifier
#endif // BEAUTIFIER_COMMAND_H

View File

@@ -27,6 +27,8 @@
**
****************************************************************************/
// Tested with version 0.59 and 0.60
#include "uncrustify.h"
#include "uncrustifyconstants.h"
@@ -35,6 +37,7 @@
#include "../beautifierconstants.h"
#include "../beautifierplugin.h"
#include "../command.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -130,16 +133,16 @@ void Uncrustify::formatFile()
BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile(
QLatin1String(Constants::Uncrustify::DISPLAY_NAME)));
} else {
BeautifierPlugin::formatCurrentFile(QStringList()
<< m_settings->command()
<< QLatin1String("-l")
<< QLatin1String("cpp")
<< QLatin1String("-L")
<< QLatin1String("1-2")
<< QLatin1String("--no-backup")
<< QLatin1String("-c")
<< cfgFileName
<< QLatin1String("%file"));
Command command;
command.setExecutable(m_settings->command());
command.setProcessing(Command::PipeProcessing);
command.addOption(QLatin1String("-l"));
command.addOption(QLatin1String("cpp"));
command.addOption(QLatin1String("-L"));
command.addOption(QLatin1String("1-2"));
command.addOption(QLatin1String("-c"));
command.addOption(cfgFileName);
BeautifierPlugin::formatCurrentFile(command);
}
}