Python: Add info bar entry to enable pyls

Show an editor info bar entry displaying that the language server for
the current python is disabled and a button to quickly enable the pyls.

Change-Id: I3adb2e7cbfb1a32e35413b0b06dfbe66a0b214af
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2019-10-17 10:03:57 +02:00
parent c8ccfea225
commit 28c3f0c31e
5 changed files with 73 additions and 5 deletions

View File

@@ -284,6 +284,13 @@ void LanguageClientManager::registerClientSettings(BaseSettings *settings)
managerInstance->applySettings(); managerInstance->applySettings();
} }
void LanguageClientManager::enableClientSettings(const QString &settingsId)
{
QTC_ASSERT(managerInstance, return);
LanguageClientSettings::enableSettings(settingsId);
managerInstance->applySettings();
}
QVector<Client *> LanguageClientManager::clientForSetting(const BaseSettings *setting) QVector<Client *> LanguageClientManager::clientForSetting(const BaseSettings *setting)
{ {
QTC_ASSERT(managerInstance, return {}); QTC_ASSERT(managerInstance, return {});

View File

@@ -76,6 +76,7 @@ public:
static void applySettings(); static void applySettings();
static QList<BaseSettings *> currentSettings(); static QList<BaseSettings *> currentSettings();
static void registerClientSettings(BaseSettings *settings); static void registerClientSettings(BaseSettings *settings);
static void enableClientSettings(const QString &settingsId);
static QVector<Client *> clientForSetting(const BaseSettings *setting); static QVector<Client *> clientForSetting(const BaseSettings *setting);
static const BaseSettings *settingForClient(Client *setting); static const BaseSettings *settingForClient(Client *setting);
static Client *clientForDocument(TextEditor::TextDocument *document); static Client *clientForDocument(TextEditor::TextDocument *document);

View File

@@ -101,6 +101,7 @@ public:
void reset(const QList<BaseSettings *> &settings); void reset(const QList<BaseSettings *> &settings);
QList<BaseSettings *> settings() const { return m_settings; } QList<BaseSettings *> settings() const { return m_settings; }
void insertSettings(BaseSettings *settings); void insertSettings(BaseSettings *settings);
void enableSetting(const QString &id);
QList<BaseSettings *> removed() const { return m_removed; } QList<BaseSettings *> removed() const { return m_removed; }
BaseSettings *settingForIndex(const QModelIndex &index) const; BaseSettings *settingForIndex(const QModelIndex &index) const;
QModelIndex indexForSetting(BaseSettings *setting) const; QModelIndex indexForSetting(BaseSettings *setting) const;
@@ -148,6 +149,7 @@ public:
QList<BaseSettings *> settings() const; QList<BaseSettings *> settings() const;
void addSettings(BaseSettings *settings); void addSettings(BaseSettings *settings);
void enableSettings(const QString &id);
private: private:
LanguageClientSettingsModel m_model; LanguageClientSettingsModel m_model;
@@ -311,6 +313,11 @@ void LanguageClientSettingsPage::addSettings(BaseSettings *settings)
m_model.insertSettings(settings); m_model.insertSettings(settings);
} }
void LanguageClientSettingsPage::enableSettings(const QString &id)
{
m_model.enableSetting(id);
}
LanguageClientSettingsModel::~LanguageClientSettingsModel() LanguageClientSettingsModel::~LanguageClientSettingsModel()
{ {
qDeleteAll(m_settings); qDeleteAll(m_settings);
@@ -435,6 +442,17 @@ void LanguageClientSettingsModel::insertSettings(BaseSettings *settings)
endInsertRows(); 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 BaseSettings *LanguageClientSettingsModel::settingForIndex(const QModelIndex &index) const
{ {
if (!index.isValid() || index.row() >= m_settings.size()) if (!index.isValid() || index.row() >= m_settings.size())
@@ -548,6 +566,11 @@ void LanguageClientSettings::addSettings(BaseSettings *settings)
settingsPage().addSettings(settings); settingsPage().addSettings(settings);
} }
void LanguageClientSettings::enableSettings(const QString &id)
{
settingsPage().enableSettings(id);
}
void LanguageClientSettings::toSettings(QSettings *settings, void LanguageClientSettings::toSettings(QSettings *settings,
const QList<BaseSettings *> &languageClientSettings) const QList<BaseSettings *> &languageClientSettings)
{ {

View File

@@ -139,6 +139,7 @@ public:
static QList<BaseSettings *> fromSettings(QSettings *settings); static QList<BaseSettings *> fromSettings(QSettings *settings);
static QList<BaseSettings *> currentPageSettings(); static QList<BaseSettings *> currentPageSettings();
static void addSettings(BaseSettings *settings); static void addSettings(BaseSettings *settings);
static void enableSettings(const QString &id);
static void toSettings(QSettings *settings, const QList<BaseSettings *> &languageClientSettings); static void toSettings(QSettings *settings, const QList<BaseSettings *> &languageClientSettings);
}; };

View File

@@ -41,6 +41,7 @@
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <utils/qtcassert.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QDir> #include <QDir>
@@ -55,12 +56,19 @@ namespace Internal {
static constexpr char startPylsInfoBarId[] = "Python::StartPyls"; static constexpr char startPylsInfoBarId[] = "Python::StartPyls";
static constexpr char installPylsInfoBarId[] = "Python::InstallPyls"; static constexpr char installPylsInfoBarId[] = "Python::InstallPyls";
static constexpr char enablePylsInfoBarId[] = "Python::EnablePyls";
static constexpr char installPylsTaskId[] = "Python::InstallPylsTask"; static constexpr char installPylsTaskId[] = "Python::InstallPylsTask";
static constexpr char pythonUtilsTrContext[] = "Python::Utils"; static constexpr char pythonUtilsTrContext[] = "Python::Utils";
struct PythonLanguageServerState struct PythonLanguageServerState
{ {
enum { CanNotBeInstalled, CanBeInstalled, AlreadyInstalled, AlreadyConfigured } state; enum {
CanNotBeInstalled,
CanBeInstalled,
AlreadyInstalled,
AlreadyConfigured,
ConfiguredButDisabled
} state;
FilePath pylsModulePath; FilePath pylsModulePath;
}; };
@@ -130,8 +138,11 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho
if (response.allOutput().contains("Python Language Server")) { if (response.allOutput().contains("Python Language Server")) {
const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand); const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand);
for (const StdIOSettings *serverSetting : configuredPythonLanguageServer()) { for (const StdIOSettings *serverSetting : configuredPythonLanguageServer()) {
if (modulePath == getPylsModulePath(serverSetting->command())) if (modulePath == getPylsModulePath(serverSetting->command())) {
return {PythonLanguageServerState::AlreadyConfigured, FilePath()}; return {serverSetting->m_enabled ? PythonLanguageServerState::AlreadyConfigured
: PythonLanguageServerState::ConfiguredButDisabled,
FilePath()};
}
} }
return {PythonLanguageServerState::AlreadyInstalled, getPylsModulePath(pythonLShelpCommand)}; return {PythonLanguageServerState::AlreadyInstalled, getPylsModulePath(pythonLShelpCommand)};
@@ -299,6 +310,20 @@ static void setupPythonLanguageServer(const FilePath &python,
LanguageClient::LanguageClientManager::reOpenDocumentWithClient(document, client); LanguageClient::LanguageClientManager::reOpenDocumentWithClient(document, client);
} }
static void enablePythonLanguageServer(const FilePath &python,
QPointer<TextEditor::TextDocument> 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) void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *document)
{ {
const PythonLanguageServerState &lsState = checkPythonLanguageServer(python); const PythonLanguageServerState &lsState = checkPythonLanguageServer(python);
@@ -308,9 +333,8 @@ void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *docum
return; return;
} }
resetEditorInfoBar(document);
Core::InfoBar *infoBar = document->infoBar(); Core::InfoBar *infoBar = document->infoBar();
infoBar->removeInfo(installPylsInfoBarId);
infoBar->removeInfo(startPylsInfoBarId);
if (lsState.state == PythonLanguageServerState::CanBeInstalled if (lsState.state == PythonLanguageServerState::CanBeInstalled
&& infoBar->canInfoBeAdded(installPylsInfoBarId)) { && infoBar->canInfoBeAdded(installPylsInfoBarId)) {
auto message auto message
@@ -336,6 +360,17 @@ void updateEditorInfoBar(const FilePath &python, TextEditor::TextDocument *docum
info.setCustomButtonInfo(QCoreApplication::translate(pythonUtilsTrContext, "Setup"), info.setCustomButtonInfo(QCoreApplication::translate(pythonUtilsTrContext, "Setup"),
[=]() { setupPythonLanguageServer(python, document); }); [=]() { setupPythonLanguageServer(python, document); });
infoBar->addInfo(info); 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(); Core::InfoBar *infoBar = document->infoBar();
infoBar->removeInfo(installPylsInfoBarId); infoBar->removeInfo(installPylsInfoBarId);
infoBar->removeInfo(startPylsInfoBarId); infoBar->removeInfo(startPylsInfoBarId);
infoBar->removeInfo(enablePylsInfoBarId);
} }
} // namespace Internal } // namespace Internal