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:
Artem Sokolovskii
2022-04-04 14:53:05 +02:00
parent ca7a18568c
commit 7574ec3e21
10 changed files with 67 additions and 29 deletions

View File

@@ -43,7 +43,9 @@
#include <extensionsystem/pluginspec.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <projectexplorer/editorconfiguration.h>
#include <texteditor/displaysettings.h>
#include <texteditor/icodestylepreferences.h>
#include <texteditor/snippets/snippeteditor.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditorsettings.h>
@@ -100,19 +102,22 @@ bool ClangFormatConfigWidget::eventFilter(QObject *object, QEvent *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)
, m_project(project)
, m_checks(std::make_unique<Ui::ClangFormatChecksWidget>())
, m_ui(std::make_unique<Ui::ClangFormatConfigWidget>())
{
m_ui->setupUi(this);
setEnabled(!codeStyle->isReadOnly());
Utils::FilePath filePath = Core::ICore::userResourcePath();
if (m_project)
filePath = filePath / "clang-format/" / currentProjectUniqueId();
filePath = filePath / QLatin1String(Constants::SETTINGS_FILE_NAME);
m_config = std::make_unique<ClangFormatFile>(filePath);
filePath = filePath / "clang-format/"
/ Utils::FileUtils::fileSystemFriendlyName(codeStyle->displayName())
/ QLatin1String(Constants::SETTINGS_FILE_NAME);
m_config = std::make_unique<ClangFormatFile>(filePath, codeStyle->isReadOnly());
initChecksAndPreview();
showCombobox();
@@ -329,8 +334,7 @@ void ClangFormatConfigWidget::fillTable()
Utils::ExecuteOnDestruction executeOnDestruction([this]() { m_disableTableUpdate = false; });
m_disableTableUpdate = true;
const std::string configText = m_project ? currentProjectConfigText()
: currentGlobalConfigText();
const std::string configText = readFile(m_config->filePath().path());
for (QObject *child : m_checksWidget->children()) {
if (!qobject_cast<QComboBox *>(child) && !qobject_cast<QLineEdit *>(child)

View File

@@ -48,7 +48,8 @@ class ClangFormatConfigWidget : public CppEditor::CppCodeStyleWidget
Q_OBJECT
public:
explicit ClangFormatConfigWidget(ProjectExplorer::Project *project = nullptr,
explicit ClangFormatConfigWidget(TextEditor::ICodeStylePreferences *codeStyle,
ProjectExplorer::Project *project = nullptr,
QWidget *parent = nullptr);
~ClangFormatConfigWidget() override;
void apply() override;

View File

@@ -25,6 +25,7 @@
#include "clangformatfile.h"
#include "clangformatsettings.h"
#include "clangformatutils.h"
#include <cppeditor/cppcodestylesettings.h>
#include <projectexplorer/project.h>
#include <texteditor/tabsettings.h>
@@ -34,11 +35,18 @@
using namespace ClangFormat;
ClangFormatFile::ClangFormatFile(Utils::FilePath filePath)
ClangFormatFile::ClangFormatFile(Utils::FilePath filePath, bool isReadOnly)
: m_filePath(filePath)
, m_isReadOnly(isReadOnly)
{
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;
}
@@ -46,7 +54,7 @@ ClangFormatFile::ClangFormatFile(Utils::FilePath filePath)
const std::error_code error
= clang::format::parseConfiguration(m_filePath.fileContents().toStdString(), &m_style);
if (error.value() != static_cast<int>(clang::format::ParseError::Success)) {
resetStyleToLLVM();
resetStyleToQtC();
}
}
@@ -65,10 +73,15 @@ void ClangFormatFile::setStyle(clang::format::FormatStyle style)
saveNewFormat();
}
void ClangFormatFile::resetStyleToLLVM()
bool ClangFormatFile::isReadOnly() const
{
m_style = clang::format::getLLVMStyle();
saveNewFormat();
return m_isReadOnly;
}
void ClangFormatFile::resetStyleToQtC()
{
m_style = qtcStyle();
saveStyleToFile(m_style, m_filePath);
}
void ClangFormatFile::setBasedOnStyle(QString styleName)
@@ -107,17 +120,17 @@ QString ClangFormatFile::changeFields(QList<Field> fields)
void ClangFormatFile::saveNewFormat()
{
std::string style = clang::format::configurationAsText(m_style);
if (m_isReadOnly)
return;
// workaround: configurationAsText() add comment "# " before BasedOnStyle line
const int pos = style.find("# BasedOnStyle");
if (pos != int(std::string::npos))
style.erase(pos, 2);
m_filePath.writeFileContents(QByteArray::fromStdString(style));
saveStyleToFile(m_style, m_filePath);
}
void ClangFormatFile::saveNewFormat(QByteArray style)
{
if (m_isReadOnly)
return;
m_filePath.writeFileContents(style);
}

View File

@@ -37,11 +37,11 @@ namespace ClangFormat {
class ClangFormatFile
{
public:
explicit ClangFormatFile(Utils::FilePath file);
explicit ClangFormatFile(Utils::FilePath file, bool isReadOnly);
clang::format::FormatStyle format();
Utils::FilePath filePath();
void resetStyleToLLVM();
void resetStyleToQtC();
void setBasedOnStyle(QString styleName);
void setStyle(clang::format::FormatStyle style);
QString setStyle(QString style);
@@ -54,6 +54,7 @@ public:
TextEditor::TabSettings toTabSettings(ProjectExplorer::Project *project) const;
void fromCppCodeStyleSettings(const CppEditor::CppCodeStyleSettings &settings);
void fromTabSettings(const TextEditor::TabSettings &settings);
bool isReadOnly() const;
private:
void saveNewFormat();
@@ -62,6 +63,7 @@ private:
private:
Utils::FilePath m_filePath;
clang::format::FormatStyle m_style;
const bool m_isReadOnly;
};
} // namespace ClangFormat

View File

@@ -84,11 +84,13 @@ public:
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)
return {new ClangFormatConfigWidget(), tr("ClangFormat")};
return {new ClangFormatConfigWidget(SessionManager::startupProject()), tr("ClangFormat")};
return {new ClangFormatConfigWidget(codeStyle), tr("ClangFormat")};
return {new ClangFormatConfigWidget(codeStyle, SessionManager::startupProject()),
tr("ClangFormat")};
}
};

View File

@@ -200,6 +200,17 @@ QString currentProjectUniqueId()
.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()
{
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());

View File

@@ -46,10 +46,12 @@ std::string currentGlobalConfigText();
clang::format::FormatStyle currentProjectStyle();
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.
QString configForFile(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);
clang::format::FormatStyle qtcStyle();

View File

@@ -109,7 +109,7 @@ TextEditor::CodeStyleEditorWidget *CppCodeStylePreferencesFactory::createEditor(
widget->layout()->setContentsMargins(0, 0, 0, 0);
widget->setCodeStyle(cppPreferences);
const auto tab = additionalTab(parent);
const auto tab = additionalTab(preferences, parent);
widget->addTab(tab.first, tab.second);
return widget;
@@ -131,8 +131,9 @@ QString CppCodeStylePreferencesFactory::previewText() const
}
std::pair<CppCodeStyleWidget *, QString> CppCodeStylePreferencesFactory::additionalTab(
QWidget *parent) const
TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const
{
Q_UNUSED(codeStyle)
Q_UNUSED(parent)
return {nullptr, ""};
}

View File

@@ -45,7 +45,8 @@ public:
TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
QString snippetProviderGroupId() 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

View File

@@ -104,6 +104,7 @@ CodeStyleDialog::CodeStyleDialog(ICodeStylePreferencesFactory *factory,
m_codeStyle->setValue(codeStyle->value());
m_codeStyle->setId(codeStyle->id());
m_codeStyle->setDisplayName(m_originalDisplayName);
m_codeStyle->setReadOnly(codeStyle->isReadOnly());
TextEditor::CodeStyleEditorWidget *editor = factory->createEditor(m_codeStyle, this);
m_buttons = new QDialogButtonBox(