forked from qt-creator/qt-creator
ClangFormat: Add the logical settings management
Now there are changeable and unchangeable settings, as it works for usual codestyle settings. They save parallel with codestyle settings but in another dir. In general, the behavior became similar to usual codestyle settings. ToDo: Make indenter use this settings instead standard one and instead project settings when "override" checkbox is checked. Change-Id: I639dbda296932bf9b967a11f1cc4fda120415ed9 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -43,7 +43,9 @@
|
|||||||
#include <extensionsystem/pluginspec.h>
|
#include <extensionsystem/pluginspec.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include <projectexplorer/editorconfiguration.h>
|
||||||
#include <texteditor/displaysettings.h>
|
#include <texteditor/displaysettings.h>
|
||||||
|
#include <texteditor/icodestylepreferences.h>
|
||||||
#include <texteditor/snippets/snippeteditor.h>
|
#include <texteditor/snippets/snippeteditor.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
@@ -100,19 +102,22 @@ bool ClangFormatConfigWidget::eventFilter(QObject *object, QEvent *event)
|
|||||||
return QWidget::eventFilter(object, event);
|
return QWidget::eventFilter(object, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *project, QWidget *parent)
|
ClangFormatConfigWidget::ClangFormatConfigWidget(TextEditor::ICodeStylePreferences *codeStyle,
|
||||||
|
ProjectExplorer::Project *project,
|
||||||
|
QWidget *parent)
|
||||||
: CppCodeStyleWidget(parent)
|
: CppCodeStyleWidget(parent)
|
||||||
, m_project(project)
|
, m_project(project)
|
||||||
, m_checks(std::make_unique<Ui::ClangFormatChecksWidget>())
|
, m_checks(std::make_unique<Ui::ClangFormatChecksWidget>())
|
||||||
, m_ui(std::make_unique<Ui::ClangFormatConfigWidget>())
|
, m_ui(std::make_unique<Ui::ClangFormatConfigWidget>())
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
setEnabled(!codeStyle->isReadOnly());
|
||||||
|
|
||||||
Utils::FilePath filePath = Core::ICore::userResourcePath();
|
Utils::FilePath filePath = Core::ICore::userResourcePath();
|
||||||
if (m_project)
|
filePath = filePath / "clang-format/"
|
||||||
filePath = filePath / "clang-format/" / currentProjectUniqueId();
|
/ Utils::FileUtils::fileSystemFriendlyName(codeStyle->displayName())
|
||||||
filePath = filePath / QLatin1String(Constants::SETTINGS_FILE_NAME);
|
/ QLatin1String(Constants::SETTINGS_FILE_NAME);
|
||||||
m_config = std::make_unique<ClangFormatFile>(filePath);
|
m_config = std::make_unique<ClangFormatFile>(filePath, codeStyle->isReadOnly());
|
||||||
|
|
||||||
initChecksAndPreview();
|
initChecksAndPreview();
|
||||||
showCombobox();
|
showCombobox();
|
||||||
@@ -329,8 +334,7 @@ void ClangFormatConfigWidget::fillTable()
|
|||||||
Utils::ExecuteOnDestruction executeOnDestruction([this]() { m_disableTableUpdate = false; });
|
Utils::ExecuteOnDestruction executeOnDestruction([this]() { m_disableTableUpdate = false; });
|
||||||
m_disableTableUpdate = true;
|
m_disableTableUpdate = true;
|
||||||
|
|
||||||
const std::string configText = m_project ? currentProjectConfigText()
|
const std::string configText = readFile(m_config->filePath().path());
|
||||||
: currentGlobalConfigText();
|
|
||||||
|
|
||||||
for (QObject *child : m_checksWidget->children()) {
|
for (QObject *child : m_checksWidget->children()) {
|
||||||
if (!qobject_cast<QComboBox *>(child) && !qobject_cast<QLineEdit *>(child)
|
if (!qobject_cast<QComboBox *>(child) && !qobject_cast<QLineEdit *>(child)
|
||||||
|
@@ -48,7 +48,8 @@ class ClangFormatConfigWidget : public CppEditor::CppCodeStyleWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ClangFormatConfigWidget(ProjectExplorer::Project *project = nullptr,
|
explicit ClangFormatConfigWidget(TextEditor::ICodeStylePreferences *codeStyle,
|
||||||
|
ProjectExplorer::Project *project = nullptr,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~ClangFormatConfigWidget() override;
|
~ClangFormatConfigWidget() override;
|
||||||
void apply() override;
|
void apply() override;
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "clangformatfile.h"
|
#include "clangformatfile.h"
|
||||||
#include "clangformatsettings.h"
|
#include "clangformatsettings.h"
|
||||||
|
#include "clangformatutils.h"
|
||||||
#include <cppeditor/cppcodestylesettings.h>
|
#include <cppeditor/cppcodestylesettings.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <texteditor/tabsettings.h>
|
#include <texteditor/tabsettings.h>
|
||||||
@@ -34,11 +35,18 @@
|
|||||||
|
|
||||||
using namespace ClangFormat;
|
using namespace ClangFormat;
|
||||||
|
|
||||||
ClangFormatFile::ClangFormatFile(Utils::FilePath filePath)
|
ClangFormatFile::ClangFormatFile(Utils::FilePath filePath, bool isReadOnly)
|
||||||
: m_filePath(filePath)
|
: m_filePath(filePath)
|
||||||
|
, m_isReadOnly(isReadOnly)
|
||||||
{
|
{
|
||||||
if (!m_filePath.exists()) {
|
if (!m_filePath.exists()) {
|
||||||
resetStyleToLLVM();
|
// create file and folder
|
||||||
|
m_filePath.parentDir().createDir();
|
||||||
|
std::fstream newStyleFile(m_filePath.path().toStdString(), std::fstream::out);
|
||||||
|
if (newStyleFile.is_open()) {
|
||||||
|
newStyleFile.close();
|
||||||
|
}
|
||||||
|
resetStyleToQtC();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +54,7 @@ ClangFormatFile::ClangFormatFile(Utils::FilePath filePath)
|
|||||||
const std::error_code error
|
const std::error_code error
|
||||||
= clang::format::parseConfiguration(m_filePath.fileContents().toStdString(), &m_style);
|
= clang::format::parseConfiguration(m_filePath.fileContents().toStdString(), &m_style);
|
||||||
if (error.value() != static_cast<int>(clang::format::ParseError::Success)) {
|
if (error.value() != static_cast<int>(clang::format::ParseError::Success)) {
|
||||||
resetStyleToLLVM();
|
resetStyleToQtC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +73,15 @@ void ClangFormatFile::setStyle(clang::format::FormatStyle style)
|
|||||||
saveNewFormat();
|
saveNewFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangFormatFile::resetStyleToLLVM()
|
bool ClangFormatFile::isReadOnly() const
|
||||||
{
|
{
|
||||||
m_style = clang::format::getLLVMStyle();
|
return m_isReadOnly;
|
||||||
saveNewFormat();
|
}
|
||||||
|
|
||||||
|
void ClangFormatFile::resetStyleToQtC()
|
||||||
|
{
|
||||||
|
m_style = qtcStyle();
|
||||||
|
saveStyleToFile(m_style, m_filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangFormatFile::setBasedOnStyle(QString styleName)
|
void ClangFormatFile::setBasedOnStyle(QString styleName)
|
||||||
@@ -107,17 +120,17 @@ QString ClangFormatFile::changeFields(QList<Field> fields)
|
|||||||
|
|
||||||
void ClangFormatFile::saveNewFormat()
|
void ClangFormatFile::saveNewFormat()
|
||||||
{
|
{
|
||||||
std::string style = clang::format::configurationAsText(m_style);
|
if (m_isReadOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
// workaround: configurationAsText() add comment "# " before BasedOnStyle line
|
saveStyleToFile(m_style, m_filePath);
|
||||||
const int pos = style.find("# BasedOnStyle");
|
|
||||||
if (pos != int(std::string::npos))
|
|
||||||
style.erase(pos, 2);
|
|
||||||
m_filePath.writeFileContents(QByteArray::fromStdString(style));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangFormatFile::saveNewFormat(QByteArray style)
|
void ClangFormatFile::saveNewFormat(QByteArray style)
|
||||||
{
|
{
|
||||||
|
if (m_isReadOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
m_filePath.writeFileContents(style);
|
m_filePath.writeFileContents(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,11 +37,11 @@ namespace ClangFormat {
|
|||||||
class ClangFormatFile
|
class ClangFormatFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ClangFormatFile(Utils::FilePath file);
|
explicit ClangFormatFile(Utils::FilePath file, bool isReadOnly);
|
||||||
clang::format::FormatStyle format();
|
clang::format::FormatStyle format();
|
||||||
|
|
||||||
Utils::FilePath filePath();
|
Utils::FilePath filePath();
|
||||||
void resetStyleToLLVM();
|
void resetStyleToQtC();
|
||||||
void setBasedOnStyle(QString styleName);
|
void setBasedOnStyle(QString styleName);
|
||||||
void setStyle(clang::format::FormatStyle style);
|
void setStyle(clang::format::FormatStyle style);
|
||||||
QString setStyle(QString style);
|
QString setStyle(QString style);
|
||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
TextEditor::TabSettings toTabSettings(ProjectExplorer::Project *project) const;
|
TextEditor::TabSettings toTabSettings(ProjectExplorer::Project *project) const;
|
||||||
void fromCppCodeStyleSettings(const CppEditor::CppCodeStyleSettings &settings);
|
void fromCppCodeStyleSettings(const CppEditor::CppCodeStyleSettings &settings);
|
||||||
void fromTabSettings(const TextEditor::TabSettings &settings);
|
void fromTabSettings(const TextEditor::TabSettings &settings);
|
||||||
|
bool isReadOnly() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveNewFormat();
|
void saveNewFormat();
|
||||||
@@ -62,6 +63,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
Utils::FilePath m_filePath;
|
Utils::FilePath m_filePath;
|
||||||
clang::format::FormatStyle m_style;
|
clang::format::FormatStyle m_style;
|
||||||
|
const bool m_isReadOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangFormat
|
} // namespace ClangFormat
|
||||||
|
@@ -84,11 +84,13 @@ public:
|
|||||||
return new ClangFormatIndenter(doc);
|
return new ClangFormatIndenter(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CppEditor::CppCodeStyleWidget *, QString> additionalTab(QWidget *parent) const override
|
std::pair<CppEditor::CppCodeStyleWidget *, QString> additionalTab(
|
||||||
|
TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const override
|
||||||
{
|
{
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return {new ClangFormatConfigWidget(), tr("ClangFormat")};
|
return {new ClangFormatConfigWidget(codeStyle), tr("ClangFormat")};
|
||||||
return {new ClangFormatConfigWidget(SessionManager::startupProject()), tr("ClangFormat")};
|
return {new ClangFormatConfigWidget(codeStyle, SessionManager::startupProject()),
|
||||||
|
tr("ClangFormat")};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -200,6 +200,17 @@ QString currentProjectUniqueId()
|
|||||||
.toHex(0));
|
.toHex(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveStyleToFile(clang::format::FormatStyle style, Utils::FilePath filePath)
|
||||||
|
{
|
||||||
|
std::string styleStr = clang::format::configurationAsText(style);
|
||||||
|
|
||||||
|
// workaround: configurationAsText() add comment "# " before BasedOnStyle line
|
||||||
|
const int pos = styleStr.find("# BasedOnStyle");
|
||||||
|
if (pos != int(std::string::npos))
|
||||||
|
styleStr.erase(pos, 2);
|
||||||
|
filePath.writeFileContents(QByteArray::fromStdString(styleStr));
|
||||||
|
}
|
||||||
|
|
||||||
static bool useProjectOverriddenSettings()
|
static bool useProjectOverriddenSettings()
|
||||||
{
|
{
|
||||||
const Project *project = SessionManager::startupProject();
|
const Project *project = SessionManager::startupProject();
|
||||||
@@ -371,7 +382,7 @@ void addQtcStatementMacros(clang::format::FormatStyle &style)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string readFile(const QString &path)
|
std::string readFile(const QString &path)
|
||||||
{
|
{
|
||||||
const std::string defaultStyle = clang::format::configurationAsText(qtcStyle());
|
const std::string defaultStyle = clang::format::configurationAsText(qtcStyle());
|
||||||
|
|
||||||
|
@@ -46,10 +46,12 @@ std::string currentGlobalConfigText();
|
|||||||
|
|
||||||
clang::format::FormatStyle currentProjectStyle();
|
clang::format::FormatStyle currentProjectStyle();
|
||||||
clang::format::FormatStyle currentGlobalStyle();
|
clang::format::FormatStyle currentGlobalStyle();
|
||||||
|
std::string readFile(const QString &path);
|
||||||
|
|
||||||
// Is the style from the matching .clang-format file or global one if it's not found.
|
// Is the style from the matching .clang-format file or global one if it's not found.
|
||||||
QString configForFile(Utils::FilePath fileName);
|
QString configForFile(Utils::FilePath fileName);
|
||||||
clang::format::FormatStyle styleForFile(Utils::FilePath fileName);
|
clang::format::FormatStyle styleForFile(Utils::FilePath fileName);
|
||||||
|
void saveStyleToFile(clang::format::FormatStyle style, Utils::FilePath filePath);
|
||||||
|
|
||||||
void addQtcStatementMacros(clang::format::FormatStyle &style);
|
void addQtcStatementMacros(clang::format::FormatStyle &style);
|
||||||
clang::format::FormatStyle qtcStyle();
|
clang::format::FormatStyle qtcStyle();
|
||||||
|
@@ -109,7 +109,7 @@ TextEditor::CodeStyleEditorWidget *CppCodeStylePreferencesFactory::createEditor(
|
|||||||
widget->layout()->setContentsMargins(0, 0, 0, 0);
|
widget->layout()->setContentsMargins(0, 0, 0, 0);
|
||||||
widget->setCodeStyle(cppPreferences);
|
widget->setCodeStyle(cppPreferences);
|
||||||
|
|
||||||
const auto tab = additionalTab(parent);
|
const auto tab = additionalTab(preferences, parent);
|
||||||
widget->addTab(tab.first, tab.second);
|
widget->addTab(tab.first, tab.second);
|
||||||
|
|
||||||
return widget;
|
return widget;
|
||||||
@@ -131,8 +131,9 @@ QString CppCodeStylePreferencesFactory::previewText() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CppCodeStyleWidget *, QString> CppCodeStylePreferencesFactory::additionalTab(
|
std::pair<CppCodeStyleWidget *, QString> CppCodeStylePreferencesFactory::additionalTab(
|
||||||
QWidget *parent) const
|
TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(codeStyle)
|
||||||
Q_UNUSED(parent)
|
Q_UNUSED(parent)
|
||||||
return {nullptr, ""};
|
return {nullptr, ""};
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,8 @@ public:
|
|||||||
TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
|
TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
|
||||||
QString snippetProviderGroupId() const override;
|
QString snippetProviderGroupId() const override;
|
||||||
QString previewText() const override;
|
QString previewText() const override;
|
||||||
virtual std::pair<CppCodeStyleWidget *, QString> additionalTab(QWidget *parent) const;
|
virtual std::pair<CppCodeStyleWidget *, QString> additionalTab(
|
||||||
|
TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppEditor
|
} // namespace CppEditor
|
||||||
|
@@ -104,6 +104,7 @@ CodeStyleDialog::CodeStyleDialog(ICodeStylePreferencesFactory *factory,
|
|||||||
m_codeStyle->setValue(codeStyle->value());
|
m_codeStyle->setValue(codeStyle->value());
|
||||||
m_codeStyle->setId(codeStyle->id());
|
m_codeStyle->setId(codeStyle->id());
|
||||||
m_codeStyle->setDisplayName(m_originalDisplayName);
|
m_codeStyle->setDisplayName(m_originalDisplayName);
|
||||||
|
m_codeStyle->setReadOnly(codeStyle->isReadOnly());
|
||||||
TextEditor::CodeStyleEditorWidget *editor = factory->createEditor(m_codeStyle, this);
|
TextEditor::CodeStyleEditorWidget *editor = factory->createEditor(m_codeStyle, this);
|
||||||
|
|
||||||
m_buttons = new QDialogButtonBox(
|
m_buttons = new QDialogButtonBox(
|
||||||
|
Reference in New Issue
Block a user