Beautifier: Merge Uncrustify style file pairs

Follow ArtisticStyle.

Change-Id: I599e70912a5895ce8c59a5b2df2f3ccb4b291d01
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2023-07-07 07:26:26 +02:00
parent c8d9b6f5aa
commit 60fb0fd902
6 changed files with 225 additions and 250 deletions

View File

@@ -19,5 +19,4 @@ add_qtc_plugin(Beautifier
generalsettings.cpp generalsettings.h generalsettings.cpp generalsettings.h
uncrustify/uncrustify.cpp uncrustify/uncrustify.h uncrustify/uncrustify.cpp uncrustify/uncrustify.h
uncrustify/uncrustifyconstants.h uncrustify/uncrustifyconstants.h
uncrustify/uncrustifysettings.cpp uncrustify/uncrustifysettings.h
) )

View File

@@ -58,8 +58,6 @@ QtcPlugin {
"uncrustify.cpp", "uncrustify.cpp",
"uncrustify.h", "uncrustify.h",
"uncrustifyconstants.h", "uncrustifyconstants.h",
"uncrustifysettings.cpp",
"uncrustifysettings.h"
] ]
} }
} }

View File

@@ -7,9 +7,11 @@
#include "uncrustifyconstants.h" #include "uncrustifyconstants.h"
#include "../abstractsettings.h"
#include "../beautifierconstants.h" #include "../beautifierconstants.h"
#include "../beautifierplugin.h" #include "../beautifierplugin.h"
#include "../beautifiertr.h" #include "../beautifiertr.h"
#include "../configurationpanel.h"
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
@@ -17,6 +19,7 @@
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
@@ -26,17 +29,223 @@
#include <texteditor/formattexteditor.h> #include <texteditor/formattexteditor.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <utils/filepath.h> #include <utils/aspects.h>
#include <utils/layoutbuilder.h>
#include <utils/pathchooser.h>
#include <utils/process.h>
#include <QAction> #include <QAction>
#include <QCheckBox>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu> #include <QMenu>
#include <QRegularExpression>
#include <QVersionNumber> #include <QVersionNumber>
#include <QXmlStreamWriter>
using namespace TextEditor; using namespace TextEditor;
using namespace Utils; using namespace Utils;
namespace Beautifier::Internal { namespace Beautifier::Internal {
const char SETTINGS_NAME[] = "uncrustify";
class UncrustifySettings : public AbstractSettings
{
public:
UncrustifySettings()
: AbstractSettings(SETTINGS_NAME, ".cfg")
{
setVersionRegExp(QRegularExpression("([0-9]{1})\\.([0-9]{2})"));
command.setDefaultValue("uncrustify");
command.setLabelText(Tr::tr("Uncrustify command:"));
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
Tr::tr(Constants::UNCRUSTIFY_DISPLAY_NAME)));
useOtherFiles.setSettingsKey("useOtherFiles");
useOtherFiles.setDefaultValue(true);
useOtherFiles.setLabelText(Tr::tr("Use file uncrustify.cfg defined in project files"));
useHomeFile.setSettingsKey("useHomeFile");
useHomeFile.setLabelText(Tr::tr("Use file uncrustify.cfg in HOME")
.replace( "HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
useCustomStyle.setSettingsKey("useCustomStyle");
useCustomStyle.setLabelText(Tr::tr("Use customized style:"));
useSpecificConfigFile.setSettingsKey("useSpecificConfigFile");
useSpecificConfigFile.setLabelText(Tr::tr("Use file specific uncrustify.cfg"));
customStyle.setSettingsKey("customStyle");
formatEntireFileFallback.setSettingsKey("formatEntireFileFallback");
formatEntireFileFallback.setDefaultValue(true);
formatEntireFileFallback.setLabelText(Tr::tr("Format entire file if no text was selected"));
formatEntireFileFallback.setToolTip(Tr::tr("For action Format Selected Text"));
specificConfigFile.setSettingsKey("specificConfigFile");
specificConfigFile.setExpectedKind(Utils::PathChooser::File);
specificConfigFile.setPromptDialogFilter(Tr::tr("Uncrustify file (*.cfg)"));
documentationFilePath = Core::ICore::userResourcePath(Constants::SETTINGS_DIRNAME)
.pathAppended(Constants::DOCUMENTATION_DIRNAME)
.pathAppended(SETTINGS_NAME).stringAppended(".xml");
read();
}
void createDocumentationFile() const override
{
Process process;
process.setTimeoutS(2);
process.setCommand({command(), {"--show-config"}});
process.runBlocking();
if (process.result() != ProcessResult::FinishedWithSuccess)
return;
QFile file(documentationFilePath.toFSPathString());
const QFileInfo fi(file);
if (!fi.exists())
fi.dir().mkpath(fi.absolutePath());
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
return;
bool contextWritten = false;
QXmlStreamWriter stream(&file);
stream.setAutoFormatting(true);
stream.writeStartDocument("1.0", true);
stream.writeComment("Created " + QDateTime::currentDateTime().toString(Qt::ISODate));
stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT);
const QStringList lines = process.allOutput().split(QLatin1Char('\n'));
const int totalLines = lines.count();
for (int i = 0; i < totalLines; ++i) {
const QString &line = lines.at(i);
if (line.startsWith('#') || line.trimmed().isEmpty())
continue;
const int firstSpace = line.indexOf(' ');
const QString keyword = line.left(firstSpace);
const QString options = line.right(line.size() - firstSpace).trimmed();
QStringList docu;
while (++i < totalLines) {
const QString &subline = lines.at(i);
if (line.startsWith('#') || subline.trimmed().isEmpty()) {
const QString text = "<p><span class=\"option\">" + keyword
+ "</span> <span class=\"param\">" + options
+ "</span></p><p>" + docu.join(' ').toHtmlEscaped() + "</p>";
stream.writeStartElement(Constants::DOCUMENTATION_XMLENTRY);
stream.writeTextElement(Constants::DOCUMENTATION_XMLKEY, keyword);
stream.writeTextElement(Constants::DOCUMENTATION_XMLDOC, text);
stream.writeEndElement();
contextWritten = true;
break;
} else {
docu << subline;
}
}
}
stream.writeEndElement();
stream.writeEndDocument();
// An empty file causes error messages and a contextless file preventing this function to run
// again in order to generate the documentation successfully. Thus delete the file.
if (!contextWritten) {
file.close();
file.remove();
}
}
BoolAspect useOtherFiles{this};
BoolAspect useHomeFile{this};
BoolAspect useCustomStyle{this};
StringAspect customStyle{this};
BoolAspect formatEntireFileFallback{this};
FilePathAspect specificConfigFile{this};
BoolAspect useSpecificConfigFile{this};
};
static UncrustifySettings &settings()
{
static UncrustifySettings theSettings;
return theSettings;
}
class UncrustifyOptionsPageWidget : public Core::IOptionsPageWidget
{
public:
explicit UncrustifyOptionsPageWidget()
{
UncrustifySettings &s = settings();
auto configurations = new ConfigurationPanel(this);
configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
configurations->setSettings(&settings());
configurations->setCurrentConfiguration(settings().customStyle());
QGroupBox *options = nullptr;
using namespace Layouting;
Column {
Group {
title(Tr::tr("Configuration")),
Form {
s.command, br,
s.supportedMimeTypes,
}
},
Group {
title(Tr::tr("Options")),
bindTo(&options),
Column {
s.useOtherFiles,
Row { s.useSpecificConfigFile, s.specificConfigFile },
s.useHomeFile,
Row { s.useCustomStyle, configurations },
s.formatEntireFileFallback
},
},
st
}.attachTo(this);
s.read();
connect(s.command.pathChooser(), &PathChooser::validChanged, options, &QWidget::setEnabled);
options->setEnabled(s.command.pathChooser()->isValid());
setOnApply([&s, configurations] {
s.customStyle.setValue(configurations->currentConfiguration());
s.save();
});
}
};
class UncrustifyOptionsPage final : public Core::IOptionsPage
{
public:
UncrustifyOptionsPage()
{
setId("Uncrustify");
setDisplayName(Tr::tr("Uncrustify"));
setCategory(Constants::OPTION_CATEGORY);
setWidgetCreator([] { return new UncrustifyOptionsPageWidget; });
}
};
const UncrustifyOptionsPage settingsPage;
// Uncrustify
Uncrustify::Uncrustify() Uncrustify::Uncrustify()
{ {
Core::ActionContainer *menu = Core::ActionManager::createMenu("Uncrustify.Menu"); Core::ActionContainer *menu = Core::ActionManager::createMenu("Uncrustify.Menu");
@@ -55,7 +264,7 @@ Uncrustify::Uncrustify()
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
connect(&m_settings.supportedMimeTypes, &Utils::BaseAspect::changed, connect(&settings().supportedMimeTypes, &Utils::BaseAspect::changed,
this, [this] { updateActions(Core::EditorManager::currentEditor()); }); this, [this] { updateActions(Core::EditorManager::currentEditor()); });
} }
@@ -66,7 +275,7 @@ QString Uncrustify::id() const
void Uncrustify::updateActions(Core::IEditor *editor) void Uncrustify::updateActions(Core::IEditor *editor)
{ {
const bool enabled = editor && m_settings.isApplicable(editor->document()); const bool enabled = editor && settings().isApplicable(editor->document());
m_formatFile->setEnabled(enabled); m_formatFile->setEnabled(enabled);
m_formatRange->setEnabled(enabled); m_formatRange->setEnabled(enabled);
} }
@@ -108,17 +317,17 @@ void Uncrustify::formatSelectedText()
tc.movePosition(QTextCursor::EndOfLine); tc.movePosition(QTextCursor::EndOfLine);
const int endPos = tc.position(); const int endPos = tc.position();
formatCurrentFile(command(cfgFileName, true), startPos, endPos); formatCurrentFile(command(cfgFileName, true), startPos, endPos);
} else if (m_settings.formatEntireFileFallback()) { } else if (settings().formatEntireFileFallback()) {
formatFile(); formatFile();
} }
} }
FilePath Uncrustify::configurationFile() const FilePath Uncrustify::configurationFile() const
{ {
if (m_settings.useCustomStyle()) if (settings().useCustomStyle())
return FilePath::fromUserInput(m_settings.styleFileName(m_settings.customStyle())); return FilePath::fromUserInput(settings().styleFileName(settings().customStyle()));
if (m_settings.useOtherFiles()) { if (settings().useOtherFiles()) {
using namespace ProjectExplorer; using namespace ProjectExplorer;
if (const Project *project = ProjectTree::currentProject()) { if (const Project *project = ProjectTree::currentProject()) {
const FilePaths files = project->files([](const Node *n) { const FilePaths files = project->files([](const Node *n) {
@@ -130,13 +339,13 @@ FilePath Uncrustify::configurationFile() const
} }
} }
if (m_settings.useSpecificConfigFile()) { if (settings().useSpecificConfigFile()) {
const FilePath file = m_settings.specificConfigFile(); const FilePath file = settings().specificConfigFile();
if (file.exists()) if (file.exists())
return file; return file;
} }
if (m_settings.useHomeFile()) { if (settings().useHomeFile()) {
const FilePath file = FileUtils::homePath() / "uncrustify.cfg"; const FilePath file = FileUtils::homePath() / "uncrustify.cfg";
if (file.exists()) if (file.exists())
return file; return file;
@@ -153,15 +362,15 @@ Command Uncrustify::command() const
bool Uncrustify::isApplicable(const Core::IDocument *document) const bool Uncrustify::isApplicable(const Core::IDocument *document) const
{ {
return m_settings.isApplicable(document); return settings().isApplicable(document);
} }
Command Uncrustify::command(const FilePath &cfgFile, bool fragment) const Command Uncrustify::command(const FilePath &cfgFile, bool fragment) const
{ {
Command command; Command command;
command.setExecutable(m_settings.command()); command.setExecutable(settings().command());
command.setProcessing(Command::PipeProcessing); command.setProcessing(Command::PipeProcessing);
if (m_settings.version() >= QVersionNumber(0, 62)) { if (settings().version() >= QVersionNumber(0, 62)) {
command.addOption("--assume"); command.addOption("--assume");
command.addOption("%file"); command.addOption("%file");
} else { } else {

View File

@@ -5,7 +5,9 @@
#include "../beautifierabstracttool.h" #include "../beautifierabstracttool.h"
#include "uncrustifysettings.h" QT_BEGIN_NAMESPACE
class QAction;
QT_END_NAMESPACE
namespace Beautifier::Internal { namespace Beautifier::Internal {
@@ -27,8 +29,6 @@ private:
QAction *m_formatFile = nullptr; QAction *m_formatFile = nullptr;
QAction *m_formatRange = nullptr; QAction *m_formatRange = nullptr;
UncrustifySettings m_settings;
UncrustifyOptionsPage m_page{&m_settings};
}; };
} // Beautifier::Internal } // Beautifier::Internal

View File

@@ -1,197 +0,0 @@
// Copyright (C) 2016 Lorenz Haas
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "uncrustifysettings.h"
#include "uncrustifyconstants.h"
#include "../beautifierconstants.h"
#include "../beautifierplugin.h"
#include "../beautifiertr.h"
#include "../configurationpanel.h"
#include <coreplugin/icore.h>
#include <utils/layoutbuilder.h>
#include <utils/pathchooser.h>
#include <utils/process.h>
#include <QCheckBox>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QRegularExpression>
#include <QXmlStreamWriter>
using namespace Utils;
namespace Beautifier::Internal {
const char SETTINGS_NAME[] = "uncrustify";
UncrustifySettings::UncrustifySettings()
: AbstractSettings(SETTINGS_NAME, ".cfg")
{
setVersionRegExp(QRegularExpression("([0-9]{1})\\.([0-9]{2})"));
command.setDefaultValue("uncrustify");
command.setLabelText(Tr::tr("Uncrustify command:"));
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
Tr::tr(Constants::UNCRUSTIFY_DISPLAY_NAME)));
useOtherFiles.setSettingsKey("useOtherFiles");
useOtherFiles.setDefaultValue(true);
useOtherFiles.setLabelText(Tr::tr("Use file uncrustify.cfg defined in project files"));
useHomeFile.setSettingsKey("useHomeFile");
useHomeFile.setLabelText(Tr::tr("Use file uncrustify.cfg in HOME")
.replace( "HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
useCustomStyle.setSettingsKey("useCustomStyle");
useCustomStyle.setLabelText(Tr::tr("Use customized style:"));
useSpecificConfigFile.setSettingsKey("useSpecificConfigFile");
useSpecificConfigFile.setLabelText(Tr::tr("Use file specific uncrustify.cfg"));
customStyle.setSettingsKey("customStyle");
formatEntireFileFallback.setSettingsKey("formatEntireFileFallback");
formatEntireFileFallback.setDefaultValue(true);
formatEntireFileFallback.setLabelText(Tr::tr("Format entire file if no text was selected"));
formatEntireFileFallback.setToolTip(Tr::tr("For action Format Selected Text"));
specificConfigFile.setSettingsKey("specificConfigFile");
specificConfigFile.setExpectedKind(Utils::PathChooser::File);
specificConfigFile.setPromptDialogFilter(Tr::tr("Uncrustify file (*.cfg)"));
documentationFilePath = Core::ICore::userResourcePath(Constants::SETTINGS_DIRNAME)
.pathAppended(Constants::DOCUMENTATION_DIRNAME)
.pathAppended(SETTINGS_NAME).stringAppended(".xml");
read();
}
void UncrustifySettings::createDocumentationFile() const
{
Process process;
process.setTimeoutS(2);
process.setCommand({command(), {"--show-config"}});
process.runBlocking();
if (process.result() != ProcessResult::FinishedWithSuccess)
return;
QFile file(documentationFilePath.toFSPathString());
const QFileInfo fi(file);
if (!fi.exists())
fi.dir().mkpath(fi.absolutePath());
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
return;
bool contextWritten = false;
QXmlStreamWriter stream(&file);
stream.setAutoFormatting(true);
stream.writeStartDocument("1.0", true);
stream.writeComment("Created " + QDateTime::currentDateTime().toString(Qt::ISODate));
stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT);
const QStringList lines = process.allOutput().split(QLatin1Char('\n'));
const int totalLines = lines.count();
for (int i = 0; i < totalLines; ++i) {
const QString &line = lines.at(i);
if (line.startsWith('#') || line.trimmed().isEmpty())
continue;
const int firstSpace = line.indexOf(' ');
const QString keyword = line.left(firstSpace);
const QString options = line.right(line.size() - firstSpace).trimmed();
QStringList docu;
while (++i < totalLines) {
const QString &subline = lines.at(i);
if (line.startsWith('#') || subline.trimmed().isEmpty()) {
const QString text = "<p><span class=\"option\">" + keyword
+ "</span> <span class=\"param\">" + options
+ "</span></p><p>" + docu.join(' ').toHtmlEscaped() + "</p>";
stream.writeStartElement(Constants::DOCUMENTATION_XMLENTRY);
stream.writeTextElement(Constants::DOCUMENTATION_XMLKEY, keyword);
stream.writeTextElement(Constants::DOCUMENTATION_XMLDOC, text);
stream.writeEndElement();
contextWritten = true;
break;
} else {
docu << subline;
}
}
}
stream.writeEndElement();
stream.writeEndDocument();
// An empty file causes error messages and a contextless file preventing this function to run
// again in order to generate the documentation successfully. Thus delete the file.
if (!contextWritten) {
file.close();
file.remove();
}
}
class UncrustifyOptionsPageWidget : public Core::IOptionsPageWidget
{
public:
explicit UncrustifyOptionsPageWidget(UncrustifySettings *settings)
{
UncrustifySettings &s = *settings;
auto configurations = new ConfigurationPanel(this);
configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
configurations->setSettings(settings);
configurations->setCurrentConfiguration(settings->customStyle());
QGroupBox *options = nullptr;
using namespace Layouting;
Column {
Group {
title(Tr::tr("Configuration")),
Form {
s.command, br,
s.supportedMimeTypes,
}
},
Group {
title(Tr::tr("Options")),
bindTo(&options),
Column {
s.useOtherFiles,
Row { s.useSpecificConfigFile, s.specificConfigFile },
s.useHomeFile,
Row { s.useCustomStyle, configurations },
s.formatEntireFileFallback
},
},
st
}.attachTo(this);
s.read();
connect(s.command.pathChooser(), &PathChooser::validChanged, options, &QWidget::setEnabled);
options->setEnabled(s.command.pathChooser()->isValid());
setOnApply([&s, configurations] {
s.customStyle.setValue(configurations->currentConfiguration());
s.save();
});
}
};
UncrustifyOptionsPage::UncrustifyOptionsPage(UncrustifySettings *settings)
{
setId("Uncrustify");
setDisplayName(Tr::tr("Uncrustify"));
setCategory(Constants::OPTION_CATEGORY);
setWidgetCreator([settings] { return new UncrustifyOptionsPageWidget(settings); });
}
} // Beautifier::Internal

View File

@@ -1,34 +0,0 @@
// Copyright (C) 2016 Lorenz Haas
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "../abstractsettings.h"
namespace Beautifier::Internal {
class UncrustifySettings : public AbstractSettings
{
public:
UncrustifySettings();
void createDocumentationFile() const override;
Utils::BoolAspect useOtherFiles{this};
Utils::BoolAspect useHomeFile{this};
Utils::BoolAspect useCustomStyle{this};
Utils::StringAspect customStyle{this};
Utils::BoolAspect formatEntireFileFallback{this};
Utils::FilePathAspect specificConfigFile{this};
Utils::BoolAspect useSpecificConfigFile{this};
};
class UncrustifyOptionsPage final : public Core::IOptionsPage
{
public:
explicit UncrustifyOptionsPage(UncrustifySettings *settings);
};
} // Beautifier::Internal