CppTools: Add dedicated settings and settings page for clangd

We plan to add more clangd settings, and it makes sense to have a
dedicated place for them both in the code and the UI.

Change-Id: Ideb92935b7a5a6a98e07980f4011736fb82042d1
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-06-25 16:50:52 +02:00
parent cd20ad8ff4
commit ba138a1855
11 changed files with 168 additions and 87 deletions

View File

@@ -29,6 +29,8 @@
#include "cpptoolsconstants.h"
#include "cpptoolsreuse.h"
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -172,9 +174,6 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
const QVariant indexerFileSizeLimit = s->value(indexerFileSizeLimitKey(), 5);
setIndexerFileSizeLimitInMb(indexerFileSizeLimit.toInt());
setUseClangd(s->value(useClangdKey(), false).toBool());
setClangdFilePath(FilePath::fromString(s->value(clangdPathKey()).toString()));
s->endGroup();
if (write)
@@ -198,8 +197,6 @@ void CppCodeModelSettings::toSettings(QSettings *s)
s->setValue(interpretAmbiguousHeadersAsCHeadersKey(), interpretAmbigiousHeadersAsCHeaders());
s->setValue(skipIndexingBigFilesKey(), skipIndexingBigFiles());
s->setValue(indexerFileSizeLimitKey(), indexerFileSizeLimitInMb());
s->setValue(useClangdKey(), useClangd());
s->setValue(clangdPathKey(), m_clangdFilePath.toString());
s->endGroup();
@@ -300,14 +297,60 @@ void CppCodeModelSettings::setEnableLowerClazyLevels(bool yesno)
m_enableLowerClazyLevels = yesno;
}
void CppCodeModelSettings::setDefaultClangdPath(const Utils::FilePath &filePath)
static bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
{
return s1.useClangd == s2.useClangd && s1.executableFilePath == s2.executableFilePath;
}
static bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
{
return !(s1 == s2);
}
ClangdSettings &ClangdSettings::instance()
{
static ClangdSettings settings;
return settings;
}
void ClangdSettings::setDefaultClangdPath(const Utils::FilePath &filePath)
{
g_defaultClangdFilePath = filePath;
}
FilePath CppCodeModelSettings::clangdFilePath() const
FilePath ClangdSettings::clangdFilePath()
{
if (!m_clangdFilePath.isEmpty())
return m_clangdFilePath;
if (!instance().m_data.executableFilePath.isEmpty())
return instance().m_data.executableFilePath;
return fallbackClangdFilePath();
}
void ClangdSettings::setData(const Data &data)
{
if (data != instance().m_data) {
instance().m_data = data;
instance().saveSettings();
}
}
void ClangdSettings::loadSettings()
{
QSettings * const s = Core::ICore::settings();
m_data.useClangd = s->value(useClangdKey(), false).toBool();
m_data.executableFilePath = FilePath::fromString(s->value(clangdPathKey()).toString());
}
void ClangdSettings::saveSettings()
{
QSettings * const s = Core::ICore::settings();
s->setValue(useClangdKey(), useClangd());
s->setValue(clangdPathKey(), m_data.executableFilePath.toString());
}
#ifdef WITH_TESTS
void ClangdSettings::setUseClangd(bool use) { instance().m_data.useClangd = use; }
void ClangdSettings::setClangdFilePath(const Utils::FilePath &filePath)
{
instance().m_data.executableFilePath = filePath;
}
#endif

View File

@@ -78,13 +78,6 @@ public:
int indexerFileSizeLimitInMb() const;
void setIndexerFileSizeLimitInMb(int sizeInMB);
void setUseClangd(bool use) { m_useClangd = use; }
bool useClangd() const { return m_useClangd; }
static void setDefaultClangdPath(const Utils::FilePath &filePath);
void setClangdFilePath(const Utils::FilePath &filePath) { m_clangdFilePath = filePath; }
Utils::FilePath clangdFilePath() const;
void setCategorizeFindReferences(bool categorize) { m_categorizeFindReferences = categorize; }
bool categorizeFindReferences() const { return m_categorizeFindReferences; }
@@ -100,9 +93,40 @@ private:
ClangDiagnosticConfigs m_clangCustomDiagnosticConfigs;
Utils::Id m_clangDiagnosticConfigId;
bool m_enableLowerClazyLevels = true; // For UI behavior only
Utils::FilePath m_clangdFilePath;
bool m_useClangd = false;
bool m_categorizeFindReferences = false; // Ephemeral!
};
class CPPTOOLS_EXPORT ClangdSettings
{
public:
class Data
{
public:
bool useClangd = false;
Utils::FilePath executableFilePath;
};
static bool useClangd() { return instance().m_data.useClangd; }
static void setDefaultClangdPath(const Utils::FilePath &filePath);
static Utils::FilePath clangdFilePath();
static void setData(const Data &data);
static Data data() { return instance().m_data; }
#ifdef WITH_TESTS
static void setUseClangd(bool use);
static void setClangdFilePath(const Utils::FilePath &filePath);
#endif
private:
ClangdSettings() { loadSettings(); }
static ClangdSettings &instance();
void loadSettings();
void saveSettings();
Data m_data;
};
} // namespace CppTools

View File

@@ -33,7 +33,9 @@
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/pathchooser.h>
#include <QFormLayout>
#include <QTextStream>
namespace CppTools {
@@ -100,8 +102,6 @@ void CppCodeModelSettingsWidget::setupClangCodeModelWidgets()
const bool isClangActive = CppModelManager::instance()->isClangCodeModelActive();
m_ui->clangCodeModelIsDisabledHint->setVisible(!isClangActive);
m_ui->clangCodeModelIsEnabledHint->setVisible(isClangActive);
m_ui->clangdCheckBox->setVisible(isClangActive);
m_ui->clangdChooser->setVisible(isClangActive);
for (int i = 0; i < m_ui->clangDiagnosticConfigsSelectionWidget->layout()->count(); ++i) {
QWidget *widget = m_ui->clangDiagnosticConfigsSelectionWidget->layout()->itemAt(i)->widget();
@@ -120,16 +120,6 @@ void CppCodeModelSettingsWidget::setupGeneralWidgets()
const bool ignorePch = m_settings->pchUsage() == CppCodeModelSettings::PchUse_None;
m_ui->ignorePCHCheckBox->setChecked(ignorePch);
m_ui->clangdCheckBox->setChecked(m_settings->useClangd());
m_ui->clangdCheckBox->setToolTip(tr("Use clangd for locators and \"Find References\".\n"
"Changing this option does not affect projects that are already open."));
m_ui->clangdChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui->clangdChooser->setFilePath(codeModelSettings()->clangdFilePath());
m_ui->clangdChooser->setEnabled(m_ui->clangdCheckBox->isChecked());
connect(m_ui->clangdCheckBox, &QCheckBox::toggled, m_ui->clangdChooser, [this](bool checked) {
m_ui->clangdChooser->setEnabled(checked);
});
}
bool CppCodeModelSettingsWidget::applyClangCodeModelWidgetsToSettings() const
@@ -176,16 +166,6 @@ bool CppCodeModelSettingsWidget::applyGeneralWidgetsToSettings() const
m_settings->setIndexerFileSizeLimitInMb(newFileSizeLimit);
settingsChanged = true;
}
const bool newUseClangd = m_ui->clangdCheckBox->isChecked();
if (m_settings->useClangd() != newUseClangd) {
m_settings->setUseClangd(newUseClangd);
settingsChanged = true;
}
const Utils::FilePath newClangdPath = m_ui->clangdChooser->rawFilePath();
if (m_settings->clangdFilePath() != newClangdPath) {
m_settings->setClangdFilePath(newClangdPath);
settingsChanged = true;
}
const bool newIgnorePch = m_ui->ignorePCHCheckBox->isChecked();
const bool previousIgnorePch = m_settings->pchUsage() == CppCodeModelSettings::PchUse_None;
@@ -210,5 +190,60 @@ CppCodeModelSettingsPage::CppCodeModelSettingsPage(CppCodeModelSettings *setting
setWidgetCreator([settings] { return new CppCodeModelSettingsWidget(settings); });
}
class ClangdSettingsWidget final : public Core::IOptionsPageWidget
{
Q_DECLARE_TR_FUNCTIONS(CppTools::Internal::ClangdSettingsWidget)
public:
ClangdSettingsWidget()
{
m_useClangdCheckBox.setText(tr("Use clangd (EXPERIMENTAL)"));
m_useClangdCheckBox.setChecked(ClangdSettings::useClangd());
m_useClangdCheckBox.setToolTip(tr("Changing this option does not affect projects "
"that are already open."));
m_clangdChooser.setExpectedKind(Utils::PathChooser::ExistingCommand);
m_clangdChooser.setFilePath(ClangdSettings::clangdFilePath());
m_clangdChooser.setEnabled(m_useClangdCheckBox.isChecked());
const auto layout = new QVBoxLayout(this);
layout->addWidget(&m_useClangdCheckBox);
const auto formLayout = new QFormLayout;
const auto chooserLabel = new QLabel(tr("Path to executable:"));
formLayout->addRow(chooserLabel, &m_clangdChooser);
layout->addLayout(formLayout);
layout->addStretch(1);
const auto toggleEnabled = [=](const bool checked) {
chooserLabel->setEnabled(checked);
m_clangdChooser.setEnabled(checked);
};
connect(&m_useClangdCheckBox, &QCheckBox::toggled, toggleEnabled);
toggleEnabled(m_useClangdCheckBox.isChecked());
}
private:
void apply() final
{
ClangdSettings::Data data;
data.useClangd = m_useClangdCheckBox.isChecked();
data.executableFilePath = m_clangdChooser.filePath();
ClangdSettings::setData(data);
}
QCheckBox m_useClangdCheckBox;
Utils::PathChooser m_clangdChooser;
};
ClangdSettingsPage::ClangdSettingsPage()
{
setId("K.Clangd");
setDisplayName(ClangdSettingsWidget::tr("Clangd"));
setCategory(Constants::CPP_SETTINGS_CATEGORY);
setWidgetCreator([] { return new ClangdSettingsWidget; });
}
} // Internal
} // CppTools

View File

@@ -38,5 +38,11 @@ public:
explicit CppCodeModelSettingsPage(CppCodeModelSettings *settings);
};
class ClangdSettingsPage final : public Core::IOptionsPage
{
public:
explicit ClangdSettingsPage();
};
} // Internal namespace
} // CppTools namespace

View File

@@ -81,31 +81,7 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="clangdCheckBox">
<property name="text">
<string>Use clangd (EXPERIMENTAL)</string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="clangdChooser"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<layout class="QHBoxLayout" name="horizontalLayout_3"/>
</item>
</layout>
</widget>
@@ -174,11 +150,6 @@
<extends>QWidget</extends>
<header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
</customwidget>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QLineEdit</extends>
<header location="global">utils/pathchooser.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@@ -86,6 +86,7 @@ public:
~CppToolsPluginPrivate()
{
ExtensionSystem::PluginManager::removeObject(&m_cppProjectUpdaterFactory);
delete m_clangdSettingsPage;
}
StringTable stringTable;
@@ -95,6 +96,7 @@ public:
CppFileSettings m_fileSettings;
CppFileSettingsPage m_cppFileSettingsPage{&m_fileSettings};
CppCodeModelSettingsPage m_cppCodeModelSettingsPage{&m_codeModelSettings};
ClangdSettingsPage *m_clangdSettingsPage = nullptr;
CppCodeStyleSettingsPage m_cppCodeStyleSettingsPage;
CppProjectUpdaterFactory m_cppProjectUpdaterFactory;
};
@@ -218,6 +220,8 @@ void CppToolsPlugin::extensionsInitialized()
d->m_fileSettings.fromSettings(ICore::settings());
if (!d->m_fileSettings.applySuffixesToMimeDB())
qWarning("Unable to apply cpp suffixes to mime database (cpp mime types not found).\n");
if (CppModelManager::instance()->isClangCodeModelActive())
d->m_clangdSettingsPage = new ClangdSettingsPage;
}
CppCodeModelSettings *CppToolsPlugin::codeModelSettings()