diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-11-08 10:35:23 +0100 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-11-08 14:23:06 +0000 |
commit | 0e5c7f51fa88f8df0061ae6c8e43a7a0e143d552 (patch) | |
tree | 88c12e554bf11e8e913f68dfc90a49dbe47380b9 | |
parent | 3de607f4e03dce5f60570835ecaf3babb780db17 (diff) | |
download | qt-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.pro | 3 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatconfigwidget.cpp | 28 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatconfigwidget.h | 2 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatindenter.cpp | 38 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatplugin.cpp | 24 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatutils.cpp | 179 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatutils.h | 20 | ||||
-rw-r--r-- | src/plugins/cpptools/cppcodestylesettings.cpp | 27 | ||||
-rw-r--r-- | src/plugins/cpptools/cppcodestylesettings.h | 3 |
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 ¤tBlock) { 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. |