aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2024-02-08 15:00:55 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2024-02-12 11:38:57 +0000
commit1af555ad09be169bebc7525e4bb7e10ad4de271d (patch)
treee43a799ae9c08947c65d4983551dc853d0174d4c
parent7a055a2f0ad7bd99eb5629f8ce6dfa5ae7a27080 (diff)
ClangCodeModel: Let users configure the clangd index location
Fixes: QTCREATORBUG-27346 Change-Id: I9bc59f759682e70b761c0f22a011868008fc0360 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.cpp21
-rw-r--r--src/plugins/coreplugin/coreplugin.cpp4
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettings.cpp32
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettings.h34
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettingspage.cpp53
5 files changed, 120 insertions, 24 deletions
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
index 53d0e6f378..3c3fc18c91 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
@@ -45,6 +45,7 @@
#include <utils/algorithm.h>
#include <utils/async.h>
#include <utils/infobar.h>
+#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
#include <QApplication>
@@ -472,17 +473,15 @@ void ClangModelManagerSupport::connectToWidgetsMarkContextMenuRequested(QWidget
}
}
-static FilePath getJsonDbDir(const Project *project)
+static FilePath getJsonDbDir(Project *project)
{
- static const QString dirName(".qtc_clangd");
- if (!project) {
- const QString sessionDirName = FileUtils::fileSystemFriendlyName(
- SessionManager::activeSession());
- return ICore::userResourcePath() / dirName / sessionDirName; // TODO: Make configurable?
- }
- if (const Target * const target = project->activeTarget()) {
- if (const BuildConfiguration * const bc = target->activeBuildConfiguration())
- return bc->buildDirectory() / dirName;
+ if (!project)
+ return ClangdSettings::instance().sessionIndexPath(*globalMacroExpander());
+ if (const Target *const target = project->activeTarget()) {
+ if (const BuildConfiguration *const bc = target->activeBuildConfiguration()) {
+ return ClangdSettings(ClangdProjectSettings(project).settings())
+ .projectIndexPath(*bc->macroExpander());
+ }
}
return {};
}
@@ -696,7 +695,7 @@ ClangdClient *ClangModelManagerSupport::clientWithProject(const Project *project
void ClangModelManagerSupport::updateStaleIndexEntries()
{
QHash<FilePath, QDateTime> lastModifiedCache;
- for (const Project * const project : ProjectManager::projects()) {
+ for (Project * const project : ProjectManager::projects()) {
const FilePath jsonDbDir = getJsonDbDir(project);
if (jsonDbDir.isEmpty())
continue;
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index 49ca2fec8a..2ff53a68d0 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -226,6 +226,10 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
Tr::tr("The directory where %1 finds its pre-installed resources.")
.arg(QGuiApplication::applicationDisplayName()),
[] { return ICore::resourcePath().toString(); });
+ expander->registerVariable("IDE:UserResourcePath",
+ Tr::tr("The directory where %1 puts custom user data.")
+ .arg(QGuiApplication::applicationDisplayName()),
+ [] { return ICore::userResourcePath().toString(); });
expander->registerPrefix("CurrentDate:", Tr::tr("The current date (QDate formatstring)."),
[](const QString &fmt) { return QDate::currentDate().toString(fmt); });
expander->registerPrefix("CurrentTime:", Tr::tr("The current time (QTime formatstring)."),
diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp
index db6231cfe9..1c294af415 100644
--- a/src/plugins/cppeditor/cppcodemodelsettings.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp
@@ -15,10 +15,12 @@
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
+#include <utils/macroexpander.h>
#include <utils/process.h>
#include <utils/qtcassert.h>
#include <QDateTime>
+#include <QDir>
#include <QHash>
#include <QPair>
#include <QSettings>
@@ -45,6 +47,8 @@ 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"; }
@@ -248,6 +252,16 @@ QString ClangdSettings::rankingModelToDisplayString(CompletionRankingModel model
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;
@@ -318,6 +332,16 @@ FilePath ClangdSettings::clangdFilePath() const
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();
@@ -559,6 +583,10 @@ Store ClangdSettings::Data::toMap() const
map.insertValueWithDefault(clangdIndexingPriorityKey(),
int(indexingPriority),
int(DefaultIndexingPriority));
+ map.insertValueWithDefault(clangdProjectIndexPathKey(), projectIndexPathTemplate,
+ defaultProjectIndexPathTemplate());
+ map.insertValueWithDefault(clangdSessionIndexPathKey(), sessionIndexPathTemplate,
+ defaultSessionIndexPathTemplate());
map.insertValueWithDefault(clangdHeaderSourceSwitchModeKey(),
int(headerSourceSwitchMode),
@@ -610,6 +638,10 @@ void ClangdSettings::Data::fromMap(const Store &map)
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(DefaultHeaderSourceSwitchMode)).toInt());
completionRankingModel = CompletionRankingModel(
diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h
index b4f8ac7269..df0b81d9ca 100644
--- a/src/plugins/cppeditor/cppcodemodelsettings.h
+++ b/src/plugins/cppeditor/cppcodemodelsettings.h
@@ -17,6 +17,7 @@
#include <QVersionNumber>
namespace ProjectExplorer { class Project; }
+namespace Utils { class MacroExpander; }
namespace CppEditor {
@@ -92,6 +93,8 @@ public:
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
{
@@ -103,6 +106,8 @@ public:
{
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
@@ -119,34 +124,37 @@ public:
}
friend bool operator!=(const Data &s1, const Data &s2) { return !(s1 == s2); }
- static int defaultCompletionResults();
-
Utils::FilePath executableFilePath;
QStringList sessionsWithOneClangd;
ClangDiagnosticConfigs customDiagnosticConfigs;
Utils::Id diagnosticConfigId;
- static constexpr auto DefaultWorkerThreadLimit = 0;
- static constexpr auto DefaultDocumentUpdateThreshold = 500;
- static constexpr auto DefaultSizeThresholdInKb = 1024ll;
- static constexpr auto DefaultUseClangd = true;
- static constexpr auto DefaultIndexingPriority = ClangdSettings::IndexingPriority::Low;
- static constexpr auto DefaultHeaderSourceSwitchMode = HeaderSourceSwitchMode::Both;
- static constexpr auto DefaultCompletionRankingModel = CompletionRankingModel::Default;
- static constexpr auto DefaultAutoIncludeHeaders = false;
- static constexpr auto DefaultSizeThresholdEnabled = false;
-
int workerThreadLimit = DefaultWorkerThreadLimit;
int documentUpdateThreshold = DefaultDocumentUpdateThreshold;
qint64 sizeThresholdInKb = DefaultSizeThresholdInKb;
bool useClangd = DefaultUseClangd;
IndexingPriority indexingPriority = DefaultIndexingPriority;
+ QString projectIndexPathTemplate = defaultProjectIndexPathTemplate();
+ QString sessionIndexPathTemplate = defaultSessionIndexPathTemplate();
HeaderSourceSwitchMode headerSourceSwitchMode = DefaultHeaderSourceSwitchMode;
CompletionRankingModel completionRankingModel = DefaultCompletionRankingModel;
bool autoIncludeHeaders = DefaultAutoIncludeHeaders;
bool sizeThresholdEnabled = DefaultSizeThresholdEnabled;
bool haveCheckedHardwareReqirements = false;
int completionResults = defaultCompletionResults();
+
+ private:
+ static int defaultCompletionResults();
+
+ static constexpr auto DefaultWorkerThreadLimit = 0;
+ static constexpr auto DefaultDocumentUpdateThreshold = 500;
+ static constexpr auto DefaultSizeThresholdInKb = 1024ll;
+ static constexpr auto DefaultUseClangd = true;
+ static constexpr auto DefaultIndexingPriority = ClangdSettings::IndexingPriority::Low;
+ static constexpr auto DefaultHeaderSourceSwitchMode = HeaderSourceSwitchMode::Both;
+ static constexpr auto DefaultCompletionRankingModel = CompletionRankingModel::Default;
+ static constexpr auto DefaultAutoIncludeHeaders = false;
+ static constexpr auto DefaultSizeThresholdEnabled = false;
};
ClangdSettings(const Data &data) : m_data(data) {}
@@ -163,6 +171,8 @@ public:
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; }
diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
index bc47a78c9d..b4a19ccaae 100644
--- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
@@ -18,11 +18,13 @@
#include <projectexplorer/projectsettingswidget.h>
#include <utils/algorithm.h>
+#include <utils/fancylineedit.h>
#include <utils/infolabel.h>
#include <utils/itemviews.h>
#include <utils/layoutbuilder.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
+#include <utils/variablechooser.h>
#include <QCheckBox>
#include <QComboBox>
@@ -36,6 +38,7 @@
#include <QStringListModel>
#include <QTextBlock>
#include <QTextStream>
+#include <QTimer>
#include <QVBoxLayout>
#include <QVersionNumber>
@@ -220,6 +223,8 @@ signals:
private:
QCheckBox m_useClangdCheckBox;
QComboBox m_indexingComboBox;
+ Utils::FancyLineEdit m_projectIndexPathTemplateLineEdit;
+ Utils::FancyLineEdit m_sessionIndexPathTemplateLineEdit;
QComboBox m_headerSourceSwitchComboBox;
QComboBox m_completionRankingModelComboBox;
QCheckBox m_autoIncludeHeadersCheckBox;
@@ -249,6 +254,12 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
"cores unused.</p>"
"<p>Normal Priority: Reduced priority compared to interactive work.</p>"
"<p>Low Priority: Same priority as other clangd work.</p>");
+ const QString projectIndexPathToolTip = Tr::tr(
+ "The location of the per-project clangd index.<p>"
+ "This is also where the compile_commands.json file will go.");
+ const QString sessionIndexPathToolTip = Tr::tr(
+ "The location of the per-session clangd index.<p>"
+ "This is also where the compile_commands.json file will go.");
const QString headerSourceSwitchToolTip = Tr::tr(
"<p>The C/C++ backend to use for switching between header and source files.</p>"
"<p>While the clangd implementation has more capabilities than the built-in "
@@ -296,6 +307,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
m_indexingComboBox.setCurrentIndex(m_indexingComboBox.count() - 1);
}
m_indexingComboBox.setToolTip(indexingToolTip);
+ m_projectIndexPathTemplateLineEdit.setText(settings.data().projectIndexPathTemplate);
+ m_sessionIndexPathTemplateLineEdit.setText(settings.data().sessionIndexPathTemplate);
using SwitchMode = ClangdSettings::HeaderSourceSwitchMode;
for (SwitchMode mode : {SwitchMode::BuiltinOnly, SwitchMode::ClangdOnly, SwitchMode::Both}) {
m_headerSourceSwitchComboBox.addItem(
@@ -360,6 +373,33 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
indexingPriorityLabel->setToolTip(indexingToolTip);
formLayout->addRow(indexingPriorityLabel, indexingPriorityLayout);
+ for (const auto &[text, edit, toolTip, defaultValue] :
+ {std::make_tuple(Tr::tr("Per-project index location:"),
+ &m_projectIndexPathTemplateLineEdit,
+ projectIndexPathToolTip,
+ ClangdSettings::defaultProjectIndexPathTemplate()),
+ std::make_tuple(Tr::tr("Per-session index location:"),
+ &m_sessionIndexPathTemplateLineEdit,
+ sessionIndexPathToolTip,
+ ClangdSettings::defaultSessionIndexPathTemplate())}) {
+ if (isForProject && edit == &m_sessionIndexPathTemplateLineEdit)
+ continue;
+
+ const auto chooser = new Utils::VariableChooser(edit);
+ chooser->addSupportedWidget(edit);
+ chooser->addMacroExpanderProvider([] { return Utils::globalMacroExpander(); });
+
+ const auto resetButton = new QPushButton(Tr::tr("Reset"));
+ connect(resetButton, &QPushButton::clicked, [e = edit, v = defaultValue] { e->setText(v); });
+ const auto layout = new QHBoxLayout;
+ const auto label = new QLabel(text);
+ label->setToolTip(toolTip);
+ edit->setToolTip(toolTip);
+ layout->addWidget(edit);
+ layout->addWidget(resetButton);
+ formLayout->addRow(label, layout);
+ }
+
const auto headerSourceSwitchLayout = new QHBoxLayout;
headerSourceSwitchLayout->addWidget(&m_headerSourceSwitchComboBox);
headerSourceSwitchLayout->addStretch(1);
@@ -530,6 +570,10 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
this, &ClangdSettingsWidget::settingsDataChanged);
connect(&m_indexingComboBox, &QComboBox::currentIndexChanged,
this, &ClangdSettingsWidget::settingsDataChanged);
+ connect(&m_projectIndexPathTemplateLineEdit, &QLineEdit::textChanged,
+ this, &ClangdSettingsWidget::settingsDataChanged);
+ connect(&m_sessionIndexPathTemplateLineEdit, &QLineEdit::textChanged,
+ this, &ClangdSettingsWidget::settingsDataChanged);
connect(&m_headerSourceSwitchComboBox, &QComboBox::currentIndexChanged,
this, &ClangdSettingsWidget::settingsDataChanged);
connect(&m_completionRankingModelComboBox, &QComboBox::currentIndexChanged,
@@ -559,6 +603,8 @@ ClangdSettings::Data ClangdSettingsWidget::settingsData() const
data.executableFilePath = m_clangdChooser.filePath();
data.indexingPriority = ClangdSettings::IndexingPriority(
m_indexingComboBox.currentData().toInt());
+ data.projectIndexPathTemplate = m_projectIndexPathTemplateLineEdit.text();
+ data.sessionIndexPathTemplate = m_sessionIndexPathTemplateLineEdit.text();
data.headerSourceSwitchMode = ClangdSettings::HeaderSourceSwitchMode(
m_headerSourceSwitchComboBox.currentData().toInt());
data.completionRankingModel = ClangdSettings::CompletionRankingModel(
@@ -641,9 +687,14 @@ public:
m_settings.setSettings(m_widget.settingsData());
});
- connect(&m_widget, &ClangdSettingsWidget::settingsDataChanged, this, [this] {
+ const auto timer = new QTimer(this);
+ timer->setSingleShot(true);
+ timer->setInterval(5000);
+ connect(timer, &QTimer::timeout, this, [this] {
m_settings.setSettings(m_widget.settingsData());
});
+ connect(&m_widget, &ClangdSettingsWidget::settingsDataChanged,
+ timer, qOverload<>(&QTimer::start));
}
private: