From 2524e2adb3fb9a3a840a20422798aec0e20fc614 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 23 Feb 2024 14:31:30 +0100 Subject: [PATCH] CppEditor: Let users provide statement macros Like ClangFormat has. Fixes: QTCREATORBUG-15069 Fixes: QTCREATORBUG-18789 Change-Id: I0ffb70be502d1c73aaaf436484ddc6704f152621 Reviewed-by: David Schulz --- src/plugins/cppeditor/cppcodeformatter.cpp | 5 +++- src/plugins/cppeditor/cppcodeformatter.h | 2 ++ .../cppeditor/cppcodestylesettings.cpp | 4 +++ src/plugins/cppeditor/cppcodestylesettings.h | 1 + .../cppeditor/cppcodestylesettingspage.cpp | 27 +++++++++++++++++-- .../codeformatter/tst_codeformatter.cpp | 18 +++++++++++++ 6 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/plugins/cppeditor/cppcodeformatter.cpp b/src/plugins/cppeditor/cppcodeformatter.cpp index ca14d22a7c1..3d015394406 100644 --- a/src/plugins/cppeditor/cppcodeformatter.cpp +++ b/src/plugins/cppeditor/cppcodeformatter.cpp @@ -842,7 +842,8 @@ bool CodeFormatter::tryDeclaration() if (tokenText.startsWith(QLatin1String("Q_")) || tokenText.startsWith(QLatin1String("QT_")) || tokenText.startsWith(QLatin1String("QML_")) - || tokenText.startsWith(QLatin1String("QDOC_"))) { + || tokenText.startsWith(QLatin1String("QDOC_")) + || m_statementMacros.contains(tokenText)) { enter(qt_like_macro); return true; } @@ -1118,6 +1119,7 @@ QtStyleCodeFormatter::QtStyleCodeFormatter(const TabSettings &tabSettings, , m_styleSettings(settings) { setTabSize(tabSettings.m_tabSize); + setStatementMacros(m_styleSettings.statementMacros); } void QtStyleCodeFormatter::setTabSettings(const TabSettings &tabSettings) @@ -1129,6 +1131,7 @@ void QtStyleCodeFormatter::setTabSettings(const TabSettings &tabSettings) void QtStyleCodeFormatter::setCodeStyleSettings(const CppCodeStyleSettings &settings) { m_styleSettings = settings; + setStatementMacros(m_styleSettings.statementMacros); } void QtStyleCodeFormatter::saveBlockData(QTextBlock *block, const BlockData &data) const diff --git a/src/plugins/cppeditor/cppcodeformatter.h b/src/plugins/cppeditor/cppcodeformatter.h index 828fec763b0..98aacbc55ed 100644 --- a/src/plugins/cppeditor/cppcodeformatter.h +++ b/src/plugins/cppeditor/cppcodeformatter.h @@ -40,6 +40,7 @@ public: void indentForNewLineAfter(const QTextBlock &block, int *indent, int *padding); void setTabSize(int tabSize); + void setStatementMacros(const QStringList ¯os) { m_statementMacros = macros; } void invalidateCache(QTextDocument *document); @@ -224,6 +225,7 @@ private: int m_paddingDepth = 0; int m_tabSize = 4; + QStringList m_statementMacros; friend class Internal::CppCodeFormatterData; }; diff --git a/src/plugins/cppeditor/cppcodestylesettings.cpp b/src/plugins/cppeditor/cppcodestylesettings.cpp index 733f066eaca..5499005c62b 100644 --- a/src/plugins/cppeditor/cppcodestylesettings.cpp +++ b/src/plugins/cppeditor/cppcodestylesettings.cpp @@ -17,6 +17,7 @@ #include +static const char statementMacrosKey[] = "StatementMacros"; static const char indentBlockBracesKey[] = "IndentBlockBraces"; static const char indentBlockBodyKey[] = "IndentBlockBody"; static const char indentClassBracesKey[] = "IndentClassBraces"; @@ -50,6 +51,7 @@ CppCodeStyleSettings::CppCodeStyleSettings() = default; Store CppCodeStyleSettings::toMap() const { return { + {statementMacrosKey, statementMacros}, {indentBlockBracesKey, indentBlockBraces}, {indentBlockBodyKey, indentBlockBody}, {indentClassBracesKey, indentClassBraces}, @@ -76,6 +78,7 @@ Store CppCodeStyleSettings::toMap() const void CppCodeStyleSettings::fromMap(const Store &map) { + statementMacros = map.value(statementMacrosKey, statementMacros).toStringList(); indentBlockBraces = map.value(indentBlockBracesKey, indentBlockBraces).toBool(); indentBlockBody = map.value(indentBlockBodyKey, indentBlockBody).toBool(); indentClassBraces = map.value(indentClassBracesKey, indentClassBraces).toBool(); @@ -128,6 +131,7 @@ bool CppCodeStyleSettings::equals(const CppCodeStyleSettings &rhs) const && bindStarToRightSpecifier == rhs.bindStarToRightSpecifier && extraPaddingForConditionsIfConfusingAlign == rhs.extraPaddingForConditionsIfConfusingAlign && alignAssignments == rhs.alignAssignments + && statementMacros == rhs.statementMacros && preferGetterNameWithoutGetPrefix == rhs.preferGetterNameWithoutGetPrefix #ifdef WITH_TESTS && forceFormatting == rhs.forceFormatting diff --git a/src/plugins/cppeditor/cppcodestylesettings.h b/src/plugins/cppeditor/cppcodestylesettings.h index 8369df099e8..a798ca7434d 100644 --- a/src/plugins/cppeditor/cppcodestylesettings.h +++ b/src/plugins/cppeditor/cppcodestylesettings.h @@ -18,6 +18,7 @@ class CPPEDITOR_EXPORT CppCodeStyleSettings public: CppCodeStyleSettings(); + QStringList statementMacros; bool indentBlockBraces = false; bool indentBlockBody = true; bool indentClassBraces = false; diff --git a/src/plugins/cppeditor/cppcodestylesettingspage.cpp b/src/plugins/cppeditor/cppcodestylesettingspage.cpp index 74f505d663c..c1dfcebb3b3 100644 --- a/src/plugins/cppeditor/cppcodestylesettingspage.cpp +++ b/src/plugins/cppeditor/cppcodestylesettingspage.cpp @@ -163,8 +163,9 @@ public: , m_bindStarToRightSpecifier(createCheckBox(Tr::tr("Right const/volatile"), Tr::tr("This does not apply to references."))) , m_tabSettingsWidget(new TabSettingsWidget) + , m_statementMacros(new QPlainTextEdit) { - QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(m_tabSettingsWidget->sizePolicy().hasHeightForWidth()); @@ -241,11 +242,25 @@ public: } }; + sizePolicy.setVerticalPolicy(QSizePolicy::Preferred); + m_statementMacros->setToolTip( + Tr::tr("Macros that can be used as statements without a trailing semicolon")); + m_statementMacros->setSizePolicy(sizePolicy); + const Group statementMacrosGroup { + title(Tr::tr("Statement macros")), + Column { m_statementMacros} + }; + QObject::connect(m_statementMacros, &QPlainTextEdit::textChanged, q, [this] { + m_handlingStatementMacroChange = true; + q->slotCodeStyleSettingsChanged(); + m_handlingStatementMacroChange = false; + }); + Row { TabWidget { bindTo(&m_categoryTab), Tab { Tr::tr("General"), - Row { Column { m_tabSettingsWidget, st }, createPreview(0) } + Row { Column { m_tabSettingsWidget, statementMacrosGroup }, createPreview(0) } }, Tab { Tr::tr("Content"), Row { contentGroup, createPreview(1) } }, Tab { Tr::tr("Braces"), Row { bracesGroup, createPreview(2) } }, @@ -310,6 +325,8 @@ public: QTabWidget *m_categoryTab = nullptr; TabSettingsWidget *m_tabSettingsWidget = nullptr; + QPlainTextEdit * const m_statementMacros; + bool m_handlingStatementMacroChange = false; }; CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent) @@ -361,6 +378,10 @@ CppCodeStyleSettings CppCodeStylePreferencesWidget::cppCodeStyleSettings() const { CppCodeStyleSettings set; + set.statementMacros + = Utils::transform(d->m_statementMacros->toPlainText().trimmed().split('\n', + Qt::SkipEmptyParts), + [](const QString &line) { return line.trimmed(); }); set.indentBlockBraces = d->m_indentBlockBraces->isChecked(); set.indentBlockBody = d->m_indentBlockBody->isChecked(); set.indentClassBraces = d->m_indentClassBraces->isChecked(); @@ -399,6 +420,8 @@ void CppCodeStylePreferencesWidget::setCodeStyleSettings(const CppCodeStyleSetti { const bool wasBlocked = m_blockUpdates; m_blockUpdates = true; + if (!d->m_handlingStatementMacroChange) + d->m_statementMacros->setPlainText(s.statementMacros.join('\n')); d->m_indentBlockBraces->setChecked(s.indentBlockBraces); d->m_indentBlockBody->setChecked(s.indentBlockBody); d->m_indentClassBraces->setChecked(s.indentClassBraces); diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp index b61f91fc3bc..29ecbb58ed9 100644 --- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp +++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp @@ -108,6 +108,7 @@ private Q_SLOTS: void lambdaWithReturnType(); void structuredBinding(); void subscriptOperatorInFunctionCall(); + void statementMacros(); }; struct Line { @@ -2213,6 +2214,23 @@ void tst_CodeFormatter::subscriptOperatorInFunctionCall() checkIndent(data); } +void tst_CodeFormatter::statementMacros() +{ + QList data; + data << Line("MY_MACRO") + << Line("template") + << Line("~ class C;"); + checkIndent(data); + + data.clear(); + CppCodeStyleSettings settings; + settings.statementMacros << "MY_MACRO"; + data << Line("MY_MACRO") + << Line("template") + << Line("class C;"); + checkIndent(data, settings); +} + QTEST_GUILESS_MAIN(tst_CodeFormatter) #include "tst_codeformatter.moc"