From 048f77b96166fb0d3a654e34f01a790a8493b7e2 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 8 Aug 2023 17:02:38 +0200 Subject: [PATCH] CppEditor: Let users specify a preferred doxygen command prefix Fixes: QTCREATORBUG-8096 Change-Id: I08bf4e3e0092fc775b50be6e5f4cefb9ed6979a5 Reviewed-by: Reviewed-by: David Schulz --- src/plugins/cppeditor/cppdoxygen_test.cpp | 117 +++++++++++------- src/plugins/cppeditor/doxygengenerator.cpp | 6 + .../projectcommentssettings.cpp | 4 + src/plugins/texteditor/commentssettings.cpp | 27 +++- src/plugins/texteditor/commentssettings.h | 4 + 5 files changed, 112 insertions(+), 46 deletions(-) diff --git a/src/plugins/cppeditor/cppdoxygen_test.cpp b/src/plugins/cppeditor/cppdoxygen_test.cpp index 5e7c0f87722..2cab76ee493 100644 --- a/src/plugins/cppeditor/cppdoxygen_test.cpp +++ b/src/plugins/cppeditor/cppdoxygen_test.cpp @@ -62,7 +62,9 @@ void DoxygenTest::testBasic_data() { QTest::addColumn("given"); QTest::addColumn("expected"); + QTest::addColumn("commandPrefix"); + using CommandPrefix = CommentsSettings::CommandPrefix; QTest::newRow("qt_style") << _( "bool preventFolding;\n" "/*!|\n" @@ -72,8 +74,29 @@ void DoxygenTest::testBasic_data() "/*!\n" " * \\brief a\n" " */\n" + "int a;\n") << int(CommandPrefix::Auto); + + QTest::newRow("qt_style_settings_override") << _( + "bool preventFolding;\n" + "/*!|\n" "int a;\n" - ); + ) << _( + "bool preventFolding;\n" + "/*!\n" + " * @brief a\n" + " */\n" + "int a;\n") << int(CommandPrefix::At); + + QTest::newRow("qt_style_settings_override_redundant") << _( + "bool preventFolding;\n" + "/*!|\n" + "int a;\n" + ) << _( + "bool preventFolding;\n" + "/*!\n" + " * \\brief a\n" + " */\n" + "int a;\n") << int(CommandPrefix::Backslash); QTest::newRow("qt_style_cursor_before_existing_comment") << _( "bool preventFolding;\n" @@ -87,8 +110,7 @@ void DoxygenTest::testBasic_data() " * \n" " * \\brief something\n" " */\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("qt_style_continuation") << _( "bool preventFolding;\n" @@ -102,8 +124,7 @@ void DoxygenTest::testBasic_data() " * \\brief a\n" " * \n" " */\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("java_style") << _( "bool preventFolding;\n" @@ -114,8 +135,29 @@ void DoxygenTest::testBasic_data() "/**\n" " * @brief a\n" " */\n" + "int a;\n") << int(CommandPrefix::Auto); + + QTest::newRow("java_style_settings_override") << _( + "bool preventFolding;\n" + "/**|\n" "int a;\n" - ); + ) << _( + "bool preventFolding;\n" + "/**\n" + " * \\brief a\n" + " */\n" + "int a;\n") << int(CommandPrefix::Backslash); + + QTest::newRow("java_style_settings_override_redundant") << _( + "bool preventFolding;\n" + "/**|\n" + "int a;\n" + ) << _( + "bool preventFolding;\n" + "/**\n" + " * @brief a\n" + " */\n" + "int a;\n") << int(CommandPrefix::At); QTest::newRow("java_style_continuation") << _( "bool preventFolding;\n" @@ -129,8 +171,7 @@ void DoxygenTest::testBasic_data() " * @brief a\n" " * \n" " */\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleA") << _( "bool preventFolding;\n" @@ -141,8 +182,7 @@ void DoxygenTest::testBasic_data() "///\n" "/// \\brief a\n" "///\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleB") << _( "bool preventFolding;\n" @@ -153,8 +193,7 @@ void DoxygenTest::testBasic_data() "//!\n" "//! \\brief a\n" "//!\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleA_continuation") << _( "bool preventFolding;\n" @@ -168,8 +207,7 @@ void DoxygenTest::testBasic_data() "/// \\brief a\n" "/// \n" "///\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleB_continuation") << _( "bool preventFolding;\n" @@ -183,8 +221,7 @@ void DoxygenTest::testBasic_data() "//! \\brief a\n" "//! \n" "//!\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); /// test cpp style doxygen comment when inside a indented scope QTest::newRow("cpp_styleA_indented") << _( @@ -196,8 +233,7 @@ void DoxygenTest::testBasic_data() " ///\n" " /// \\brief a\n" " ///\n" - " int a;\n" - ); + " int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleB_indented") << _( " bool preventFolding;\n" @@ -208,8 +244,7 @@ void DoxygenTest::testBasic_data() " //!\n" " //! \\brief a\n" " //!\n" - " int a;\n" - ); + " int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleA_indented_preserve_mixed_indention_continuation") << _( "\t bool preventFolding;\n" @@ -219,8 +254,7 @@ void DoxygenTest::testBasic_data() "\t bool preventFolding;\n" "\t /// \\brief a\n" "\t /// \n" - "\t int a;\n" - ); + "\t int a;\n") << int(CommandPrefix::Auto); /// test cpp style doxygen comment continuation when inside a indented scope QTest::newRow("cpp_styleA_indented_continuation") << _( @@ -235,8 +269,7 @@ void DoxygenTest::testBasic_data() " /// \\brief a\n" " /// \n" " ///\n" - " int a;\n" - ); + " int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleB_indented_continuation") << _( " bool preventFolding;\n" @@ -250,8 +283,7 @@ void DoxygenTest::testBasic_data() " //! \\brief a\n" " //! \n" " //!\n" - " int a;\n" - ); + " int a;\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleA_corner_case") << _( "bool preventFolding;\n" @@ -261,8 +293,7 @@ void DoxygenTest::testBasic_data() "bool preventFolding;\n" "///\n" "void d(); ///\n" - "\n" - ); + "\n") << int(CommandPrefix::Auto); QTest::newRow("cpp_styleB_corner_case") << _( "bool preventFolding;\n" @@ -272,8 +303,7 @@ void DoxygenTest::testBasic_data() "bool preventFolding;\n" "//!\n" "void d(); //!\n" - "\n" - ); + "\n") << int(CommandPrefix::Auto); QTest::newRow("noContinuationForExpressionAndComment1") << _( "bool preventFolding;\n" @@ -281,8 +311,7 @@ void DoxygenTest::testBasic_data() ) << _( "bool preventFolding;\n" "*foo //\n" - "\n" - ); + "\n") << int(CommandPrefix::Auto); QTest::newRow("noContinuationForExpressionAndComment2") << _( "bool preventFolding;\n" @@ -290,8 +319,7 @@ void DoxygenTest::testBasic_data() ) << _( "bool preventFolding;\n" "*foo /*\n" - " \n" - ); + " \n") << int(CommandPrefix::Auto); QTest::newRow("withMacroFromDocumentBeforeFunction") << _( "#define API\n" @@ -302,8 +330,7 @@ void DoxygenTest::testBasic_data() "/**\n" " * @brief f\n" " */\n" - "API void f();\n" - ); + "API void f();\n") << int(CommandPrefix::Auto); QTest::newRow("withAccessSpecifierBeforeFunction") << _( "class C {\n" @@ -316,8 +343,7 @@ void DoxygenTest::testBasic_data() " * @brief f\n" " */\n" " public: void f();\n" - "};\n" - ); + "};\n") << int(CommandPrefix::Auto); QTest::newRow("classTemplate") << _( "bool preventFolding;\n" @@ -330,8 +356,7 @@ void DoxygenTest::testBasic_data() " * @brief The C class\n" " */\n" "template class C {\n" - "};\n" - ); + "};\n") << int(CommandPrefix::Auto); QTest::newRow("continuation_after_text_in_first_line") << _( "bool preventFolding;\n" @@ -343,8 +368,7 @@ void DoxygenTest::testBasic_data() "/*! leading comment\n" " * \n" " */\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); QTest::newRow("continuation_after_extra_indent") << _( "bool preventFolding;\n" @@ -358,14 +382,19 @@ void DoxygenTest::testBasic_data() " * cont\n" " * \n" " */\n" - "int a;\n" - ); + "int a;\n") << int(CommandPrefix::Auto); } void DoxygenTest::testBasic() { QFETCH(QByteArray, given); QFETCH(QByteArray, expected); + QFETCH(int, commandPrefix); + + CommentsSettings::Data settings = CommentsSettings::data(); + settings.commandPrefix = static_cast(commandPrefix); + const SettingsInjector injector(settings); + runTest(given, expected); } diff --git a/src/plugins/cppeditor/doxygengenerator.cpp b/src/plugins/cppeditor/doxygengenerator.cpp index ac79cb0d839..c77f3de7769 100644 --- a/src/plugins/cppeditor/doxygengenerator.cpp +++ b/src/plugins/cppeditor/doxygengenerator.cpp @@ -201,6 +201,12 @@ QString DoxygenGenerator::generate(QTextCursor cursor, DeclarationAST *decl) QChar DoxygenGenerator::styleMark() const { + switch (m_settings.commandPrefix) { + case TextEditor::CommentsSettings::CommandPrefix::At: return '@'; + case TextEditor::CommentsSettings::CommandPrefix::Backslash: return '\\'; + case TextEditor::CommentsSettings::CommandPrefix::Auto: break; + } + if (m_style == QtStyle || m_style == CppStyleA || m_style == CppStyleB) return QLatin1Char('\\'); return QLatin1Char('@'); diff --git a/src/plugins/projectexplorer/projectcommentssettings.cpp b/src/plugins/projectexplorer/projectcommentssettings.cpp index e08638e028a..6d41244eea1 100644 --- a/src/plugins/projectexplorer/projectcommentssettings.cpp +++ b/src/plugins/projectexplorer/projectcommentssettings.cpp @@ -63,6 +63,9 @@ void ProjectCommentsSettings::loadSettings() m_customSettings.generateBrief).toBool(); m_customSettings.leadingAsterisks = data.value(CommentsSettings::leadingAsterisksSettingsKey(), m_customSettings.leadingAsterisks).toBool(); + m_customSettings.commandPrefix = static_cast( + data.value(CommentsSettings::commandPrefixKey(), + int(m_customSettings.commandPrefix)).toInt()); } void ProjectCommentsSettings::saveSettings() @@ -81,6 +84,7 @@ void ProjectCommentsSettings::saveSettings() data.insert(CommentsSettings::enableDoxygenSettingsKey(), m_customSettings.enableDoxygen); data.insert(CommentsSettings::generateBriefSettingsKey(), m_customSettings.generateBrief); data.insert(CommentsSettings::leadingAsterisksSettingsKey(), m_customSettings.leadingAsterisks); + data.insert(CommentsSettings::commandPrefixKey(), int(m_customSettings.commandPrefix)); m_project->setNamedSettings(CommentsSettings::mainSettingsKey(), data); } diff --git a/src/plugins/texteditor/commentssettings.cpp b/src/plugins/texteditor/commentssettings.cpp index 5c6f533d254..441d01c3538 100644 --- a/src/plugins/texteditor/commentssettings.cpp +++ b/src/plugins/texteditor/commentssettings.cpp @@ -12,6 +12,7 @@ #include #include +#include #include using namespace Layouting; @@ -23,6 +24,7 @@ const char kDocumentationCommentsGroup[] = "CppToolsDocumentationComments"; const char kEnableDoxygenBlocks[] = "EnableDoxygenBlocks"; const char kGenerateBrief[] = "GenerateBrief"; const char kAddLeadingAsterisks[] = "AddLeadingAsterisks"; +const char kCommandPrefix[] = "CommandPrefix"; } void CommentsSettings::setData(const Data &data) @@ -37,6 +39,7 @@ QString CommentsSettings::mainSettingsKey() { return kDocumentationCommentsGroup QString CommentsSettings::enableDoxygenSettingsKey() { return kEnableDoxygenBlocks; } QString CommentsSettings::generateBriefSettingsKey() { return kGenerateBrief; } QString CommentsSettings::leadingAsterisksSettingsKey() { return kAddLeadingAsterisks; } +QString CommentsSettings::commandPrefixKey() { return kCommandPrefix; } CommentsSettings::CommentsSettings() { @@ -56,6 +59,7 @@ void CommentsSettings::save() const s->setValue(kEnableDoxygenBlocks, m_data.enableDoxygen); s->setValue(kGenerateBrief, m_data.generateBrief); s->setValue(kAddLeadingAsterisks, m_data.leadingAsterisks); + s->setValueWithDefault(kCommandPrefix, int(m_data.commandPrefix)); s->endGroup(); } @@ -66,6 +70,8 @@ void CommentsSettings::load() m_data.enableDoxygen = s->value(kEnableDoxygenBlocks, true).toBool(); m_data.generateBrief = m_data.enableDoxygen && s->value(kGenerateBrief, true).toBool(); m_data.leadingAsterisks = s->value(kAddLeadingAsterisks, true).toBool(); + m_data.commandPrefix = static_cast( + s->value(kCommandPrefix, int(m_data.commandPrefix)).toInt()); s->endGroup(); } @@ -76,13 +82,12 @@ public: QCheckBox m_enableDoxygenCheckBox; QCheckBox m_generateBriefCheckBox; QCheckBox m_leadingAsterisksCheckBox; + QComboBox m_commandPrefixComboBox; }; CommentsSettingsWidget::CommentsSettingsWidget(const CommentsSettings::Data &settings) : d(new Private) { - initFromSettings(settings); - d->m_enableDoxygenCheckBox.setText(Tr::tr("Enable Doxygen blocks")); d->m_enableDoxygenCheckBox.setToolTip( Tr::tr("Automatically creates a Doxygen comment upon pressing " @@ -98,10 +103,23 @@ CommentsSettingsWidget::CommentsSettingsWidget(const CommentsSettings::Data &set Tr::tr("Adds leading asterisks when continuing C/C++ \"/*\", Qt \"/*!\" " "and Java \"/**\" style comments on new lines.")); + const auto commandPrefixLabel = new QLabel(Tr::tr("Doxygen command prefix:")); + const QString commandPrefixToolTip = Tr::tr(R"(Doxygen allows "@" and "\" to start commands. +By default, "@" is used if the surrounding comment starts with "/**" or "///", and "\" is used +if the comment starts with "/*!" or "//!)"); + commandPrefixLabel->setToolTip(commandPrefixToolTip); + d->m_commandPrefixComboBox.setToolTip(commandPrefixToolTip); + d->m_commandPrefixComboBox.addItem(Tr::tr("Automatic")); + d->m_commandPrefixComboBox.addItem("@"); + d->m_commandPrefixComboBox.addItem("\\"); + + initFromSettings(settings); + Column { &d->m_enableDoxygenCheckBox, Row { Space(30), &d->m_generateBriefCheckBox }, &d->m_leadingAsterisksCheckBox, + Row { commandPrefixLabel, &d->m_commandPrefixComboBox, st }, st }.attachTo(this); @@ -112,6 +130,8 @@ CommentsSettingsWidget::CommentsSettingsWidget(const CommentsSettings::Data &set &d->m_leadingAsterisksCheckBox}) { connect(checkBox, &QCheckBox::clicked, this, &CommentsSettingsWidget::settingsChanged); } + connect(&d->m_commandPrefixComboBox, &QComboBox::currentIndexChanged, + this, &CommentsSettingsWidget::settingsChanged); } CommentsSettingsWidget::~CommentsSettingsWidget() { delete d; } @@ -122,6 +142,8 @@ CommentsSettings::Data CommentsSettingsWidget::settingsData() const settings.enableDoxygen = d->m_enableDoxygenCheckBox.isChecked(); settings.generateBrief = d->m_generateBriefCheckBox.isChecked(); settings.leadingAsterisks = d->m_leadingAsterisksCheckBox.isChecked(); + settings.commandPrefix = static_cast( + d->m_commandPrefixComboBox.currentIndex()); return settings; } @@ -137,6 +159,7 @@ void CommentsSettingsWidget::initFromSettings(const CommentsSettings::Data &sett d->m_generateBriefCheckBox.setEnabled(d->m_enableDoxygenCheckBox.isChecked()); d->m_generateBriefCheckBox.setChecked(settings.generateBrief); d->m_leadingAsterisksCheckBox.setChecked(settings.leadingAsterisks); + d->m_commandPrefixComboBox.setCurrentIndex(int(settings.commandPrefix)); } namespace Internal { diff --git a/src/plugins/texteditor/commentssettings.h b/src/plugins/texteditor/commentssettings.h index b14bd376ae5..7206a8ccc4c 100644 --- a/src/plugins/texteditor/commentssettings.h +++ b/src/plugins/texteditor/commentssettings.h @@ -14,8 +14,10 @@ namespace TextEditor { class TEXTEDITOR_EXPORT CommentsSettings { public: + enum class CommandPrefix { Auto, At, Backslash }; class Data { public: + CommandPrefix commandPrefix = CommandPrefix::Auto; bool enableDoxygen = true; bool generateBrief = true; bool leadingAsterisks = true; @@ -28,6 +30,7 @@ public: static QString enableDoxygenSettingsKey(); static QString generateBriefSettingsKey(); static QString leadingAsterisksSettingsKey(); + static QString commandPrefixKey(); private: CommentsSettings(); @@ -40,6 +43,7 @@ private: inline bool operator==(const CommentsSettings::Data &a, const CommentsSettings::Data &b) { return a.enableDoxygen == b.enableDoxygen + && a.commandPrefix == b.commandPrefix && a.generateBrief == b.generateBrief && a.leadingAsterisks == b.leadingAsterisks; }