aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cppeditor
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2024-03-15 16:02:50 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2024-03-28 19:06:08 +0000
commit3ca0deef536d33163256fee9a50895f1ee5e4a75 (patch)
tree0a24461264862ae66ac3c07ef39ee40bc05d541c /src/plugins/cppeditor
parentfc8f1bc47df91e829c569cb5977677b835b86f88 (diff)
CppEditor: Move ClangdSettings into a dedicated set of files
They were originally put alongside the CppCodeModelSettings for simplicity, but there is no coupling (anymore?) between these two classes. Change-Id: Ic24df109b74a5b5c39de073c938c6de12f4aa319 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r--src/plugins/cppeditor/CMakeLists.txt1
-rw-r--r--src/plugins/cppeditor/clangdsettings.cpp491
-rw-r--r--src/plugins/cppeditor/clangdsettings.h162
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettings.cpp470
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettings.h150
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettingspage.cpp2
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs2
-rw-r--r--src/plugins/cppeditor/cpptoolsreuse.cpp1
-rw-r--r--src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp1
9 files changed, 660 insertions, 620 deletions
diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt
index ec5ad89cea..93c37beaca 100644
--- a/src/plugins/cppeditor/CMakeLists.txt
+++ b/src/plugins/cppeditor/CMakeLists.txt
@@ -93,6 +93,7 @@ add_qtc_plugin(CppEditor
cppvirtualfunctionassistprovider.cpp cppvirtualfunctionassistprovider.h
cppvirtualfunctionproposalitem.cpp cppvirtualfunctionproposalitem.h
cppworkingcopy.cpp cppworkingcopy.h
+ clangdsettings.cpp clangdsettings.h
cursorineditor.h
doxygengenerator.cpp doxygengenerator.h
editordocumenthandle.cpp editordocumenthandle.h
diff --git a/src/plugins/cppeditor/clangdsettings.cpp b/src/plugins/cppeditor/clangdsettings.cpp
new file mode 100644
index 0000000000..b5352af6d8
--- /dev/null
+++ b/src/plugins/cppeditor/clangdsettings.cpp
@@ -0,0 +1,491 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "clangdsettings.h"
+
+#include "clangdiagnosticconfigsmodel.h"
+#include "cppeditorconstants.h"
+#include "cppeditortr.h"
+#include "cpptoolsreuse.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/session.h>
+#include <projectexplorer/project.h>
+#include <utils/clangutils.h>
+#include <utils/qtcprocess.h>
+
+#include <QStandardPaths>
+#include <QVersionNumber>
+
+using namespace Utils;
+
+namespace CppEditor {
+
+static FilePath g_defaultClangdFilePath;
+static FilePath fallbackClangdFilePath()
+{
+ if (g_defaultClangdFilePath.exists())
+ return g_defaultClangdFilePath;
+ return Environment::systemEnvironment().searchInPath("clangd");
+}
+
+static Id initialClangDiagnosticConfigId() { return Constants::CPP_CLANG_DIAG_CONFIG_BUILDSYSTEM; }
+
+static Key clangdSettingsKey() { return "ClangdSettings"; }
+static Key useClangdKey() { return "UseClangdV7"; }
+static Key clangdPathKey() { return "ClangdPath"; }
+static Key clangdIndexingKey() { return "ClangdIndexing"; }
+static Key clangdProjectIndexPathKey() { return "ClangdProjectIndexPath"; }
+static Key clangdSessionIndexPathKey() { return "ClangdSessionIndexPath"; }
+static Key clangdIndexingPriorityKey() { return "ClangdIndexingPriority"; }
+static Key clangdHeaderSourceSwitchModeKey() { return "ClangdHeaderSourceSwitchMode"; }
+static Key clangdCompletionRankingModelKey() { return "ClangdCompletionRankingModel"; }
+static Key clangdHeaderInsertionKey() { return "ClangdHeaderInsertion"; }
+static Key clangdThreadLimitKey() { return "ClangdThreadLimit"; }
+static Key clangdDocumentThresholdKey() { return "ClangdDocumentThreshold"; }
+static Key clangdSizeThresholdEnabledKey() { return "ClangdSizeThresholdEnabled"; }
+static Key clangdSizeThresholdKey() { return "ClangdSizeThreshold"; }
+static Key useGlobalSettingsKey() { return "useGlobalSettings"; }
+static Key clangdblockIndexingSettingsKey() { return "blockIndexing"; }
+static Key sessionsWithOneClangdKey() { return "SessionsWithOneClangd"; }
+static Key diagnosticConfigIdKey() { return "diagnosticConfigId"; }
+static Key checkedHardwareKey() { return "checkedHardware"; }
+static Key completionResultsKey() { return "completionResults"; }
+
+QString ClangdSettings::priorityToString(const IndexingPriority &priority)
+{
+ switch (priority) {
+ case IndexingPriority::Background: return "background";
+ case IndexingPriority::Normal: return "normal";
+ case IndexingPriority::Low: return "low";
+ case IndexingPriority::Off: return {};
+ }
+ return {};
+}
+
+QString ClangdSettings::priorityToDisplayString(const IndexingPriority &priority)
+{
+ switch (priority) {
+ case IndexingPriority::Background: return Tr::tr("Background Priority");
+ case IndexingPriority::Normal: return Tr::tr("Normal Priority");
+ case IndexingPriority::Low: return Tr::tr("Low Priority");
+ case IndexingPriority::Off: return Tr::tr("Off");
+ }
+ return {};
+}
+
+QString ClangdSettings::headerSourceSwitchModeToDisplayString(HeaderSourceSwitchMode mode)
+{
+ switch (mode) {
+ case HeaderSourceSwitchMode::BuiltinOnly: return Tr::tr("Use Built-in Only");
+ case HeaderSourceSwitchMode::ClangdOnly: return Tr::tr("Use Clangd Only");
+ case HeaderSourceSwitchMode::Both: return Tr::tr("Try Both");
+ }
+ return {};
+}
+
+QString ClangdSettings::rankingModelToCmdLineString(CompletionRankingModel model)
+{
+ switch (model) {
+ case CompletionRankingModel::Default: break;
+ case CompletionRankingModel::DecisionForest: return "decision_forest";
+ case CompletionRankingModel::Heuristics: return "heuristics";
+ }
+ QTC_ASSERT(false, return {});
+}
+
+QString ClangdSettings::rankingModelToDisplayString(CompletionRankingModel model)
+{
+ switch (model) {
+ case CompletionRankingModel::Default: return Tr::tr("Default");
+ case CompletionRankingModel::DecisionForest: return Tr::tr("Decision Forest");
+ case CompletionRankingModel::Heuristics: return Tr::tr("Heuristics");
+ }
+ QTC_ASSERT(false, return {});
+}
+
+QString ClangdSettings::defaultProjectIndexPathTemplate()
+{
+ return QDir::toNativeSeparators("%{BuildConfig:BuildDirectory:FilePath}/.qtc_clangd");
+}
+
+QString ClangdSettings::defaultSessionIndexPathTemplate()
+{
+ return QDir::toNativeSeparators("%{IDE:UserResourcePath}/.qtc_clangd/%{Session:FileBaseName}");
+}
+
+ClangdSettings &ClangdSettings::instance()
+{
+ static ClangdSettings settings;
+ return settings;
+}
+
+ClangdSettings::ClangdSettings()
+{
+ loadSettings();
+ const auto sessionMgr = Core::SessionManager::instance();
+ connect(sessionMgr, &Core::SessionManager::sessionRemoved, this, [this](const QString &name) {
+ m_data.sessionsWithOneClangd.removeOne(name);
+ });
+ connect(sessionMgr,
+ &Core::SessionManager::sessionRenamed,
+ this,
+ [this](const QString &oldName, const QString &newName) {
+ const auto index = m_data.sessionsWithOneClangd.indexOf(oldName);
+ if (index != -1)
+ m_data.sessionsWithOneClangd[index] = newName;
+ });
+}
+
+bool ClangdSettings::useClangd() const
+{
+ return m_data.useClangd && clangdVersion(clangdFilePath()) >= minimumClangdVersion();
+}
+
+void ClangdSettings::setUseClangd(bool use) { instance().m_data.useClangd = use; }
+
+void ClangdSettings::setUseClangdAndSave(bool use)
+{
+ setUseClangd(use);
+ instance().saveSettings();
+}
+
+bool ClangdSettings::hardwareFulfillsRequirements()
+{
+ instance().m_data.haveCheckedHardwareReqirements = true;
+ instance().saveSettings();
+ const quint64 minRam = quint64(12) * 1024 * 1024 * 1024;
+ const std::optional<quint64> totalRam = Utils::HostOsInfo::totalMemoryInstalledInBytes();
+ return !totalRam || *totalRam >= minRam;
+}
+
+bool ClangdSettings::haveCheckedHardwareRequirements()
+{
+ return instance().data().haveCheckedHardwareReqirements;
+}
+
+void ClangdSettings::setDefaultClangdPath(const FilePath &filePath)
+{
+ g_defaultClangdFilePath = filePath;
+}
+
+void ClangdSettings::setCustomDiagnosticConfigs(const ClangDiagnosticConfigs &configs)
+{
+ if (instance().customDiagnosticConfigs() == configs)
+ return;
+ instance().m_data.customDiagnosticConfigs = configs;
+ instance().saveSettings();
+}
+
+FilePath ClangdSettings::clangdFilePath() const
+{
+ if (!m_data.executableFilePath.isEmpty())
+ return m_data.executableFilePath;
+ return fallbackClangdFilePath();
+}
+
+FilePath ClangdSettings::projectIndexPath(const Utils::MacroExpander &expander) const
+{
+ return FilePath::fromUserInput(expander.expand(m_data.projectIndexPathTemplate));
+}
+
+FilePath ClangdSettings::sessionIndexPath(const Utils::MacroExpander &expander) const
+{
+ return FilePath::fromUserInput(expander.expand(m_data.sessionIndexPathTemplate));
+}
+
+bool ClangdSettings::sizeIsOkay(const Utils::FilePath &fp) const
+{
+ return !sizeThresholdEnabled() || sizeThresholdInKb() * 1024 >= fp.fileSize();
+}
+
+ClangDiagnosticConfigs ClangdSettings::customDiagnosticConfigs() const
+{
+ return m_data.customDiagnosticConfigs;
+}
+
+Id ClangdSettings::diagnosticConfigId() const
+{
+ if (!diagnosticConfigsModel().hasConfigWithId(m_data.diagnosticConfigId))
+ return initialClangDiagnosticConfigId();
+ return m_data.diagnosticConfigId;
+}
+
+ClangDiagnosticConfig ClangdSettings::diagnosticConfig() const
+{
+ return diagnosticConfigsModel(customDiagnosticConfigs()).configWithId(diagnosticConfigId());
+}
+
+ClangdSettings::Granularity ClangdSettings::granularity() const
+{
+ if (m_data.sessionsWithOneClangd.contains(Core::SessionManager::activeSession()))
+ return Granularity::Session;
+ return Granularity::Project;
+}
+
+void ClangdSettings::setData(const Data &data)
+{
+ if (this == &instance() && data != m_data) {
+ m_data = data;
+ saveSettings();
+ emit changed();
+ }
+}
+
+static FilePath getClangHeadersPathFromClang(const FilePath &clangdFilePath)
+{
+ const FilePath clangFilePath = clangdFilePath.absolutePath().pathAppended("clang")
+ .withExecutableSuffix();
+ if (!clangFilePath.exists())
+ return {};
+ Process clang;
+ clang.setCommand({clangFilePath, {"-print-resource-dir"}});
+ clang.start();
+ if (!clang.waitForFinished())
+ return {};
+ const FilePath resourceDir = FilePath::fromUserInput(QString::fromLocal8Bit(
+ clang.rawStdOut().trimmed()));
+ if (resourceDir.isEmpty() || !resourceDir.exists())
+ return {};
+ const FilePath includeDir = resourceDir.pathAppended("include");
+ if (!includeDir.exists())
+ return {};
+ return includeDir;
+}
+
+static FilePath getClangHeadersPath(const FilePath &clangdFilePath)
+{
+ const FilePath headersPath = getClangHeadersPathFromClang(clangdFilePath);
+ if (!headersPath.isEmpty())
+ return headersPath;
+
+ const QVersionNumber version = Utils::clangdVersion(clangdFilePath);
+ QTC_ASSERT(!version.isNull(), return {});
+ static const QStringList libDirs{"lib", "lib64"};
+ const QStringList versionStrings{QString::number(version.majorVersion()), version.toString()};
+ for (const QString &libDir : libDirs) {
+ for (const QString &versionString : versionStrings) {
+ const FilePath includePath = clangdFilePath.absolutePath().parentDir()
+ .pathAppended(libDir).pathAppended("clang")
+ .pathAppended(versionString).pathAppended("include");
+ if (includePath.exists())
+ return includePath;
+ }
+ }
+ QTC_CHECK(false);
+ return {};
+}
+
+FilePath ClangdSettings::clangdIncludePath() const
+{
+ QTC_ASSERT(useClangd(), return {});
+ FilePath clangdPath = clangdFilePath();
+ QTC_ASSERT(!clangdPath.isEmpty() && clangdPath.exists(), return {});
+ static QHash<FilePath, FilePath> headersPathCache;
+ const auto it = headersPathCache.constFind(clangdPath);
+ if (it != headersPathCache.constEnd())
+ return *it;
+ const FilePath headersPath = getClangHeadersPath(clangdPath);
+ if (!headersPath.isEmpty())
+ headersPathCache.insert(clangdPath, headersPath);
+ return headersPath;
+}
+
+FilePath ClangdSettings::clangdUserConfigFilePath()
+{
+ return FilePath::fromString(
+ QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation))
+ / "clangd/config.yaml";
+}
+
+void ClangdSettings::loadSettings()
+{
+ const auto settings = Core::ICore::settings();
+
+ m_data.fromMap(Utils::storeFromSettings(clangdSettingsKey(), settings));
+
+ settings->beginGroup(Constants::CPPEDITOR_SETTINGSGROUP);
+ m_data.customDiagnosticConfigs = diagnosticConfigsFromSettings(settings);
+
+ // Pre-8.0 compat
+ static const Key oldKey("ClangDiagnosticConfig");
+ const QVariant configId = settings->value(oldKey);
+ if (configId.isValid()) {
+ m_data.diagnosticConfigId = Id::fromSetting(configId);
+ settings->setValue(oldKey, {});
+ }
+
+ settings->endGroup();
+}
+
+void ClangdSettings::saveSettings()
+{
+ const auto settings = Core::ICore::settings();
+ const ClangdSettings::Data defaultData;
+ Utils::storeToSettingsWithDefault(clangdSettingsKey(),
+ settings,
+ m_data.toMap(),
+ defaultData.toMap());
+ settings->beginGroup(Constants::CPPEDITOR_SETTINGSGROUP);
+ diagnosticConfigsToSettings(settings, m_data.customDiagnosticConfigs);
+ settings->endGroup();
+}
+
+#ifdef WITH_TESTS
+void ClangdSettings::setClangdFilePath(const FilePath &filePath)
+{
+ instance().m_data.executableFilePath = filePath;
+}
+#endif
+
+ClangdProjectSettings::ClangdProjectSettings(ProjectExplorer::Project *project) : m_project(project)
+{
+ loadSettings();
+}
+
+ClangdSettings::Data ClangdProjectSettings::settings() const
+{
+ const ClangdSettings::Data globalData = ClangdSettings::instance().data();
+ ClangdSettings::Data data = globalData;
+ if (!m_useGlobalSettings) {
+ data = m_customSettings;
+ // This property is global by definition.
+ data.sessionsWithOneClangd = ClangdSettings::instance().data().sessionsWithOneClangd;
+
+ // This list exists only once.
+ data.customDiagnosticConfigs = ClangdSettings::instance().data().customDiagnosticConfigs;
+ }
+ if (m_blockIndexing)
+ data.indexingPriority = ClangdSettings::IndexingPriority::Off;
+ return data;
+}
+
+void ClangdProjectSettings::setSettings(const ClangdSettings::Data &data)
+{
+ m_customSettings = data;
+ saveSettings();
+ ClangdSettings::setCustomDiagnosticConfigs(data.customDiagnosticConfigs);
+ emit ClangdSettings::instance().changed();
+}
+
+void ClangdProjectSettings::setUseGlobalSettings(bool useGlobal)
+{
+ m_useGlobalSettings = useGlobal;
+ saveSettings();
+ emit ClangdSettings::instance().changed();
+}
+
+void ClangdProjectSettings::setDiagnosticConfigId(Utils::Id configId)
+{
+ m_customSettings.diagnosticConfigId = configId;
+ saveSettings();
+ emit ClangdSettings::instance().changed();
+}
+
+void ClangdProjectSettings::blockIndexing()
+{
+ if (m_blockIndexing)
+ return;
+ m_blockIndexing = true;
+ saveSettings();
+ emit ClangdSettings::instance().changed();
+}
+
+void ClangdProjectSettings::unblockIndexing()
+{
+ if (!m_blockIndexing)
+ return;
+ m_blockIndexing = false;
+ saveSettings();
+ // Do not emit changed here since that would restart clients with blocked indexing
+}
+
+void ClangdProjectSettings::loadSettings()
+{
+ if (!m_project)
+ return;
+ const Store data = storeFromVariant(m_project->namedSettings(clangdSettingsKey()));
+ m_useGlobalSettings = data.value(useGlobalSettingsKey(), true).toBool();
+ m_blockIndexing = data.value(clangdblockIndexingSettingsKey(), false).toBool();
+ if (!m_useGlobalSettings)
+ m_customSettings.fromMap(data);
+}
+
+void ClangdProjectSettings::saveSettings()
+{
+ if (!m_project)
+ return;
+ Store data;
+ if (!m_useGlobalSettings)
+ data = m_customSettings.toMap();
+ data.insert(useGlobalSettingsKey(), m_useGlobalSettings);
+ data.insert(clangdblockIndexingSettingsKey(), m_blockIndexing);
+ m_project->setNamedSettings(clangdSettingsKey(), variantFromStore(data));
+}
+
+Store ClangdSettings::Data::toMap() const
+{
+ Store map;
+
+ map.insert(useClangdKey(), useClangd);
+
+ map.insert(clangdPathKey(),
+ executableFilePath != fallbackClangdFilePath() ? executableFilePath.toString()
+ : QString());
+
+ map.insert(clangdIndexingKey(), indexingPriority != IndexingPriority::Off);
+ map.insert(clangdIndexingPriorityKey(), int(indexingPriority));
+ map.insert(clangdProjectIndexPathKey(), projectIndexPathTemplate);
+ map.insert(clangdSessionIndexPathKey(), sessionIndexPathTemplate);
+ map.insert(clangdHeaderSourceSwitchModeKey(), int(headerSourceSwitchMode));
+ map.insert(clangdCompletionRankingModelKey(), int(completionRankingModel));
+ map.insert(clangdHeaderInsertionKey(), autoIncludeHeaders);
+ map.insert(clangdThreadLimitKey(), workerThreadLimit);
+ map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold);
+ map.insert(clangdSizeThresholdEnabledKey(), sizeThresholdEnabled);
+ map.insert(clangdSizeThresholdKey(), sizeThresholdInKb);
+ map.insert(sessionsWithOneClangdKey(), sessionsWithOneClangd);
+ map.insert(diagnosticConfigIdKey(), diagnosticConfigId.toSetting());
+ map.insert(checkedHardwareKey(), haveCheckedHardwareReqirements);
+ map.insert(completionResultsKey(), completionResults);
+ return map;
+}
+
+void ClangdSettings::Data::fromMap(const Store &map)
+{
+ useClangd = map.value(useClangdKey(), true).toBool();
+ executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString());
+ indexingPriority = IndexingPriority(
+ map.value(clangdIndexingPriorityKey(), int(this->indexingPriority)).toInt());
+ const auto it = map.find(clangdIndexingKey());
+ if (it != map.end() && !it->toBool())
+ indexingPriority = IndexingPriority::Off;
+ projectIndexPathTemplate
+ = map.value(clangdProjectIndexPathKey(), defaultProjectIndexPathTemplate()).toString();
+ sessionIndexPathTemplate
+ = map.value(clangdSessionIndexPathKey(), defaultSessionIndexPathTemplate()).toString();
+ headerSourceSwitchMode = HeaderSourceSwitchMode(map.value(clangdHeaderSourceSwitchModeKey(),
+ int(headerSourceSwitchMode)).toInt());
+ completionRankingModel = CompletionRankingModel(map.value(clangdCompletionRankingModelKey(),
+ int(completionRankingModel)).toInt());
+ autoIncludeHeaders = map.value(clangdHeaderInsertionKey(), false).toBool();
+ workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt();
+ documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt();
+ sizeThresholdEnabled = map.value(clangdSizeThresholdEnabledKey(), false).toBool();
+ sizeThresholdInKb = map.value(clangdSizeThresholdKey(), 1024).toLongLong();
+ sessionsWithOneClangd = map.value(sessionsWithOneClangdKey()).toStringList();
+ diagnosticConfigId = Id::fromSetting(map.value(diagnosticConfigIdKey(),
+ initialClangDiagnosticConfigId().toSetting()));
+ haveCheckedHardwareReqirements = map.value(checkedHardwareKey(), false).toBool();
+ completionResults = map.value(completionResultsKey(), defaultCompletionResults()).toInt();
+}
+
+int ClangdSettings::Data::defaultCompletionResults()
+{
+ // Default clangd --limit-results value is 100
+ bool ok = false;
+ const int userValue = qtcEnvironmentVariableIntValue("QTC_CLANGD_COMPLETION_RESULTS", &ok);
+ return ok ? userValue : 100;
+}
+
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/clangdsettings.h b/src/plugins/cppeditor/clangdsettings.h
new file mode 100644
index 0000000000..c1fb3b6ae8
--- /dev/null
+++ b/src/plugins/cppeditor/clangdsettings.h
@@ -0,0 +1,162 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "clangdiagnosticconfig.h"
+#include "cppeditor_global.h"
+
+#include <utils/filepath.h>
+#include <utils/store.h>
+
+namespace ProjectExplorer { class Project; }
+namespace Utils { class MacroExpander; }
+
+namespace CppEditor {
+
+// TODO: Can we move this to ClangCodeModel?
+class CPPEDITOR_EXPORT ClangdSettings : public QObject
+{
+ Q_OBJECT
+public:
+ enum class IndexingPriority { Off, Background, Normal, Low, };
+ enum class HeaderSourceSwitchMode { BuiltinOnly, ClangdOnly, Both };
+ enum class CompletionRankingModel { Default, DecisionForest, Heuristics };
+
+ static QString priorityToString(const IndexingPriority &priority);
+ static QString priorityToDisplayString(const IndexingPriority &priority);
+ static QString headerSourceSwitchModeToDisplayString(HeaderSourceSwitchMode mode);
+ static QString rankingModelToCmdLineString(CompletionRankingModel model);
+ static QString rankingModelToDisplayString(CompletionRankingModel model);
+ static QString defaultProjectIndexPathTemplate();
+ static QString defaultSessionIndexPathTemplate();
+
+ class CPPEDITOR_EXPORT Data
+ {
+ public:
+ Utils::Store toMap() const;
+ void fromMap(const Utils::Store &map);
+
+ friend bool operator==(const Data &s1, const Data &s2)
+ {
+ return s1.useClangd == s2.useClangd
+ && s1.executableFilePath == s2.executableFilePath
+ && s1.projectIndexPathTemplate == s2.projectIndexPathTemplate
+ && s1.sessionIndexPathTemplate == s2.sessionIndexPathTemplate
+ && s1.sessionsWithOneClangd == s2.sessionsWithOneClangd
+ && s1.customDiagnosticConfigs == s2.customDiagnosticConfigs
+ && s1.diagnosticConfigId == s2.diagnosticConfigId
+ && s1.workerThreadLimit == s2.workerThreadLimit
+ && s1.indexingPriority == s2.indexingPriority
+ && s1.headerSourceSwitchMode == s2.headerSourceSwitchMode
+ && s1.completionRankingModel == s2.completionRankingModel
+ && s1.autoIncludeHeaders == s2.autoIncludeHeaders
+ && s1.documentUpdateThreshold == s2.documentUpdateThreshold
+ && s1.sizeThresholdEnabled == s2.sizeThresholdEnabled
+ && s1.sizeThresholdInKb == s2.sizeThresholdInKb
+ && s1.haveCheckedHardwareReqirements == s2.haveCheckedHardwareReqirements
+ && s1.completionResults == s2.completionResults;
+ }
+ friend bool operator!=(const Data &s1, const Data &s2) { return !(s1 == s2); }
+
+ Utils::FilePath executableFilePath;
+ QStringList sessionsWithOneClangd;
+ ClangDiagnosticConfigs customDiagnosticConfigs;
+ Utils::Id diagnosticConfigId;
+
+ int workerThreadLimit = 0;
+ int documentUpdateThreshold = 500;
+ qint64 sizeThresholdInKb = 1024;
+ bool useClangd = true;
+ IndexingPriority indexingPriority = IndexingPriority::Low;
+ QString projectIndexPathTemplate = defaultProjectIndexPathTemplate();
+ QString sessionIndexPathTemplate = defaultSessionIndexPathTemplate();
+ HeaderSourceSwitchMode headerSourceSwitchMode = HeaderSourceSwitchMode::Both;
+ CompletionRankingModel completionRankingModel = CompletionRankingModel::Default;
+ bool autoIncludeHeaders = false;
+ bool sizeThresholdEnabled = false;
+ bool haveCheckedHardwareReqirements = false;
+ int completionResults = defaultCompletionResults();
+
+ private:
+ static int defaultCompletionResults();
+ };
+
+ ClangdSettings(const Data &data) : m_data(data) {}
+
+ static ClangdSettings &instance();
+ bool useClangd() const;
+ static void setUseClangd(bool use);
+ static void setUseClangdAndSave(bool use);
+
+ static bool hardwareFulfillsRequirements();
+ static bool haveCheckedHardwareRequirements();
+
+ static void setDefaultClangdPath(const Utils::FilePath &filePath);
+ static void setCustomDiagnosticConfigs(const ClangDiagnosticConfigs &configs);
+ Utils::FilePath clangdFilePath() const;
+ IndexingPriority indexingPriority() const { return m_data.indexingPriority; }
+ Utils::FilePath projectIndexPath(const Utils::MacroExpander &expander) const;
+ Utils::FilePath sessionIndexPath(const Utils::MacroExpander &expander) const;
+ HeaderSourceSwitchMode headerSourceSwitchMode() const { return m_data.headerSourceSwitchMode; }
+ CompletionRankingModel completionRankingModel() const { return m_data.completionRankingModel; }
+ bool autoIncludeHeaders() const { return m_data.autoIncludeHeaders; }
+ int workerThreadLimit() const { return m_data.workerThreadLimit; }
+ int documentUpdateThreshold() const { return m_data.documentUpdateThreshold; }
+ qint64 sizeThresholdInKb() const { return m_data.sizeThresholdInKb; }
+ bool sizeThresholdEnabled() const { return m_data.sizeThresholdEnabled; }
+ int completionResults() const { return m_data.completionResults; }
+ bool sizeIsOkay(const Utils::FilePath &fp) const;
+ ClangDiagnosticConfigs customDiagnosticConfigs() const;
+ Utils::Id diagnosticConfigId() const;
+ ClangDiagnosticConfig diagnosticConfig() const;
+
+ enum class Granularity { Project, Session };
+ Granularity granularity() const;
+
+ void setData(const Data &data);
+ Data data() const { return m_data; }
+
+ Utils::FilePath clangdIncludePath() const;
+ static Utils::FilePath clangdUserConfigFilePath();
+
+#ifdef WITH_TESTS
+ static void setClangdFilePath(const Utils::FilePath &filePath);
+#endif
+
+signals:
+ void changed();
+
+private:
+ ClangdSettings();
+
+ void loadSettings();
+ void saveSettings();
+
+ Data m_data;
+};
+
+class CPPEDITOR_EXPORT ClangdProjectSettings
+{
+public:
+ ClangdProjectSettings(ProjectExplorer::Project *project);
+
+ ClangdSettings::Data settings() const;
+ void setSettings(const ClangdSettings::Data &data);
+ bool useGlobalSettings() const { return m_useGlobalSettings; }
+ void setUseGlobalSettings(bool useGlobal);
+ void setDiagnosticConfigId(Utils::Id configId);
+ void blockIndexing();
+ void unblockIndexing();
+
+private:
+ void loadSettings();
+ void saveSettings();
+
+ ProjectExplorer::Project * const m_project;
+ ClangdSettings::Data m_customSettings;
+ bool m_useGlobalSettings = true;
+ bool m_blockIndexing = false;
+};
+
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp
index d1b4c47098..d4a309363a 100644
--- a/src/plugins/cppeditor/cppcodemodelsettings.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp
@@ -3,14 +3,10 @@
#include "cppcodemodelsettings.h"
-#include "clangdiagnosticconfigsmodel.h"
#include "compileroptionsbuilder.h"
#include "cppeditorconstants.h"
-#include "cppeditortr.h"
-#include "cpptoolsreuse.h"
#include <coreplugin/icore.h>
-#include <coreplugin/session.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectmanager.h>
@@ -27,14 +23,12 @@
#include <QHash>
#include <QPair>
#include <QSettings>
-#include <QStandardPaths>
using namespace ProjectExplorer;
using namespace Utils;
namespace CppEditor {
-static Id initialClangDiagnosticConfigId() { return Constants::CPP_CLANG_DIAG_CONFIG_BUILDSYSTEM; }
static Key pchUsageKey() { return Constants::CPPEDITOR_MODEL_MANAGER_PCH_USAGE; }
static Key interpretAmbiguousHeadersAsCHeadersKey()
{ return Constants::CPPEDITOR_INTERPRET_AMBIGIUOUS_HEADERS_AS_C_HEADERS; }
@@ -43,35 +37,7 @@ static Key ignoreFilesKey() { return Constants::CPPEDITOR_IGNORE_FILES; }
static Key ignorePatternKey() { return Constants::CPPEDITOR_IGNORE_PATTERN; }
static Key useBuiltinPreprocessorKey() { return Constants::CPPEDITOR_USE_BUILTIN_PREPROCESSOR; }
static Key indexerFileSizeLimitKey() { return Constants::CPPEDITOR_INDEXER_FILE_SIZE_LIMIT; }
-
-static Key clangdSettingsKey() { return "ClangdSettings"; }
-static Key useClangdKey() { return "UseClangdV7"; }
-static Key clangdPathKey() { return "ClangdPath"; }
-static Key clangdIndexingKey() { return "ClangdIndexing"; }
-static Key clangdProjectIndexPathKey() { return "ClangdProjectIndexPath"; }
-static Key clangdSessionIndexPathKey() { return "ClangdSessionIndexPath"; }
-static Key clangdIndexingPriorityKey() { return "ClangdIndexingPriority"; }
-static Key clangdHeaderSourceSwitchModeKey() { return "ClangdHeaderSourceSwitchMode"; }
-static Key clangdCompletionRankingModelKey() { return "ClangdCompletionRankingModel"; }
-static Key clangdHeaderInsertionKey() { return "ClangdHeaderInsertion"; }
-static Key clangdThreadLimitKey() { return "ClangdThreadLimit"; }
-static Key clangdDocumentThresholdKey() { return "ClangdDocumentThreshold"; }
-static Key clangdSizeThresholdEnabledKey() { return "ClangdSizeThresholdEnabled"; }
-static Key clangdSizeThresholdKey() { return "ClangdSizeThreshold"; }
static Key useGlobalSettingsKey() { return "useGlobalSettings"; }
-static Key clangdblockIndexingSettingsKey() { return "blockIndexing"; }
-static Key sessionsWithOneClangdKey() { return "SessionsWithOneClangd"; }
-static Key diagnosticConfigIdKey() { return "diagnosticConfigId"; }
-static Key checkedHardwareKey() { return "checkedHardware"; }
-static Key completionResultsKey() { return "completionResults"; }
-
-static FilePath g_defaultClangdFilePath;
-static FilePath fallbackClangdFilePath()
-{
- if (g_defaultClangdFilePath.exists())
- return g_defaultClangdFilePath;
- return Environment::systemEnvironment().searchInPath("clangd");
-}
bool operator==(const CppEditor::CppCodeModelSettings::Data &s1,
const CppEditor::CppCodeModelSettings::Data &s2)
@@ -230,440 +196,4 @@ void CppCodeModelProjectSettings::saveSettings()
m_project->setNamedSettings(Constants::CPPEDITOR_SETTINGSGROUP, variantFromStore(data));
}
-QString ClangdSettings::priorityToString(const IndexingPriority &priority)
-{
- switch (priority) {
- case IndexingPriority::Background: return "background";
- case IndexingPriority::Normal: return "normal";
- case IndexingPriority::Low: return "low";
- case IndexingPriority::Off: return {};
- }
- return {};
-}
-
-QString ClangdSettings::priorityToDisplayString(const IndexingPriority &priority)
-{
- switch (priority) {
- case IndexingPriority::Background: return Tr::tr("Background Priority");
- case IndexingPriority::Normal: return Tr::tr("Normal Priority");
- case IndexingPriority::Low: return Tr::tr("Low Priority");
- case IndexingPriority::Off: return Tr::tr("Off");
- }
- return {};
-}
-
-QString ClangdSettings::headerSourceSwitchModeToDisplayString(HeaderSourceSwitchMode mode)
-{
- switch (mode) {
- case HeaderSourceSwitchMode::BuiltinOnly: return Tr::tr("Use Built-in Only");
- case HeaderSourceSwitchMode::ClangdOnly: return Tr::tr("Use Clangd Only");
- case HeaderSourceSwitchMode::Both: return Tr::tr("Try Both");
- }
- return {};
-}
-
-QString ClangdSettings::rankingModelToCmdLineString(CompletionRankingModel model)
-{
- switch (model) {
- case CompletionRankingModel::Default: break;
- case CompletionRankingModel::DecisionForest: return "decision_forest";
- case CompletionRankingModel::Heuristics: return "heuristics";
- }
- QTC_ASSERT(false, return {});
-}
-
-QString ClangdSettings::rankingModelToDisplayString(CompletionRankingModel model)
-{
- switch (model) {
- case CompletionRankingModel::Default: return Tr::tr("Default");
- case CompletionRankingModel::DecisionForest: return Tr::tr("Decision Forest");
- case CompletionRankingModel::Heuristics: return Tr::tr("Heuristics");
- }
- QTC_ASSERT(false, return {});
-}
-
-QString ClangdSettings::defaultProjectIndexPathTemplate()
-{
- return QDir::toNativeSeparators("%{BuildConfig:BuildDirectory:FilePath}/.qtc_clangd");
-}
-
-QString ClangdSettings::defaultSessionIndexPathTemplate()
-{
- return QDir::toNativeSeparators("%{IDE:UserResourcePath}/.qtc_clangd/%{Session:FileBaseName}");
-}
-
-ClangdSettings &ClangdSettings::instance()
-{
- static ClangdSettings settings;
- return settings;
-}
-
-ClangdSettings::ClangdSettings()
-{
- loadSettings();
- const auto sessionMgr = Core::SessionManager::instance();
- connect(sessionMgr, &Core::SessionManager::sessionRemoved, this, [this](const QString &name) {
- m_data.sessionsWithOneClangd.removeOne(name);
- });
- connect(sessionMgr,
- &Core::SessionManager::sessionRenamed,
- this,
- [this](const QString &oldName, const QString &newName) {
- const auto index = m_data.sessionsWithOneClangd.indexOf(oldName);
- if (index != -1)
- m_data.sessionsWithOneClangd[index] = newName;
- });
-}
-
-bool ClangdSettings::useClangd() const
-{
- return m_data.useClangd && clangdVersion(clangdFilePath()) >= minimumClangdVersion();
-}
-
-void ClangdSettings::setUseClangd(bool use) { instance().m_data.useClangd = use; }
-
-void ClangdSettings::setUseClangdAndSave(bool use)
-{
- setUseClangd(use);
- instance().saveSettings();
-}
-
-bool ClangdSettings::hardwareFulfillsRequirements()
-{
- instance().m_data.haveCheckedHardwareReqirements = true;
- instance().saveSettings();
- const quint64 minRam = quint64(12) * 1024 * 1024 * 1024;
- const std::optional<quint64> totalRam = Utils::HostOsInfo::totalMemoryInstalledInBytes();
- return !totalRam || *totalRam >= minRam;
-}
-
-bool ClangdSettings::haveCheckedHardwareRequirements()
-{
- return instance().data().haveCheckedHardwareReqirements;
-}
-
-void ClangdSettings::setDefaultClangdPath(const FilePath &filePath)
-{
- g_defaultClangdFilePath = filePath;
-}
-
-void ClangdSettings::setCustomDiagnosticConfigs(const ClangDiagnosticConfigs &configs)
-{
- if (instance().customDiagnosticConfigs() == configs)
- return;
- instance().m_data.customDiagnosticConfigs = configs;
- instance().saveSettings();
-}
-
-FilePath ClangdSettings::clangdFilePath() const
-{
- if (!m_data.executableFilePath.isEmpty())
- return m_data.executableFilePath;
- return fallbackClangdFilePath();
-}
-
-FilePath ClangdSettings::projectIndexPath(const Utils::MacroExpander &expander) const
-{
- return FilePath::fromUserInput(expander.expand(m_data.projectIndexPathTemplate));
-}
-
-FilePath ClangdSettings::sessionIndexPath(const Utils::MacroExpander &expander) const
-{
- return FilePath::fromUserInput(expander.expand(m_data.sessionIndexPathTemplate));
-}
-
-bool ClangdSettings::sizeIsOkay(const Utils::FilePath &fp) const
-{
- return !sizeThresholdEnabled() || sizeThresholdInKb() * 1024 >= fp.fileSize();
-}
-
-ClangDiagnosticConfigs ClangdSettings::customDiagnosticConfigs() const
-{
- return m_data.customDiagnosticConfigs;
-}
-
-Id ClangdSettings::diagnosticConfigId() const
-{
- if (!diagnosticConfigsModel().hasConfigWithId(m_data.diagnosticConfigId))
- return initialClangDiagnosticConfigId();
- return m_data.diagnosticConfigId;
-}
-
-ClangDiagnosticConfig ClangdSettings::diagnosticConfig() const
-{
- return diagnosticConfigsModel(customDiagnosticConfigs()).configWithId(diagnosticConfigId());
-}
-
-ClangdSettings::Granularity ClangdSettings::granularity() const
-{
- if (m_data.sessionsWithOneClangd.contains(Core::SessionManager::activeSession()))
- return Granularity::Session;
- return Granularity::Project;
-}
-
-void ClangdSettings::setData(const Data &data)
-{
- if (this == &instance() && data != m_data) {
- m_data = data;
- saveSettings();
- emit changed();
- }
-}
-
-static FilePath getClangHeadersPathFromClang(const FilePath &clangdFilePath)
-{
- const FilePath clangFilePath = clangdFilePath.absolutePath().pathAppended("clang")
- .withExecutableSuffix();
- if (!clangFilePath.exists())
- return {};
- Process clang;
- clang.setCommand({clangFilePath, {"-print-resource-dir"}});
- clang.start();
- if (!clang.waitForFinished())
- return {};
- const FilePath resourceDir = FilePath::fromUserInput(QString::fromLocal8Bit(
- clang.rawStdOut().trimmed()));
- if (resourceDir.isEmpty() || !resourceDir.exists())
- return {};
- const FilePath includeDir = resourceDir.pathAppended("include");
- if (!includeDir.exists())
- return {};
- return includeDir;
-}
-
-static FilePath getClangHeadersPath(const FilePath &clangdFilePath)
-{
- const FilePath headersPath = getClangHeadersPathFromClang(clangdFilePath);
- if (!headersPath.isEmpty())
- return headersPath;
-
- const QVersionNumber version = Utils::clangdVersion(clangdFilePath);
- QTC_ASSERT(!version.isNull(), return {});
- static const QStringList libDirs{"lib", "lib64"};
- const QStringList versionStrings{QString::number(version.majorVersion()), version.toString()};
- for (const QString &libDir : libDirs) {
- for (const QString &versionString : versionStrings) {
- const FilePath includePath = clangdFilePath.absolutePath().parentDir()
- .pathAppended(libDir).pathAppended("clang")
- .pathAppended(versionString).pathAppended("include");
- if (includePath.exists())
- return includePath;
- }
- }
- QTC_CHECK(false);
- return {};
-}
-
-FilePath ClangdSettings::clangdIncludePath() const
-{
- QTC_ASSERT(useClangd(), return {});
- FilePath clangdPath = clangdFilePath();
- QTC_ASSERT(!clangdPath.isEmpty() && clangdPath.exists(), return {});
- static QHash<FilePath, FilePath> headersPathCache;
- const auto it = headersPathCache.constFind(clangdPath);
- if (it != headersPathCache.constEnd())
- return *it;
- const FilePath headersPath = getClangHeadersPath(clangdPath);
- if (!headersPath.isEmpty())
- headersPathCache.insert(clangdPath, headersPath);
- return headersPath;
-}
-
-FilePath ClangdSettings::clangdUserConfigFilePath()
-{
- return FilePath::fromString(
- QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation))
- / "clangd/config.yaml";
-}
-
-void ClangdSettings::loadSettings()
-{
- const auto settings = Core::ICore::settings();
-
- m_data.fromMap(Utils::storeFromSettings(clangdSettingsKey(), settings));
-
- settings->beginGroup(Constants::CPPEDITOR_SETTINGSGROUP);
- m_data.customDiagnosticConfigs = diagnosticConfigsFromSettings(settings);
-
- // Pre-8.0 compat
- static const Key oldKey("ClangDiagnosticConfig");
- const QVariant configId = settings->value(oldKey);
- if (configId.isValid()) {
- m_data.diagnosticConfigId = Id::fromSetting(configId);
- settings->setValue(oldKey, {});
- }
-
- settings->endGroup();
-}
-
-void ClangdSettings::saveSettings()
-{
- const auto settings = Core::ICore::settings();
- const ClangdSettings::Data defaultData;
- Utils::storeToSettingsWithDefault(clangdSettingsKey(),
- settings,
- m_data.toMap(),
- defaultData.toMap());
- settings->beginGroup(Constants::CPPEDITOR_SETTINGSGROUP);
- diagnosticConfigsToSettings(settings, m_data.customDiagnosticConfigs);
- settings->endGroup();
-}
-
-#ifdef WITH_TESTS
-void ClangdSettings::setClangdFilePath(const FilePath &filePath)
-{
- instance().m_data.executableFilePath = filePath;
-}
-#endif
-
-ClangdProjectSettings::ClangdProjectSettings(ProjectExplorer::Project *project) : m_project(project)
-{
- loadSettings();
-}
-
-ClangdSettings::Data ClangdProjectSettings::settings() const
-{
- const ClangdSettings::Data globalData = ClangdSettings::instance().data();
- ClangdSettings::Data data = globalData;
- if (!m_useGlobalSettings) {
- data = m_customSettings;
- // This property is global by definition.
- data.sessionsWithOneClangd = ClangdSettings::instance().data().sessionsWithOneClangd;
-
- // This list exists only once.
- data.customDiagnosticConfigs = ClangdSettings::instance().data().customDiagnosticConfigs;
-}
- if (m_blockIndexing)
- data.indexingPriority = ClangdSettings::IndexingPriority::Off;
- return data;
-}
-
-void ClangdProjectSettings::setSettings(const ClangdSettings::Data &data)
-{
- m_customSettings = data;
- saveSettings();
- ClangdSettings::setCustomDiagnosticConfigs(data.customDiagnosticConfigs);
- emit ClangdSettings::instance().changed();
-}
-
-void ClangdProjectSettings::setUseGlobalSettings(bool useGlobal)
-{
- m_useGlobalSettings = useGlobal;
- saveSettings();
- emit ClangdSettings::instance().changed();
-}
-
-void ClangdProjectSettings::setDiagnosticConfigId(Utils::Id configId)
-{
- m_customSettings.diagnosticConfigId = configId;
- saveSettings();
- emit ClangdSettings::instance().changed();
-}
-
-void ClangdProjectSettings::blockIndexing()
-{
- if (m_blockIndexing)
- return;
- m_blockIndexing = true;
- saveSettings();
- emit ClangdSettings::instance().changed();
-}
-
-void ClangdProjectSettings::unblockIndexing()
-{
- if (!m_blockIndexing)
- return;
- m_blockIndexing = false;
- saveSettings();
- // Do not emit changed here since that would restart clients with blocked indexing
-}
-
-void ClangdProjectSettings::loadSettings()
-{
- if (!m_project)
- return;
- const Store data = storeFromVariant(m_project->namedSettings(clangdSettingsKey()));
- m_useGlobalSettings = data.value(useGlobalSettingsKey(), true).toBool();
- m_blockIndexing = data.value(clangdblockIndexingSettingsKey(), false).toBool();
- if (!m_useGlobalSettings)
- m_customSettings.fromMap(data);
-}
-
-void ClangdProjectSettings::saveSettings()
-{
- if (!m_project)
- return;
- Store data;
- if (!m_useGlobalSettings)
- data = m_customSettings.toMap();
- data.insert(useGlobalSettingsKey(), m_useGlobalSettings);
- data.insert(clangdblockIndexingSettingsKey(), m_blockIndexing);
- m_project->setNamedSettings(clangdSettingsKey(), variantFromStore(data));
-}
-
-Store ClangdSettings::Data::toMap() const
-{
- Store map;
-
- map.insert(useClangdKey(), useClangd);
-
- map.insert(clangdPathKey(),
- executableFilePath != fallbackClangdFilePath() ? executableFilePath.toString()
- : QString());
-
- map.insert(clangdIndexingKey(), indexingPriority != IndexingPriority::Off);
- map.insert(clangdIndexingPriorityKey(), int(indexingPriority));
- map.insert(clangdProjectIndexPathKey(), projectIndexPathTemplate);
- map.insert(clangdSessionIndexPathKey(), sessionIndexPathTemplate);
- map.insert(clangdHeaderSourceSwitchModeKey(), int(headerSourceSwitchMode));
- map.insert(clangdCompletionRankingModelKey(), int(completionRankingModel));
- map.insert(clangdHeaderInsertionKey(), autoIncludeHeaders);
- map.insert(clangdThreadLimitKey(), workerThreadLimit);
- map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold);
- map.insert(clangdSizeThresholdEnabledKey(), sizeThresholdEnabled);
- map.insert(clangdSizeThresholdKey(), sizeThresholdInKb);
- map.insert(sessionsWithOneClangdKey(), sessionsWithOneClangd);
- map.insert(diagnosticConfigIdKey(), diagnosticConfigId.toSetting());
- map.insert(checkedHardwareKey(), haveCheckedHardwareReqirements);
- map.insert(completionResultsKey(), completionResults);
- return map;
-}
-
-void ClangdSettings::Data::fromMap(const Store &map)
-{
- useClangd = map.value(useClangdKey(), true).toBool();
- executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString());
- indexingPriority = IndexingPriority(
- map.value(clangdIndexingPriorityKey(), int(this->indexingPriority)).toInt());
- const auto it = map.find(clangdIndexingKey());
- if (it != map.end() && !it->toBool())
- indexingPriority = IndexingPriority::Off;
- projectIndexPathTemplate
- = map.value(clangdProjectIndexPathKey(), defaultProjectIndexPathTemplate()).toString();
- sessionIndexPathTemplate
- = map.value(clangdSessionIndexPathKey(), defaultSessionIndexPathTemplate()).toString();
- headerSourceSwitchMode = HeaderSourceSwitchMode(map.value(clangdHeaderSourceSwitchModeKey(),
- int(headerSourceSwitchMode)).toInt());
- completionRankingModel = CompletionRankingModel(map.value(clangdCompletionRankingModelKey(),
- int(completionRankingModel)).toInt());
- autoIncludeHeaders = map.value(clangdHeaderInsertionKey(), false).toBool();
- workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt();
- documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt();
- sizeThresholdEnabled = map.value(clangdSizeThresholdEnabledKey(), false).toBool();
- sizeThresholdInKb = map.value(clangdSizeThresholdKey(), 1024).toLongLong();
- sessionsWithOneClangd = map.value(sessionsWithOneClangdKey()).toStringList();
- diagnosticConfigId = Id::fromSetting(map.value(diagnosticConfigIdKey(),
- initialClangDiagnosticConfigId().toSetting()));
- haveCheckedHardwareReqirements = map.value(checkedHardwareKey(), false).toBool();
- completionResults = map.value(completionResultsKey(), defaultCompletionResults()).toInt();
-}
-
-int ClangdSettings::Data::defaultCompletionResults()
-{
- // Default clangd --limit-results value is 100
- bool ok = false;
- const int userValue = qtcEnvironmentVariableIntValue("QTC_CLANGD_COMPLETION_RESULTS", &ok);
- return ok ? userValue : 100;
-}
-
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h
index 19cc078b26..0bd9b05fbd 100644
--- a/src/plugins/cppeditor/cppcodemodelsettings.h
+++ b/src/plugins/cppeditor/cppcodemodelsettings.h
@@ -3,10 +3,8 @@
#pragma once
-#include "clangdiagnosticconfig.h"
#include "cppeditor_global.h"
-#include <utils/clangutils.h>
#include <utils/filepath.h>
#include <utils/id.h>
#include <utils/store.h>
@@ -14,12 +12,8 @@
#include <QObject>
#include <QStringList>
-#include <QVersionNumber>
namespace ProjectExplorer { class Project; }
-namespace Utils {
-class MacroExpander;
-} // namespace Utils
namespace CppEditor {
enum class UsePrecompiledHeaders;
@@ -114,148 +108,4 @@ private:
bool m_useGlobalSettings = true;
};
-class CPPEDITOR_EXPORT ClangdSettings : public QObject
-{
- Q_OBJECT
-public:
- enum class IndexingPriority { Off, Background, Normal, Low, };
- enum class HeaderSourceSwitchMode { BuiltinOnly, ClangdOnly, Both };
- enum class CompletionRankingModel { Default, DecisionForest, Heuristics };
-
- static QString priorityToString(const IndexingPriority &priority);
- static QString priorityToDisplayString(const IndexingPriority &priority);
- static QString headerSourceSwitchModeToDisplayString(HeaderSourceSwitchMode mode);
- static QString rankingModelToCmdLineString(CompletionRankingModel model);
- static QString rankingModelToDisplayString(CompletionRankingModel model);
- static QString defaultProjectIndexPathTemplate();
- static QString defaultSessionIndexPathTemplate();
-
- class CPPEDITOR_EXPORT Data
- {
- public:
- Utils::Store toMap() const;
- void fromMap(const Utils::Store &map);
-
- friend bool operator==(const Data &s1, const Data &s2)
- {
- return s1.useClangd == s2.useClangd
- && s1.executableFilePath == s2.executableFilePath
- && s1.projectIndexPathTemplate == s2.projectIndexPathTemplate
- && s1.sessionIndexPathTemplate == s2.sessionIndexPathTemplate
- && s1.sessionsWithOneClangd == s2.sessionsWithOneClangd
- && s1.customDiagnosticConfigs == s2.customDiagnosticConfigs
- && s1.diagnosticConfigId == s2.diagnosticConfigId
- && s1.workerThreadLimit == s2.workerThreadLimit
- && s1.indexingPriority == s2.indexingPriority
- && s1.headerSourceSwitchMode == s2.headerSourceSwitchMode
- && s1.completionRankingModel == s2.completionRankingModel
- && s1.autoIncludeHeaders == s2.autoIncludeHeaders
- && s1.documentUpdateThreshold == s2.documentUpdateThreshold
- && s1.sizeThresholdEnabled == s2.sizeThresholdEnabled
- && s1.sizeThresholdInKb == s2.sizeThresholdInKb
- && s1.haveCheckedHardwareReqirements == s2.haveCheckedHardwareReqirements
- && s1.completionResults == s2.completionResults;
- }
- friend bool operator!=(const Data &s1, const Data &s2) { return !(s1 == s2); }
-
- Utils::FilePath executableFilePath;
- QStringList sessionsWithOneClangd;
- ClangDiagnosticConfigs customDiagnosticConfigs;
- Utils::Id diagnosticConfigId;
-
- int workerThreadLimit = 0;
- int documentUpdateThreshold = 500;
- qint64 sizeThresholdInKb = 1024;
- bool useClangd = true;
- IndexingPriority indexingPriority = IndexingPriority::Low;
- QString projectIndexPathTemplate = defaultProjectIndexPathTemplate();
- QString sessionIndexPathTemplate = defaultSessionIndexPathTemplate();
- HeaderSourceSwitchMode headerSourceSwitchMode = HeaderSourceSwitchMode::Both;
- CompletionRankingModel completionRankingModel = CompletionRankingModel::Default;
- bool autoIncludeHeaders = false;
- bool sizeThresholdEnabled = false;
- bool haveCheckedHardwareReqirements = false;
- int completionResults = defaultCompletionResults();
-
- private:
- static int defaultCompletionResults();
- };
-
- ClangdSettings(const Data &data) : m_data(data) {}
-
- static ClangdSettings &instance();
- bool useClangd() const;
- static void setUseClangd(bool use);
- static void setUseClangdAndSave(bool use);
-
- static bool hardwareFulfillsRequirements();
- static bool haveCheckedHardwareRequirements();
-
- static void setDefaultClangdPath(const Utils::FilePath &filePath);
- static void setCustomDiagnosticConfigs(const ClangDiagnosticConfigs &configs);
- Utils::FilePath clangdFilePath() const;
- IndexingPriority indexingPriority() const { return m_data.indexingPriority; }
- Utils::FilePath projectIndexPath(const Utils::MacroExpander &expander) const;
- Utils::FilePath sessionIndexPath(const Utils::MacroExpander &expander) const;
- HeaderSourceSwitchMode headerSourceSwitchMode() const { return m_data.headerSourceSwitchMode; }
- CompletionRankingModel completionRankingModel() const { return m_data.completionRankingModel; }
- bool autoIncludeHeaders() const { return m_data.autoIncludeHeaders; }
- int workerThreadLimit() const { return m_data.workerThreadLimit; }
- int documentUpdateThreshold() const { return m_data.documentUpdateThreshold; }
- qint64 sizeThresholdInKb() const { return m_data.sizeThresholdInKb; }
- bool sizeThresholdEnabled() const { return m_data.sizeThresholdEnabled; }
- int completionResults() const { return m_data.completionResults; }
- bool sizeIsOkay(const Utils::FilePath &fp) const;
- ClangDiagnosticConfigs customDiagnosticConfigs() const;
- Utils::Id diagnosticConfigId() const;
- ClangDiagnosticConfig diagnosticConfig() const;
-
- enum class Granularity { Project, Session };
- Granularity granularity() const;
-
- void setData(const Data &data);
- Data data() const { return m_data; }
-
- Utils::FilePath clangdIncludePath() const;
- static Utils::FilePath clangdUserConfigFilePath();
-
-#ifdef WITH_TESTS
- static void setClangdFilePath(const Utils::FilePath &filePath);
-#endif
-
-signals:
- void changed();
-
-private:
- ClangdSettings();
-
- void loadSettings();
- void saveSettings();
-
- Data m_data;
-};
-
-class CPPEDITOR_EXPORT ClangdProjectSettings
-{
-public:
- ClangdProjectSettings(ProjectExplorer::Project *project);
-
- ClangdSettings::Data settings() const;
- void setSettings(const ClangdSettings::Data &data);
- bool useGlobalSettings() const { return m_useGlobalSettings; }
- void setUseGlobalSettings(bool useGlobal);
- void setDiagnosticConfigId(Utils::Id configId);
- void blockIndexing();
- void unblockIndexing();
-
-private:
- void loadSettings();
- void saveSettings();
-
- ProjectExplorer::Project * const m_project;
- ClangdSettings::Data m_customSettings;
- bool m_useGlobalSettings = true;
- bool m_blockIndexing = false;
-};
-
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
index 616bb34f61..0e880fcb55 100644
--- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
@@ -5,6 +5,7 @@
#include "clangdiagnosticconfigsselectionwidget.h"
#include "clangdiagnosticconfigswidget.h"
+#include "clangdsettings.h"
#include "cppcodemodelsettings.h"
#include "cppeditorconstants.h"
#include "cppeditortr.h"
@@ -18,6 +19,7 @@
#include <projectexplorer/projectsettingswidget.h>
#include <utils/algorithm.h>
+#include <utils/clangutils.h>
#include <utils/fancylineedit.h>
#include <utils/infolabel.h>
#include <utils/itemviews.h>
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index b684b0e0ea..b805e3fae9 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -45,6 +45,8 @@ QtcPlugin {
"clangdiagnosticconfigsselectionwidget.h",
"clangdiagnosticconfigswidget.cpp",
"clangdiagnosticconfigswidget.h",
+ "clangdsettings.cpp",
+ "clangdsettings.h",
"compileroptionsbuilder.cpp",
"compileroptionsbuilder.h",
"cppautocompleter.cpp",
diff --git a/src/plugins/cppeditor/cpptoolsreuse.cpp b/src/plugins/cppeditor/cpptoolsreuse.cpp
index f6e58abddf..947ecdd4c6 100644
--- a/src/plugins/cppeditor/cpptoolsreuse.cpp
+++ b/src/plugins/cppeditor/cpptoolsreuse.cpp
@@ -4,6 +4,7 @@
#include "cpptoolsreuse.h"
#include "clangdiagnosticconfigsmodel.h"
+#include "clangdsettings.h"
#include "cppautocompleter.h"
#include "cppcanonicalsymbol.h"
#include "cppcodemodelsettings.h"
diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
index 9bef50b0b8..41dd6b538f 100644
--- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
+++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
@@ -3,6 +3,7 @@
#include "followsymbol_switchmethoddecldef_test.h"
+#include "clangdsettings.h"
#include "cppcodemodelsettings.h"
#include "cppeditorwidget.h"
#include "cppfollowsymbolundercursor.h"