summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-11-08 10:35:23 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-11-08 14:23:06 +0000
commit0e5c7f51fa88f8df0061ae6c8e43a7a0e143d552 (patch)
tree88c12e554bf11e8e913f68dfc90a49dbe47380b9
parent3de607f4e03dce5f60570835ecaf3babb780db17 (diff)
downloadqt-creator-0e5c7f51fa88f8df0061ae6c8e43a7a0e143d552.tar.gz
ClangFormat: Synchronize with C++ code style settings
And remove UI for default code style settings because it does not affect anything when ClangFormat plugin is enabled. Change-Id: Ie348b7d2691b09ea2b4868da987f2a27347ea0f3 Reviewed-by: Marco Bubke <marco.bubke@qt.io>
-rw-r--r--src/plugins/clangformat/clangformat.pro3
-rw-r--r--src/plugins/clangformat/clangformatconfigwidget.cpp28
-rw-r--r--src/plugins/clangformat/clangformatconfigwidget.h2
-rw-r--r--src/plugins/clangformat/clangformatindenter.cpp38
-rw-r--r--src/plugins/clangformat/clangformatplugin.cpp24
-rw-r--r--src/plugins/clangformat/clangformatutils.cpp179
-rw-r--r--src/plugins/clangformat/clangformatutils.h20
-rw-r--r--src/plugins/cpptools/cppcodestylesettings.cpp27
-rw-r--r--src/plugins/cpptools/cppcodestylesettings.h3
9 files changed, 254 insertions, 70 deletions
diff --git a/src/plugins/clangformat/clangformat.pro b/src/plugins/clangformat/clangformat.pro
index 74331b9e5f..70eefe17f4 100644
--- a/src/plugins/clangformat/clangformat.pro
+++ b/src/plugins/clangformat/clangformat.pro
@@ -18,7 +18,8 @@ QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS
SOURCES = \
clangformatconfigwidget.cpp \
clangformatindenter.cpp \
- clangformatplugin.cpp
+ clangformatplugin.cpp \
+ clangformatutils.cpp
HEADERS = \
clangformatconfigwidget.h \
diff --git a/src/plugins/clangformat/clangformatconfigwidget.cpp b/src/plugins/clangformat/clangformatconfigwidget.cpp
index 620989d02b..213fd88a1a 100644
--- a/src/plugins/clangformat/clangformatconfigwidget.cpp
+++ b/src/plugins/clangformat/clangformatconfigwidget.cpp
@@ -138,7 +138,7 @@ void ClangFormatConfigWidget::initialize()
connect(m_ui->createFileButton, &QPushButton::clicked,
this, [this]() {
- createStyleFileIfNeeded(m_project->projectDirectory());
+ createStyleFileIfNeeded(m_project->projectDirectory(), false);
initialize();
});
return;
@@ -146,10 +146,8 @@ void ClangFormatConfigWidget::initialize()
m_ui->createFileButton->hide();
- std::string testFilePath;
if (m_project) {
m_ui->projectHasClangFormat->hide();
- testFilePath = m_project->projectDirectory().appendPath("t.cpp").toString().toStdString();
connect(m_ui->applyButton, &QPushButton::clicked, this, &ClangFormatConfigWidget::apply);
} else {
const Project *currentProject = SessionManager::startupProject();
@@ -162,34 +160,20 @@ void ClangFormatConfigWidget::initialize()
"and can be configured in Projects > Clang Format."));
}
const QString settingsDir = Core::ICore::userResourcePath();
- createStyleFileIfNeeded(Utils::FileName::fromString(settingsDir));
- testFilePath = settingsDir.toStdString() + "/t.cpp";
+ createStyleFileIfNeeded(Utils::FileName::fromString(settingsDir), true);
m_ui->applyButton->hide();
}
- fillTable(testFilePath);
+ fillTable();
}
-void ClangFormatConfigWidget::fillTable(const std::string &testFilePath)
+void ClangFormatConfigWidget::fillTable()
{
- llvm::Expected<clang::format::FormatStyle> formatStyle =
- clang::format::getStyle("file", testFilePath, "LLVM");
- std::string configText;
- bool brokenConfig = false;
- if (!formatStyle) {
- handleAllErrors(formatStyle.takeError(), [](const llvm::ErrorInfoBase &) {
- // do nothing
- });
- configText = clang::format::configurationAsText(clang::format::getLLVMStyle());
- brokenConfig = true;
- } else {
- configText = clang::format::configurationAsText(*formatStyle);
- }
+ clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
+ std::string configText = clang::format::configurationAsText(style);
std::istringstream stream(configText);
readTable(m_ui->clangFormatOptionsTable, stream);
- if (brokenConfig)
- apply();
}
diff --git a/src/plugins/clangformat/clangformatconfigwidget.h b/src/plugins/clangformat/clangformatconfigwidget.h
index 5694bd820b..951e0cc408 100644
--- a/src/plugins/clangformat/clangformatconfigwidget.h
+++ b/src/plugins/clangformat/clangformatconfigwidget.h
@@ -49,7 +49,7 @@ public:
private:
void initialize();
- void fillTable(const std::string &testFilePath);
+ void fillTable();
ProjectExplorer::Project *m_project;
std::unique_ptr<Ui::ClangFormatConfigWidget> m_ui;
diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp
index 20c4c2c3e9..ddd786fc22 100644
--- a/src/plugins/clangformat/clangformatindenter.cpp
+++ b/src/plugins/clangformat/clangformatindenter.cpp
@@ -30,10 +30,7 @@
#include <clang/Format/Format.h>
#include <clang/Tooling/Core/Replacement.h>
-#include <coreplugin/icore.h>
#include <cpptools/cppmodelmanager.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/session.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
@@ -95,31 +92,6 @@ Replacements filteredReplacements(const Replacements &replacements,
return filtered;
}
-Utils::FileName styleConfigPath()
-{
- const Project *project = SessionManager::startupProject();
- if (project && project->projectDirectory().appendPath(".clang-format").exists())
- return project->projectDirectory();
-
- return Utils::FileName::fromString(Core::ICore::userResourcePath());
-}
-
-FormatStyle formatStyle(Utils::FileName styleConfigPath)
-{
- createStyleFileIfNeeded(styleConfigPath);
-
- Expected<FormatStyle> style = format::getStyle(
- "file", styleConfigPath.appendPath("test.cpp").toString().toStdString(), "LLVM");
- if (style)
- return *style;
-
- handleAllErrors(style.takeError(), [](const ErrorInfoBase &) {
- // do nothing
- });
-
- return format::getLLVMStyle();
-}
-
void trimFirstNonEmptyBlock(const QTextBlock &currentBlock)
{
QTextBlock prevBlock = currentBlock.previous();
@@ -198,8 +170,7 @@ Replacements replacements(QByteArray buffer,
const QTextBlock *block = nullptr,
const QChar &typedChar = QChar::Null)
{
- Utils::FileName stylePath = styleConfigPath();
- FormatStyle style = formatStyle(stylePath);
+ FormatStyle style = currentStyle();
int extraOffset = 0;
if (block) {
@@ -227,6 +198,7 @@ Replacements replacements(QByteArray buffer,
static_cast<unsigned int>(utf8Length)}};
FormattingAttemptStatus status;
+ Utils::FileName stylePath = currentStyleConfigPath();
const std::string assumedFilePath
= stylePath.appendPath("test.cpp").toString().toStdString();
Replacements replacements = reformat(style, buffer.data(), ranges, assumedFilePath, &status);
@@ -451,7 +423,7 @@ int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::Ta
TabSettings ClangFormatIndenter::tabSettings() const
{
- FormatStyle style = formatStyle(styleConfigPath());
+ FormatStyle style = currentStyle();
TabSettings tabSettings;
switch (style.UseTab) {
@@ -468,8 +440,8 @@ TabSettings ClangFormatIndenter::tabSettings() const
tabSettings.m_tabSize = static_cast<int>(style.TabWidth);
tabSettings.m_indentSize = static_cast<int>(style.IndentWidth);
- if (style.AlignAfterOpenBracket)
- tabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithSpaces;
+ if (style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign)
+ tabSettings.m_continuationAlignBehavior = TabSettings::NoContinuationAlign;
else
tabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent;
diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp
index f421b686ac..02f107f40c 100644
--- a/src/plugins/clangformat/clangformatplugin.cpp
+++ b/src/plugins/clangformat/clangformatplugin.cpp
@@ -45,8 +45,12 @@
#include <projectexplorer/projectpanelfactory.h>
#include <projectexplorer/target.h>
+#include <texteditor/texteditorsettings.h>
+
#include <clang/Format/Format.h>
+#include <utils/algorithm.h>
+
#include <QAction>
#include <QDebug>
#include <QMainWindow>
@@ -95,6 +99,24 @@ private:
ClangFormatPlugin::ClangFormatPlugin() = default;
ClangFormatPlugin::~ClangFormatPlugin() = default;
+static void disableCppCodeStyle()
+{
+ using namespace TextEditor;
+ TextEditorSettings::unregisterCodeStyleFactory(CppTools::Constants::CPP_SETTINGS_ID);
+ TextEditorSettings::unregisterCodeStylePool(CppTools::Constants::CPP_SETTINGS_ID);
+ TextEditorSettings::unregisterCodeStyle(CppTools::Constants::CPP_SETTINGS_ID);
+
+ QList<Core::IOptionsPage *> pages = Core::IOptionsPage::allOptionsPages();
+ int codeStylePageIndex = Utils::indexOf(pages, [](Core::IOptionsPage *page) {
+ return page->id() == CppTools::Constants::CPP_CODE_STYLE_SETTINGS_ID;
+ });
+ if (codeStylePageIndex >= 0) {
+ auto *page = pages[codeStylePageIndex];
+ page->finish();
+ page->deleteLater();
+ }
+}
+
bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorString)
{
Q_UNUSED(arguments);
@@ -113,6 +135,8 @@ bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorS
CppTools::CppModelManager::instance()->setCppIndenterCreator([]() {
return new ClangFormatIndenter();
});
+
+ disableCppCodeStyle();
#endif
return true;
}
diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp
new file mode 100644
index 0000000000..4e901ab563
--- /dev/null
+++ b/src/plugins/clangformat/clangformatutils.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangformatutils.h"
+
+#include <coreplugin/icore.h>
+#include <cpptools/cppcodestylesettings.h>
+#include <texteditor/tabsettings.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+
+using namespace clang;
+using namespace format;
+using namespace llvm;
+using namespace CppTools;
+using namespace ProjectExplorer;
+using namespace TextEditor;
+
+namespace ClangFormat {
+
+static void applyTabSettings(clang::format::FormatStyle &style, const TabSettings &settings)
+{
+ style.IndentWidth = static_cast<unsigned>(settings.m_indentSize);
+ style.TabWidth = static_cast<unsigned>(settings.m_tabSize);
+
+ if (settings.m_tabPolicy == TabSettings::TabsOnlyTabPolicy)
+ style.UseTab = FormatStyle::UT_Always;
+ else if (settings.m_tabPolicy == TabSettings::SpacesOnlyTabPolicy)
+ style.UseTab = FormatStyle::UT_Never;
+ else
+ style.UseTab = FormatStyle::UT_ForContinuationAndIndentation;
+
+ if (settings.m_continuationAlignBehavior == TabSettings::NoContinuationAlign) {
+ style.ContinuationIndentWidth = 0;
+ style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
+ } else {
+ style.ContinuationIndentWidth = style.IndentWidth;
+ style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
+ }
+}
+
+static void applyCppCodeStyleSettings(clang::format::FormatStyle &style,
+ const CppCodeStyleSettings &settings)
+{
+ style.IndentCaseLabels = settings.indentSwitchLabels;
+ style.AlignOperands = settings.alignAssignments;
+ style.NamespaceIndentation = FormatStyle::NI_None;
+ if (settings.indentNamespaceBody)
+ style.NamespaceIndentation = FormatStyle::NI_All;
+
+ style.BraceWrapping.IndentBraces = false;
+ if (settings.indentBlockBraces) {
+ if (settings.indentClassBraces && settings.indentEnumBraces
+ && settings.indentNamespaceBraces && settings.indentFunctionBraces) {
+ style.BraceWrapping.IndentBraces = true;
+ } else {
+ style.BreakBeforeBraces = FormatStyle::BS_GNU;
+ }
+ }
+
+ if (settings.bindStarToIdentifier || settings.bindStarToRightSpecifier)
+ style.PointerAlignment = FormatStyle::PAS_Right;
+ else
+ style.PointerAlignment = FormatStyle::PAS_Left;
+
+ style.AccessModifierOffset = settings.indentAccessSpecifiers
+ ? 0
+ : - static_cast<int>(style.IndentWidth);
+}
+
+static Utils::FileName projectStylePath()
+{
+ const Project *project = SessionManager::startupProject();
+ if (project)
+ return project->projectDirectory();
+
+ return Utils::FileName();
+}
+
+static Utils::FileName globalStylePath()
+{
+ return Utils::FileName::fromString(Core::ICore::userResourcePath());
+}
+
+Utils::FileName currentStyleConfigPath()
+{
+ Utils::FileName path = projectStylePath();
+ if (!path.isEmpty())
+ return path;
+
+ return globalStylePath();
+}
+
+static clang::format::FormatStyle constructStyle(bool isGlobal)
+{
+ FormatStyle style = getLLVMStyle();
+ const CppCodeStyleSettings codeStyleSettings = isGlobal
+ ? CppCodeStyleSettings::currentGlobalCodeStyle()
+ : CppCodeStyleSettings::currentProjectCodeStyle();
+ const TabSettings tabSettings = isGlobal
+ ? CppCodeStyleSettings::currentGlobalTabSettings()
+ : CppCodeStyleSettings::currentProjectTabSettings();
+
+ applyTabSettings(style, tabSettings);
+ applyCppCodeStyleSettings(style, codeStyleSettings);
+
+ return style;
+}
+
+void createStyleFileIfNeeded(Utils::FileName styleConfigPath, bool isGlobal)
+{
+ const QString configFile = styleConfigPath.appendPath(".clang-format").toString();
+ if (QFile::exists(configFile))
+ return;
+
+ std::fstream newStyleFile(configFile.toStdString(), std::fstream::out);
+ if (newStyleFile.is_open()) {
+ newStyleFile << clang::format::configurationAsText(constructStyle(isGlobal));
+ newStyleFile.close();
+ }
+}
+
+static clang::format::FormatStyle currentStyle(bool isGlobal)
+{
+ Utils::FileName styleConfigPath = isGlobal ? globalStylePath() : projectStylePath();
+ createStyleFileIfNeeded(styleConfigPath, isGlobal);
+
+ Expected<FormatStyle> style = format::getStyle(
+ "file", styleConfigPath.appendPath("test.cpp").toString().toStdString(), "LLVM");
+ if (style)
+ return *style;
+
+ handleAllErrors(style.takeError(), [](const ErrorInfoBase &) {
+ // do nothing
+ });
+
+ return constructStyle(isGlobal);
+}
+
+clang::format::FormatStyle currentProjectStyle()
+{
+ return currentStyle(false);
+}
+
+clang::format::FormatStyle currentGlobalStyle()
+{
+ return currentStyle(true);
+}
+
+clang::format::FormatStyle currentStyle()
+{
+ const bool isGlobal = (CppCodeStyleSettings::currentProjectCodeStyle()
+ == CppCodeStyleSettings::currentGlobalCodeStyle());
+ return currentStyle(isGlobal);
+}
+
+}
diff --git a/src/plugins/clangformat/clangformatutils.h b/src/plugins/clangformat/clangformatutils.h
index ad4e21f889..8634685971 100644
--- a/src/plugins/clangformat/clangformatutils.h
+++ b/src/plugins/clangformat/clangformatutils.h
@@ -34,18 +34,12 @@
namespace ClangFormat {
-inline void createStyleFileIfNeeded(Utils::FileName styleConfigPath)
-{
- const QString configFile = styleConfigPath.appendPath(".clang-format").toString();
- if (QFile::exists(configFile))
- return;
-
- clang::format::FormatStyle newStyle = clang::format::getLLVMStyle();
- std::fstream newStyleFile(configFile.toStdString(), std::fstream::out);
- if (newStyleFile.is_open()) {
- newStyleFile << clang::format::configurationAsText(newStyle);
- newStyleFile.close();
- }
-}
+void createStyleFileIfNeeded(Utils::FileName styleConfigPath, bool isGlobal);
+
+clang::format::FormatStyle currentProjectStyle();
+clang::format::FormatStyle currentGlobalStyle();
+
+Utils::FileName currentStyleConfigPath();
+clang::format::FormatStyle currentStyle();
}
diff --git a/src/plugins/cpptools/cppcodestylesettings.cpp b/src/plugins/cpptools/cppcodestylesettings.cpp
index 06d396e59c..723ae2c222 100644
--- a/src/plugins/cpptools/cppcodestylesettings.cpp
+++ b/src/plugins/cpptools/cppcodestylesettings.cpp
@@ -33,6 +33,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
+#include <texteditor/tabsettings.h>
+
#include <cplusplus/Overview.h>
#include <utils/qtcassert.h>
@@ -226,6 +228,31 @@ CppCodeStyleSettings CppCodeStyleSettings::currentGlobalCodeStyle()
return cppCodeStylePreferences->currentCodeStyleSettings();
}
+TextEditor::TabSettings CppCodeStyleSettings::currentProjectTabSettings()
+{
+ ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject();
+ if (!project)
+ return currentGlobalTabSettings();
+
+ ProjectExplorer::EditorConfiguration *editorConfiguration = project->editorConfiguration();
+ QTC_ASSERT(editorConfiguration, return currentGlobalTabSettings());
+
+ TextEditor::ICodeStylePreferences *codeStylePreferences
+ = editorConfiguration->codeStyle(CppTools::Constants::CPP_SETTINGS_ID);
+ QTC_ASSERT(codeStylePreferences, return currentGlobalTabSettings());
+ return codeStylePreferences->tabSettings();
+}
+
+TextEditor::TabSettings CppCodeStyleSettings::currentGlobalTabSettings()
+{
+ CppTools::CppCodeStylePreferences *cppCodeStylePreferences
+ = CppTools::CppToolsSettings::instance()->cppCodeStyle();
+ QTC_ASSERT(cppCodeStylePreferences, return TextEditor::TabSettings());
+
+ return cppCodeStylePreferences->tabSettings();
+}
+
+
static void configureOverviewWithCodeStyleSettings(CPlusPlus::Overview &overview,
const CppCodeStyleSettings &settings)
{
diff --git a/src/plugins/cpptools/cppcodestylesettings.h b/src/plugins/cpptools/cppcodestylesettings.h
index f69d72d0ab..4af18fbdbc 100644
--- a/src/plugins/cpptools/cppcodestylesettings.h
+++ b/src/plugins/cpptools/cppcodestylesettings.h
@@ -34,6 +34,7 @@ class QSettings;
QT_END_NAMESPACE
namespace CPlusPlus { class Overview; }
+namespace TextEditor { class TabSettings; }
namespace CppTools {
@@ -94,6 +95,8 @@ public:
static CppCodeStyleSettings currentProjectCodeStyle();
static CppCodeStyleSettings currentGlobalCodeStyle();
+ static TextEditor::TabSettings currentProjectTabSettings();
+ static TextEditor::TabSettings currentGlobalTabSettings();
/*! Returns an Overview configured by the current project's code style.