diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 194a372c386..83b67eadbce 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -284,6 +284,13 @@ void LanguageClientManager::registerClientSettings(BaseSettings *settings) managerInstance->applySettings(); } +void LanguageClientManager::enableClientSettings(const QString &settingsId) +{ + QTC_ASSERT(managerInstance, return); + LanguageClientSettings::enableSettings(settingsId); + managerInstance->applySettings(); +} + QVector LanguageClientManager::clientForSetting(const BaseSettings *setting) { QTC_ASSERT(managerInstance, return {}); diff --git a/src/plugins/languageclient/languageclientmanager.h b/src/plugins/languageclient/languageclientmanager.h index 6aba7594b5e..84bdf63d133 100644 --- a/src/plugins/languageclient/languageclientmanager.h +++ b/src/plugins/languageclient/languageclientmanager.h @@ -76,6 +76,7 @@ public: static void applySettings(); static QList currentSettings(); static void registerClientSettings(BaseSettings *settings); + static void enableClientSettings(const QString &settingsId); static QVector clientForSetting(const BaseSettings *setting); static const BaseSettings *settingForClient(Client *setting); static Client *clientForDocument(TextEditor::TextDocument *document); diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index a8714fc2b83..a08e52208fc 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -101,6 +101,7 @@ public: void reset(const QList &settings); QList settings() const { return m_settings; } void insertSettings(BaseSettings *settings); + void enableSetting(const QString &id); QList removed() const { return m_removed; } BaseSettings *settingForIndex(const QModelIndex &index) const; QModelIndex indexForSetting(BaseSettings *setting) const; @@ -148,6 +149,7 @@ public: QList settings() const; void addSettings(BaseSettings *settings); + void enableSettings(const QString &id); private: LanguageClientSettingsModel m_model; @@ -311,6 +313,11 @@ void LanguageClientSettingsPage::addSettings(BaseSettings *settings) m_model.insertSettings(settings); } +void LanguageClientSettingsPage::enableSettings(const QString &id) +{ + m_model.enableSetting(id); +} + LanguageClientSettingsModel::~LanguageClientSettingsModel() { qDeleteAll(m_settings); @@ -435,6 +442,17 @@ void LanguageClientSettingsModel::insertSettings(BaseSettings *settings) endInsertRows(); } +void LanguageClientSettingsModel::enableSetting(const QString &id) +{ + BaseSettings *setting = Utils::findOrDefault(m_settings, Utils::equal(&BaseSettings::m_id, id)); + if (!setting) + return; + setting->m_enabled = true; + const QModelIndex &index = indexForSetting(setting); + if (index.isValid()) + emit dataChanged(index, index, {Qt::CheckStateRole}); +} + BaseSettings *LanguageClientSettingsModel::settingForIndex(const QModelIndex &index) const { if (!index.isValid() || index.row() >= m_settings.size()) @@ -548,6 +566,11 @@ void LanguageClientSettings::addSettings(BaseSettings *settings) settingsPage().addSettings(settings); } +void LanguageClientSettings::enableSettings(const QString &id) +{ + settingsPage().enableSettings(id); +} + void LanguageClientSettings::toSettings(QSettings *settings, const QList &languageClientSettings) { diff --git a/src/plugins/languageclient/languageclientsettings.h b/src/plugins/languageclient/languageclientsettings.h index 40b273e7357..579a2e36e93 100644 --- a/src/plugins/languageclient/languageclientsettings.h +++ b/src/plugins/languageclient/languageclientsettings.h @@ -139,6 +139,7 @@ public: static QList fromSettings(QSettings *settings); static QList currentPageSettings(); static void addSettings(BaseSettings *settings); + static void enableSettings(const QString &id); static void toSettings(QSettings *settings, const QList &languageClientSettings); }; diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp index 29fc14953b0..acb78ef4c3d 100644 --- a/src/plugins/python/pythonutils.cpp +++ b/src/plugins/python/pythonutils.cpp @@ -41,6 +41,7 @@ #include +#include #include #include @@ -55,12 +56,19 @@ namespace Internal { static constexpr char startPylsInfoBarId[] = "Python::StartPyls"; static constexpr char installPylsInfoBarId[] = "Python::InstallPyls"; +static constexpr char enablePylsInfoBarId[] = "Python::EnablePyls"; static constexpr char installPylsTaskId[] = "Python::InstallPylsTask"; static constexpr char pythonUtilsTrContext[] = "Python::Utils"; struct PythonLanguageServerState { - enum { CanNotBeInstalled, CanBeInstalled, AlreadyInstalled, AlreadyConfigured } state; + enum { + CanNotBeInstalled, + CanBeInstalled, + AlreadyInstalled, + AlreadyConfigured, + ConfiguredButDisabled + } state; FilePath pylsModulePath; }; @@ -130,8 +138,11 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho if (response.allOutput().contains("Python Language Server")) { const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand); for (const StdIOSettings *serverSetting : configuredPythonLanguageServer()) { - if (modulePath == getPylsModulePath(serverSetting->command())) - return {PythonLanguageServerState::AlreadyConfigured, FilePath()}; + if (modulePath == getPylsModulePath(serverSetting->command())) { + return {serverSetting->m_enabled ? PythonLanguageServerState::AlreadyConfigured + : PythonLanguageServerState::ConfiguredButDisabled, + FilePath()}; + } } return {PythonLanguageServerState::AlreadyInstalled, getPylsModulePath(pythonLShelpCommand)}; @@ -299,6 +310,20 @@ static void setupPythonLanguageServer(const FilePath &python, LanguageClient::LanguageClientManager::reOpenDocumentWithClient(document, client); } +static void enablePythonLanguageServer(const FilePath &python, + QPointer document) +{ + using namespace LanguageClient; + document->infoBar()->removeInfo(enablePylsInfoBarId); + if (const StdIOSettings *setting = languageServerForPython(python)) { + LanguageClientManager::enableClientSettings(setting->m_id); + if (const StdIOSettings *setting = languageServerForPython(python)) { + if (Client *client = LanguageClientManager::clientForSetting(setting).value(0)) + LanguageClientManager::reOpenDocumentWithClient(document, client); + } + } +} + void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *document) { const PythonLanguageServerState &lsState = checkPythonLanguageServer(python); @@ -308,9 +333,8 @@ void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *docum return; } + resetEditorInfoBar(document); Core::InfoBar *infoBar = document->infoBar(); - infoBar->removeInfo(installPylsInfoBarId); - infoBar->removeInfo(startPylsInfoBarId); if (lsState.state == PythonLanguageServerState::CanBeInstalled && infoBar->canInfoBeAdded(installPylsInfoBarId)) { auto message @@ -336,6 +360,17 @@ void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *docum info.setCustomButtonInfo(QCoreApplication::translate(pythonUtilsTrContext, "Setup"), [=]() { setupPythonLanguageServer(python, document); }); infoBar->addInfo(info); + } else if (lsState.state == PythonLanguageServerState::ConfiguredButDisabled + && infoBar->canInfoBeAdded(enablePylsInfoBarId)) { + auto message = QCoreApplication::translate(pythonUtilsTrContext, + "Enable Python language server for %1 (%2)?") + .arg(pythonName(python), python.toUserOutput()); + Core::InfoBarEntry info(enablePylsInfoBarId, + message, + Core::InfoBarEntry::GlobalSuppression::Enabled); + info.setCustomButtonInfo(QCoreApplication::translate(pythonUtilsTrContext, "Enable"), + [=]() { enablePythonLanguageServer(python, document); }); + infoBar->addInfo(info); } } @@ -344,6 +379,7 @@ void resetEditorInfoBar(TextEditor::TextDocument *document) Core::InfoBar *infoBar = document->infoBar(); infoBar->removeInfo(installPylsInfoBarId); infoBar->removeInfo(startPylsInfoBarId); + infoBar->removeInfo(enablePylsInfoBarId); } } // namespace Internal