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 <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-10-27 11:03:42 +02:00
parent 6bf8e5dfce
commit 2ecbbb126d
4 changed files with 21 additions and 2 deletions

View File

@@ -521,8 +521,10 @@ static BaseClientInterface *clientInterface(Project *project, const Utils::FileP
const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings()); const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings());
if (!settings.indexingEnabled()) if (!settings.indexingEnabled())
indexingOption += "=0"; indexingOption += "=0";
Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, "--limit-results=0", const QString headerInsertionOption = QString("--header-insertion=")
"--clang-tidy=0"}}; + (settings.autoIncludeHeaders() ? "iwyu" : "never");
Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, headerInsertionOption,
"--limit-results=0", "--clang-tidy=0"}};
if (settings.workerThreadLimit() != 0) if (settings.workerThreadLimit() != 0)
cmd.addArg("-j=" + QString::number(settings.workerThreadLimit())); cmd.addArg("-j=" + QString::number(settings.workerThreadLimit()));
if (!jsonDbDir.isEmpty()) if (!jsonDbDir.isEmpty())

View File

@@ -69,6 +69,7 @@ static QString clangdSettingsKey() { return QLatin1String("ClangdSettings"); }
static QString useClangdKey() { return QLatin1String("UseClangd"); } static QString useClangdKey() { return QLatin1String("UseClangd"); }
static QString clangdPathKey() { return QLatin1String("ClangdPath"); } static QString clangdPathKey() { return QLatin1String("ClangdPath"); }
static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); } static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); }
static QString clangdHeaderInsertionKey() { return QLatin1String("ClangdHeaderInsertion"); }
static QString clangdThreadLimitKey() { return QLatin1String("ClangdThreadLimit"); } static QString clangdThreadLimitKey() { return QLatin1String("ClangdThreadLimit"); }
static QString clangdDocumentThresholdKey() { return QLatin1String("ClangdDocumentThreshold"); } static QString clangdDocumentThresholdKey() { return QLatin1String("ClangdDocumentThreshold"); }
static QString clangdUseGlobalSettingsKey() { return QLatin1String("useGlobalSettings"); } static QString clangdUseGlobalSettingsKey() { return QLatin1String("useGlobalSettings"); }
@@ -405,6 +406,7 @@ QVariantMap ClangdSettings::Data::toMap() const
if (executableFilePath != fallbackClangdFilePath()) if (executableFilePath != fallbackClangdFilePath())
map.insert(clangdPathKey(), executableFilePath.toString()); map.insert(clangdPathKey(), executableFilePath.toString());
map.insert(clangdIndexingKey(), enableIndexing); map.insert(clangdIndexingKey(), enableIndexing);
map.insert(clangdHeaderInsertionKey(), autoIncludeHeaders);
map.insert(clangdThreadLimitKey(), workerThreadLimit); map.insert(clangdThreadLimitKey(), workerThreadLimit);
map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold); map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold);
return map; return map;
@@ -415,6 +417,7 @@ void ClangdSettings::Data::fromMap(const QVariantMap &map)
useClangd = map.value(useClangdKey(), false).toBool(); useClangd = map.value(useClangdKey(), false).toBool();
executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString()); executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString());
enableIndexing = map.value(clangdIndexingKey(), true).toBool(); enableIndexing = map.value(clangdIndexingKey(), true).toBool();
autoIncludeHeaders = map.value(clangdHeaderInsertionKey(), false).toBool();
workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt(); workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt();
documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt(); documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt();
} }

View File

@@ -110,6 +110,7 @@ public:
int workerThreadLimit = 0; int workerThreadLimit = 0;
bool useClangd = false; bool useClangd = false;
bool enableIndexing = true; bool enableIndexing = true;
bool autoIncludeHeaders = false;
int documentUpdateThreshold = 500; int documentUpdateThreshold = 500;
}; };
@@ -121,6 +122,7 @@ public:
static void setDefaultClangdPath(const Utils::FilePath &filePath); static void setDefaultClangdPath(const Utils::FilePath &filePath);
Utils::FilePath clangdFilePath() const; Utils::FilePath clangdFilePath() const;
bool indexingEnabled() const { return m_data.enableIndexing; } bool indexingEnabled() const { return m_data.enableIndexing; }
bool autoIncludeHeaders() const { return m_data.autoIncludeHeaders; }
int workerThreadLimit() const { return m_data.workerThreadLimit; } int workerThreadLimit() const { return m_data.workerThreadLimit; }
int documentUpdateThreshold() const { return m_data.documentUpdateThreshold; } 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.executableFilePath == s2.executableFilePath
&& s1.workerThreadLimit == s2.workerThreadLimit && s1.workerThreadLimit == s2.workerThreadLimit
&& s1.enableIndexing == s2.enableIndexing && s1.enableIndexing == s2.enableIndexing
&& s1.autoIncludeHeaders == s2.autoIncludeHeaders
&& s1.documentUpdateThreshold == s2.documentUpdateThreshold; && s1.documentUpdateThreshold == s2.documentUpdateThreshold;
} }
inline bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) inline bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)

View File

@@ -197,6 +197,7 @@ class ClangdSettingsWidget::Private
public: public:
QCheckBox useClangdCheckBox; QCheckBox useClangdCheckBox;
QCheckBox indexingCheckBox; QCheckBox indexingCheckBox;
QCheckBox autoIncludeHeadersCheckBox;
QSpinBox threadLimitSpinBox; QSpinBox threadLimitSpinBox;
QSpinBox documentUpdateThreshold; QSpinBox documentUpdateThreshold;
Utils::PathChooser clangdChooser; Utils::PathChooser clangdChooser;
@@ -217,6 +218,9 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
"If background indexing is enabled, global symbol searches will yield\n" "If background indexing is enabled, global symbol searches will yield\n"
"more accurate results, at the cost of additional CPU load when\n" "more accurate results, at the cost of additional CPU load when\n"
"the project is first opened.")); "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.setValue(settings.workerThreadLimit());
d->threadLimitSpinBox.setSpecialValueText("Automatic"); d->threadLimitSpinBox.setSpecialValueText("Automatic");
d->documentUpdateThreshold.setMinimum(50); d->documentUpdateThreshold.setMinimum(50);
@@ -237,6 +241,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
formLayout->addRow(QString(), &d->versionWarningLabel); formLayout->addRow(QString(), &d->versionWarningLabel);
const auto indexingLabel = new QLabel(tr("Enable background indexing:")); const auto indexingLabel = new QLabel(tr("Enable background indexing:"));
formLayout->addRow(indexingLabel, &d->indexingCheckBox); 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; const auto threadLimitLayout = new QHBoxLayout;
threadLimitLayout->addWidget(&d->threadLimitSpinBox); threadLimitLayout->addWidget(&d->threadLimitSpinBox);
threadLimitLayout->addStretch(1); threadLimitLayout->addStretch(1);
@@ -255,6 +261,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
d->clangdChooser.setEnabled(checked); d->clangdChooser.setEnabled(checked);
indexingLabel->setEnabled(checked); indexingLabel->setEnabled(checked);
d->indexingCheckBox.setEnabled(checked); d->indexingCheckBox.setEnabled(checked);
autoIncludeHeadersLabel->setEnabled(checked);
d->autoIncludeHeadersCheckBox.setEnabled(checked);
d->threadLimitSpinBox.setEnabled(checked); d->threadLimitSpinBox.setEnabled(checked);
d->versionWarningLabel.setEnabled(checked); d->versionWarningLabel.setEnabled(checked);
}; };
@@ -312,6 +320,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
this, &ClangdSettingsWidget::settingsDataChanged); this, &ClangdSettingsWidget::settingsDataChanged);
connect(&d->indexingCheckBox, &QCheckBox::toggled, connect(&d->indexingCheckBox, &QCheckBox::toggled,
this, &ClangdSettingsWidget::settingsDataChanged); this, &ClangdSettingsWidget::settingsDataChanged);
connect(&d->autoIncludeHeadersCheckBox, &QCheckBox::toggled,
this, &ClangdSettingsWidget::settingsDataChanged);
connect(&d->threadLimitSpinBox, qOverload<int>(&QSpinBox::valueChanged), connect(&d->threadLimitSpinBox, qOverload<int>(&QSpinBox::valueChanged),
this, &ClangdSettingsWidget::settingsDataChanged); this, &ClangdSettingsWidget::settingsDataChanged);
connect(&d->clangdChooser, &Utils::PathChooser::pathChanged, connect(&d->clangdChooser, &Utils::PathChooser::pathChanged,
@@ -329,6 +339,7 @@ ClangdSettings::Data ClangdSettingsWidget::settingsData() const
data.useClangd = d->useClangdCheckBox.isChecked(); data.useClangd = d->useClangdCheckBox.isChecked();
data.executableFilePath = d->clangdChooser.filePath(); data.executableFilePath = d->clangdChooser.filePath();
data.enableIndexing = d->indexingCheckBox.isChecked(); data.enableIndexing = d->indexingCheckBox.isChecked();
data.autoIncludeHeaders = d->autoIncludeHeadersCheckBox.isChecked();
data.workerThreadLimit = d->threadLimitSpinBox.value(); data.workerThreadLimit = d->threadLimitSpinBox.value();
data.documentUpdateThreshold = d->documentUpdateThreshold.value(); data.documentUpdateThreshold = d->documentUpdateThreshold.value();
return data; return data;