From 25e1266c26843a9f822910717fe19429d863095b Mon Sep 17 00:00:00 2001 From: Sami Shalayel Date: Fri, 1 Sep 2023 11:40:37 +0200 Subject: [PATCH] qmljs: add option to disable builtin codemodel Add an option in the QML Language Server settings to disable the code model, for now it allows to use qmlls for renaming and find usages operations. Some of the checkboxes in the qmlls settings were not making a lot of sense, rephrased them to be easier to understand for the user. TODOs for later commits: * use qmlls for 'go to definition' aka 'follow symbol under cursor' * add extra action to the context menu for 'go to type definition' and implement it using the language client * also, remove builtin codemode stuff from the context menu when the builtin model is disabled Task-number: QTCREATORBUG-29567 Change-Id: I6283d99bd2b5dc8aef7df49994eb313bfbb854c6 Reviewed-by: David Schulz Reviewed-by: Ulf Hermann --- .../qmljseditor/qmljseditingsettingspage.cpp | 20 ++++++++--- src/plugins/qmljseditor/qmljseditor.cpp | 33 +++++++++++++++++-- src/plugins/qmljseditor/qmllssettings.h | 4 ++- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp index 3b53185bcfe..f28fa5d8c17 100644 --- a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp +++ b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp @@ -33,6 +33,7 @@ const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned"; const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData"; const char USE_QMLLS[] = "QmlJSEditor.UseQmlls"; const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls"; +const char DISABLE_BUILTIN_CODEMODEL[] = "QmlJSEditor.DisableBuiltinCodemodel"; const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode"; const char FORMAT_COMMAND[] = "QmlJSEditor.formatCommand"; const char FORMAT_COMMAND_OPTIONS[] = "QmlJSEditor.formatCommandOptions"; @@ -101,6 +102,8 @@ void QmlJsEditingSettings::fromSettings(QSettings *settings) m_uiQmlOpenMode = settings->value(UIQML_OPEN_MODE, "").toString(); m_qmllsSettings.useQmlls = settings->value(USE_QMLLS, QVariant(false)).toBool(); m_qmllsSettings.useLatestQmlls = settings->value(USE_LATEST_QMLLS, QVariant(false)).toBool(); + m_qmllsSettings.disableBuiltinCodemodel + = settings->value(DISABLE_BUILTIN_CODEMODEL, QVariant(false)).toBool(); m_formatCommand = settings->value(FORMAT_COMMAND, {}).toString(); m_formatCommandOptions = settings->value(FORMAT_COMMAND_OPTIONS, {}).toString(); m_useCustomFormatCommand = settings->value(CUSTOM_COMMAND, QVariant(false)).toBool(); @@ -128,6 +131,7 @@ void QmlJsEditingSettings::toSettings(QSettings *settings) const settings->setValue(UIQML_OPEN_MODE, m_uiQmlOpenMode); settings->setValue(USE_QMLLS, m_qmllsSettings.useQmlls); settings->setValue(USE_LATEST_QMLLS, m_qmllsSettings.useLatestQmlls); + settings->setValue(DISABLE_BUILTIN_CODEMODEL, m_qmllsSettings.disableBuiltinCodemodel); Utils::QtcSettings::setValueWithDefault(settings, FORMAT_COMMAND, m_formatCommand, {}); Utils::QtcSettings::setValueWithDefault(settings, FORMAT_COMMAND_OPTIONS, @@ -396,13 +400,19 @@ public: uiQmlOpenComboBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); uiQmlOpenComboBox->setSizeAdjustPolicy(QComboBox::QComboBox::AdjustToContents); - useQmlls = new QCheckBox(Tr::tr("Use qmlls (EXPERIMENTAL!)")); + useQmlls = new QCheckBox(Tr::tr("Enable QML Language Server (EXPERIMENTAL!)")); useQmlls->setChecked(s.qmllsSettings().useQmlls); - useLatestQmlls = new QCheckBox(Tr::tr("Always use latest qmlls")); + disableBuiltInCodemodel = new QCheckBox( + Tr::tr("Use QML Language Server advanced features (renaming, find usages and co.) " + "(EXPERIMENTAL!)")); + disableBuiltInCodemodel->setChecked(s.qmllsSettings().disableBuiltinCodemodel); + disableBuiltInCodemodel->setEnabled(s.qmllsSettings().useQmlls); + useLatestQmlls = new QCheckBox(Tr::tr("Use QML Language Server from latest Qt version")); useLatestQmlls->setChecked(s.qmllsSettings().useLatestQmlls); useLatestQmlls->setEnabled(s.qmllsSettings().useQmlls); QObject::connect(useQmlls, &QCheckBox::stateChanged, this, [this](int checked) { useLatestQmlls->setEnabled(checked != Qt::Unchecked); + disableBuiltInCodemodel->setEnabled(checked != Qt::Unchecked); }); useCustomAnalyzer = new QCheckBox(Tr::tr("Use customized static analyzer")); @@ -454,8 +464,8 @@ public: }, }, Group{ - title(Tr::tr("Language Server")), - Column{useQmlls, useLatestQmlls}, + title(Tr::tr("QML Language Server")), + Column{useQmlls, disableBuiltInCodemodel , useLatestQmlls}, }, Group { title(Tr::tr("Static Analyzer")), @@ -499,6 +509,7 @@ public: s.setFoldAuxData(foldAuxData->isChecked()); s.setUiQmlOpenMode(uiQmlOpenComboBox->currentData().toString()); s.qmllsSettings().useQmlls = useQmlls->isChecked(); + s.qmllsSettings().disableBuiltinCodemodel = disableBuiltInCodemodel->isChecked(); s.qmllsSettings().useLatestQmlls = useLatestQmlls->isChecked(); s.setUseCustomAnalyzer(useCustomAnalyzer->isChecked()); QSet disabled; @@ -557,6 +568,7 @@ private: QCheckBox *foldAuxData; QCheckBox *useQmlls; QCheckBox *useLatestQmlls; + QCheckBox *disableBuiltInCodemodel; QComboBox *uiQmlOpenComboBox; QCheckBox *useCustomAnalyzer; QTreeView *analyzerMessagesView; diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 04c94d628a4..1e0cc5d29ae 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -60,6 +60,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -855,14 +859,39 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, processLinkCallback(Utils::Link()); } +static LanguageClient::Client *getQmllsClient(const Utils::FilePath &fileName) +{ + // the value in disableBuiltinCodemodel is only valid when useQmlls is enabled + if (QmlJsEditingSettings::get().qmllsSettings().useQmlls + && !QmlJsEditingSettings::get().qmllsSettings().disableBuiltinCodemodel) + return nullptr; + + auto client = LanguageClient::LanguageClientManager::clientForFilePath(fileName); + return client; +} + void QmlJSEditorWidget::findUsages() { - m_findReferences->findUsages(textDocument()->filePath(), textCursor().position()); + const Utils::FilePath fileName = textDocument()->filePath(); + + if (auto client = getQmllsClient(fileName)) { + client->symbolSupport().findUsages(textDocument(), textCursor()); + } else { + const int offset = textCursor().position(); + m_findReferences->findUsages(fileName, offset); + } } void QmlJSEditorWidget::renameSymbolUnderCursor() { - m_findReferences->renameUsages(textDocument()->filePath(), textCursor().position()); + const Utils::FilePath fileName = textDocument()->filePath(); + + if (auto client = getQmllsClient(fileName)) { + client->symbolSupport().renameSymbol(textDocument(), textCursor(), QString()); + } else { + const int offset = textCursor().position(); + m_findReferences->renameUsages(fileName, offset); + } } void QmlJSEditorWidget::showContextPane() diff --git a/src/plugins/qmljseditor/qmllssettings.h b/src/plugins/qmljseditor/qmllssettings.h index 040f64d4334..32890d3762a 100644 --- a/src/plugins/qmljseditor/qmllssettings.h +++ b/src/plugins/qmljseditor/qmllssettings.h @@ -15,10 +15,12 @@ struct QmllsSettings { bool useQmlls = true; bool useLatestQmlls = false; + bool disableBuiltinCodemodel = false; friend bool operator==(const QmllsSettings &s1, const QmllsSettings &s2) { - return s1.useQmlls == s2.useQmlls && s1.useLatestQmlls == s2.useLatestQmlls; + return s1.useQmlls == s2.useQmlls && s1.useLatestQmlls == s2.useLatestQmlls + && s1.disableBuiltinCodemodel == s2.disableBuiltinCodemodel; } friend bool operator!=(const QmllsSettings &s1, const QmllsSettings &s2) { return !(s1 == s2); } };