From 2ecbbb126dd0e158a1899796b310adf920728815 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 27 Oct 2021 11:03:42 +0200 Subject: [PATCH] ClangCodeModel: Do not let clangd insert header files on completion ... by default. This feature often doesn't do what you'd want it to, so we make it opt- in. Change-Id: I631eae9c154ddcb0e8feeac44c5d5c0265706a67 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 6 ++++-- src/plugins/cppeditor/cppcodemodelsettings.cpp | 3 +++ src/plugins/cppeditor/cppcodemodelsettings.h | 3 +++ src/plugins/cppeditor/cppcodemodelsettingspage.cpp | 11 +++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index c65d8ee95c9..cc192fc9c18 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -521,8 +521,10 @@ static BaseClientInterface *clientInterface(Project *project, const Utils::FileP const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings()); if (!settings.indexingEnabled()) indexingOption += "=0"; - Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, "--limit-results=0", - "--clang-tidy=0"}}; + const QString headerInsertionOption = QString("--header-insertion=") + + (settings.autoIncludeHeaders() ? "iwyu" : "never"); + Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, headerInsertionOption, + "--limit-results=0", "--clang-tidy=0"}}; if (settings.workerThreadLimit() != 0) cmd.addArg("-j=" + QString::number(settings.workerThreadLimit())); if (!jsonDbDir.isEmpty()) diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp index 66c07bed7a1..f6c4629d0c7 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp @@ -69,6 +69,7 @@ static QString clangdSettingsKey() { return QLatin1String("ClangdSettings"); } static QString useClangdKey() { return QLatin1String("UseClangd"); } static QString clangdPathKey() { return QLatin1String("ClangdPath"); } static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); } +static QString clangdHeaderInsertionKey() { return QLatin1String("ClangdHeaderInsertion"); } static QString clangdThreadLimitKey() { return QLatin1String("ClangdThreadLimit"); } static QString clangdDocumentThresholdKey() { return QLatin1String("ClangdDocumentThreshold"); } static QString clangdUseGlobalSettingsKey() { return QLatin1String("useGlobalSettings"); } @@ -405,6 +406,7 @@ QVariantMap ClangdSettings::Data::toMap() const if (executableFilePath != fallbackClangdFilePath()) map.insert(clangdPathKey(), executableFilePath.toString()); map.insert(clangdIndexingKey(), enableIndexing); + map.insert(clangdHeaderInsertionKey(), autoIncludeHeaders); map.insert(clangdThreadLimitKey(), workerThreadLimit); map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold); return map; @@ -415,6 +417,7 @@ void ClangdSettings::Data::fromMap(const QVariantMap &map) useClangd = map.value(useClangdKey(), false).toBool(); executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString()); enableIndexing = map.value(clangdIndexingKey(), true).toBool(); + autoIncludeHeaders = map.value(clangdHeaderInsertionKey(), false).toBool(); workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt(); documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt(); } diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h index c3ae5b72491..5f4f4622c7a 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.h +++ b/src/plugins/cppeditor/cppcodemodelsettings.h @@ -110,6 +110,7 @@ public: int workerThreadLimit = 0; bool useClangd = false; bool enableIndexing = true; + bool autoIncludeHeaders = false; int documentUpdateThreshold = 500; }; @@ -121,6 +122,7 @@ public: static void setDefaultClangdPath(const Utils::FilePath &filePath); Utils::FilePath clangdFilePath() const; bool indexingEnabled() const { return m_data.enableIndexing; } + bool autoIncludeHeaders() const { return m_data.autoIncludeHeaders; } int workerThreadLimit() const { return m_data.workerThreadLimit; } int documentUpdateThreshold() const { return m_data.documentUpdateThreshold; } @@ -150,6 +152,7 @@ inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Dat && s1.executableFilePath == s2.executableFilePath && s1.workerThreadLimit == s2.workerThreadLimit && s1.enableIndexing == s2.enableIndexing + && s1.autoIncludeHeaders == s2.autoIncludeHeaders && s1.documentUpdateThreshold == s2.documentUpdateThreshold; } inline bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp index 1c6621e070b..7a850df329f 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp @@ -197,6 +197,7 @@ class ClangdSettingsWidget::Private public: QCheckBox useClangdCheckBox; QCheckBox indexingCheckBox; + QCheckBox autoIncludeHeadersCheckBox; QSpinBox threadLimitSpinBox; QSpinBox documentUpdateThreshold; Utils::PathChooser clangdChooser; @@ -217,6 +218,9 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD "If background indexing is enabled, global symbol searches will yield\n" "more accurate results, at the cost of additional CPU load when\n" "the project is first opened.")); + d->autoIncludeHeadersCheckBox.setChecked(settings.autoIncludeHeaders()); + d->autoIncludeHeadersCheckBox.setToolTip(tr( + "Controls whether clangd may insert header files as part of symbol completion.")); d->threadLimitSpinBox.setValue(settings.workerThreadLimit()); d->threadLimitSpinBox.setSpecialValueText("Automatic"); d->documentUpdateThreshold.setMinimum(50); @@ -237,6 +241,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD formLayout->addRow(QString(), &d->versionWarningLabel); const auto indexingLabel = new QLabel(tr("Enable background indexing:")); formLayout->addRow(indexingLabel, &d->indexingCheckBox); + const auto autoIncludeHeadersLabel = new QLabel(tr("Insert header files on completion:")); + formLayout->addRow(autoIncludeHeadersLabel, &d->autoIncludeHeadersCheckBox); const auto threadLimitLayout = new QHBoxLayout; threadLimitLayout->addWidget(&d->threadLimitSpinBox); threadLimitLayout->addStretch(1); @@ -255,6 +261,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD d->clangdChooser.setEnabled(checked); indexingLabel->setEnabled(checked); d->indexingCheckBox.setEnabled(checked); + autoIncludeHeadersLabel->setEnabled(checked); + d->autoIncludeHeadersCheckBox.setEnabled(checked); d->threadLimitSpinBox.setEnabled(checked); d->versionWarningLabel.setEnabled(checked); }; @@ -312,6 +320,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->indexingCheckBox, &QCheckBox::toggled, this, &ClangdSettingsWidget::settingsDataChanged); + connect(&d->autoIncludeHeadersCheckBox, &QCheckBox::toggled, + this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->threadLimitSpinBox, qOverload(&QSpinBox::valueChanged), this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->clangdChooser, &Utils::PathChooser::pathChanged, @@ -329,6 +339,7 @@ ClangdSettings::Data ClangdSettingsWidget::settingsData() const data.useClangd = d->useClangdCheckBox.isChecked(); data.executableFilePath = d->clangdChooser.filePath(); data.enableIndexing = d->indexingCheckBox.isChecked(); + data.autoIncludeHeaders = d->autoIncludeHeadersCheckBox.isChecked(); data.workerThreadLimit = d->threadLimitSpinBox.value(); data.documentUpdateThreshold = d->documentUpdateThreshold.value(); return data;