Python: remove python specific language client settings

Change-Id: Ic993d525f29c1925f7e64dfc6f5e053234fb4904
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2022-06-09 13:41:41 +02:00
parent ed22ef7854
commit 4c20a880e6
6 changed files with 122 additions and 310 deletions

View File

@@ -108,7 +108,19 @@ static QWidget *createEditorWidget()
class PythonDocument : public TextEditor::TextDocument class PythonDocument : public TextEditor::TextDocument
{ {
public: public:
PythonDocument() : TextEditor::TextDocument(Constants::C_PYTHONEDITOR_ID) {} PythonDocument() : TextEditor::TextDocument(Constants::C_PYTHONEDITOR_ID)
{
connect(PythonSettings::instance(),
&PythonSettings::pylsEnabledChanged,
this,
[this](const bool enabled) {
if (!enabled)
return;
const Utils::FilePath &python = detectPython(filePath());
if (python.exists())
PyLSConfigureAssistant::openDocumentWithPython(python, this);
});
}
void setFilePath(const Utils::FilePath &filePath) override void setFilePath(const Utils::FilePath &filePath) override
{ {

View File

@@ -69,9 +69,7 @@ using namespace Utils;
namespace Python { namespace Python {
namespace Internal { namespace Internal {
static constexpr char startPylsInfoBarId[] = "Python::StartPyls";
static constexpr char installPylsInfoBarId[] = "Python::InstallPyls"; static constexpr char installPylsInfoBarId[] = "Python::InstallPyls";
static constexpr char enablePylsInfoBarId[] = "Python::EnablePyls";
class PythonLanguageServerState class PythonLanguageServerState
{ {
@@ -79,13 +77,17 @@ public:
enum { enum {
CanNotBeInstalled, CanNotBeInstalled,
CanBeInstalled, CanBeInstalled,
AlreadyInstalled, AlreadyInstalled
AlreadyConfigured,
ConfiguredButDisabled
} state; } state;
FilePath pylsModulePath; FilePath pylsModulePath;
}; };
static QHash<FilePath, PyLSClient*> &pythonClients()
{
static QHash<FilePath, PyLSClient*> clients;
return clients;
}
FilePath getPylsModulePath(CommandLine pylsCommand) FilePath getPylsModulePath(CommandLine pylsCommand)
{ {
static QMutex mutex; // protect the access to the cache static QMutex mutex; // protect the access to the cache
@@ -125,29 +127,11 @@ FilePath getPylsModulePath(CommandLine pylsCommand)
return {}; return {};
} }
QList<const StdIOSettings *> configuredPythonLanguageServer()
{
using namespace LanguageClient;
QList<const StdIOSettings *> result;
for (const BaseSettings *setting : LanguageClientManager::currentSettings()) {
if (setting->m_languageFilter.isSupported("foo.py", Constants::C_PY_MIMETYPE))
result << dynamic_cast<const StdIOSettings *>(setting);
}
return result;
}
static PythonLanguageServerState checkPythonLanguageServer(const FilePath &python) static PythonLanguageServerState checkPythonLanguageServer(const FilePath &python)
{ {
using namespace LanguageClient; using namespace LanguageClient;
const CommandLine pythonLShelpCommand(python, {"-m", "pylsp", "-h"}); const CommandLine pythonLShelpCommand(python, {"-m", "pylsp", "-h"});
const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand); const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand);
for (const StdIOSettings *serverSetting : configuredPythonLanguageServer()) {
if (modulePath == getPylsModulePath(serverSetting->command())) {
return {serverSetting->m_enabled ? PythonLanguageServerState::AlreadyConfigured
: PythonLanguageServerState::ConfiguredButDisabled,
FilePath()};
}
}
QtcProcess pythonProcess; QtcProcess pythonProcess;
pythonProcess.setCommand(pythonLShelpCommand); pythonProcess.setCommand(pythonLShelpCommand);
@@ -163,137 +147,6 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho
return {PythonLanguageServerState::CanNotBeInstalled, FilePath()}; return {PythonLanguageServerState::CanNotBeInstalled, FilePath()};
} }
class PyLSSettingsWidget : public QWidget
{
Q_DECLARE_TR_FUNCTIONS(PyLSSettingsWidget)
public:
PyLSSettingsWidget(const PyLSSettings *settings, QWidget *parent)
: QWidget(parent)
, m_name(new QLineEdit(settings->m_name, this))
, m_interpreter(new QComboBox(this))
, m_configure(new QPushButton(tr("Configure..."), this))
{
int row = 0;
auto *mainLayout = new QGridLayout;
mainLayout->addWidget(new QLabel(tr("Name:")), row, 0);
mainLayout->addWidget(m_name, row, 1);
auto chooser = new VariableChooser(this);
chooser->addSupportedWidget(m_name);
mainLayout->addWidget(new QLabel(tr("Python:")), ++row, 0);
QString settingsId = settings->interpreterId();
if (settingsId.isEmpty())
settingsId = PythonSettings::defaultInterpreter().id;
updateInterpreters(PythonSettings::interpreters(), settingsId);
mainLayout->addWidget(m_interpreter, row, 1);
setLayout(mainLayout);
mainLayout->addWidget(m_configure, ++row, 0);
connect(PythonSettings::instance(),
&PythonSettings::interpretersChanged,
this,
&PyLSSettingsWidget::updateInterpreters);
connect(m_configure, &QPushButton::clicked, this, &PyLSSettingsWidget::switchToPylsConfigurePage);
}
void updateInterpreters(const QList<Interpreter> &interpreters, const QString &defaultId)
{
QString currentId = interpreterId();
if (currentId.isEmpty())
currentId = defaultId;
m_interpreter->clear();
for (const Interpreter &interpreter : interpreters) {
if (!interpreter.command.exists())
continue;
const QString name = QString(interpreter.name + " (%1)")
.arg(interpreter.command.toUserOutput());
m_interpreter->addItem(name, interpreter.id);
if (!currentId.isEmpty() && currentId == interpreter.id)
m_interpreter->setCurrentIndex(m_interpreter->count() - 1);
}
}
QString name() const { return m_name->text(); }
QString interpreterId() const { return m_interpreter->currentData().toString(); }
private:
void switchToPylsConfigurePage()
{
Core::ICore::showOptionsDialog(Constants::C_PYLSCONFIGURATION_PAGE_ID);
}
QLineEdit *m_name = nullptr;
QComboBox *m_interpreter = nullptr;
QPushButton *m_configure = nullptr;
};
PyLSSettings::PyLSSettings()
{
m_settingsTypeId = Constants::PYLS_SETTINGS_ID;
m_name = "Python Language Server";
m_startBehavior = RequiresFile;
m_languageFilter.mimeTypes = QStringList()
<< Constants::C_PY_MIMETYPE << Constants::C_PY3_MIMETYPE;
m_arguments = "-m pylsp";
}
bool PyLSSettings::isValid() const
{
return !m_interpreterId.isEmpty() && StdIOSettings::isValid();
}
static const char interpreterKey[] = "interpreter";
QVariantMap PyLSSettings::toMap() const
{
QVariantMap map = StdIOSettings::toMap();
map.insert(interpreterKey, m_interpreterId);
return map;
}
void PyLSSettings::fromMap(const QVariantMap &map)
{
StdIOSettings::fromMap(map);
m_languageFilter.mimeTypes = QStringList()
<< Constants::C_PY_MIMETYPE << Constants::C_PY3_MIMETYPE;
setInterpreter(map[interpreterKey].toString());
}
bool PyLSSettings::applyFromSettingsWidget(QWidget *widget)
{
bool changed = false;
auto pylswidget = static_cast<PyLSSettingsWidget *>(widget);
changed |= m_name != pylswidget->name();
m_name = pylswidget->name();
changed |= m_interpreterId != pylswidget->interpreterId();
setInterpreter(pylswidget->interpreterId());
return changed;
}
QWidget *PyLSSettings::createSettingsWidget(QWidget *parent) const
{
return new PyLSSettingsWidget(this, parent);
}
BaseSettings *PyLSSettings::copy() const
{
return new PyLSSettings(*this);
}
void PyLSSettings::setInterpreter(const QString &interpreterId)
{
m_interpreterId = interpreterId;
if (m_interpreterId.isEmpty())
return;
Interpreter interpreter = Utils::findOrDefault(PythonSettings::interpreters(),
Utils::equal(&Interpreter::id, interpreterId));
m_executable = interpreter.command;
}
class PyLSInterface : public StdIOClientInterface class PyLSInterface : public StdIOClientInterface
{ {
@@ -310,13 +163,22 @@ public:
TemporaryDirectory m_extraPythonPath; TemporaryDirectory m_extraPythonPath;
}; };
BaseClientInterface *PyLSSettings::createInterface(ProjectExplorer::Project *project) const PyLSClient *clientForPython(const FilePath &python)
{ {
if (auto client = pythonClients()[python])
return client;
auto interface = new PyLSInterface; auto interface = new PyLSInterface;
interface->setCommandLine(command()); interface->setCommandLine(CommandLine(python, {"-m", "pylsp"}));
if (project) auto client = new PyLSClient(interface);
interface->setWorkingDirectory(project->projectDirectory()); client->setName(PyLSClient::tr("Python Language Server (%1)").arg(python.toUserOutput()));
return interface; client->setActivateDocumentAutomatically(true);
client->updateConfiguration();
LanguageFilter filter;
filter.mimeTypes = QStringList() << Constants::C_PY_MIMETYPE << Constants::C_PY3_MIMETYPE;
client->setSupportedLanguage(filter);
client->start();
pythonClients()[python] = client;
return client;
} }
PyLSClient::PyLSClient(BaseClientInterface *interface) PyLSClient::PyLSClient(BaseClientInterface *interface)
@@ -326,6 +188,17 @@ PyLSClient::PyLSClient(BaseClientInterface *interface)
connect(this, &Client::initialized, this, &PyLSClient::updateConfiguration); connect(this, &Client::initialized, this, &PyLSClient::updateConfiguration);
connect(PythonSettings::instance(), &PythonSettings::pylsConfigurationChanged, connect(PythonSettings::instance(), &PythonSettings::pylsConfigurationChanged,
this, &PyLSClient::updateConfiguration); this, &PyLSClient::updateConfiguration);
connect(PythonSettings::instance(), &PythonSettings::pylsEnabledChanged,
this, [this](const bool enabled){
if (!enabled)
LanguageClientManager::shutdownClient(this);
});
}
PyLSClient::~PyLSClient()
{
pythonClients().remove(pythonClients().key(this));
} }
void PyLSClient::updateConfiguration() void PyLSClient::updateConfiguration()
@@ -413,16 +286,7 @@ void PyLSClient::closeExtraCompiler(ProjectExplorer::ExtraCompiler *compiler)
PyLSClient *PyLSClient::clientForPython(const FilePath &python) PyLSClient *PyLSClient::clientForPython(const FilePath &python)
{ {
if (auto setting = PyLSConfigureAssistant::languageServerForPython(python)) { return pythonClients()[python];
if (auto client = LanguageClientManager::clientsForSetting(setting).value(0))
return qobject_cast<PyLSClient *>(client);
}
return nullptr;
}
Client *PyLSSettings::createClient(BaseClientInterface *interface) const
{
return new PyLSClient(interface);
} }
PyLSConfigureAssistant *PyLSConfigureAssistant::instance() PyLSConfigureAssistant *PyLSConfigureAssistant::instance()
@@ -431,40 +295,6 @@ PyLSConfigureAssistant *PyLSConfigureAssistant::instance()
return instance; return instance;
} }
const StdIOSettings *PyLSConfigureAssistant::languageServerForPython(const FilePath &python)
{
const FilePath pythonModulePath = getPylsModulePath({python, {"-m", "pylsp"}});
return findOrDefault(configuredPythonLanguageServer(),
[pythonModulePath](const StdIOSettings *setting) {
return getPylsModulePath(setting->command()) == pythonModulePath;
});
}
static Client *registerLanguageServer(const FilePath &python)
{
Interpreter interpreter = Utils::findOrDefault(PythonSettings::interpreters(),
Utils::equal(&Interpreter::command, python));
StdIOSettings *settings = nullptr;
if (!interpreter.id.isEmpty()) {
auto *pylsSettings = new PyLSSettings();
pylsSettings->setInterpreter(interpreter.id);
settings = pylsSettings;
} else {
// cannot find a matching interpreter in settings for the python path add a generic server
auto *settings = new StdIOSettings();
settings->m_executable = python;
settings->m_arguments = "-m pylsp";
settings->m_languageFilter.mimeTypes = QStringList() << Constants::C_PY_MIMETYPE
<< Constants::C_PY3_MIMETYPE;
}
settings->m_name = PyLSConfigureAssistant::tr("Python Language Server (%1)")
.arg(pythonName(python));
LanguageClientManager::registerClientSettings(settings);
Client *client = LanguageClientManager::clientsForSetting(settings).value(0);
PyLSConfigureAssistant::updateEditorInfoBars(python, client);
return client;
}
void PyLSConfigureAssistant::installPythonLanguageServer(const FilePath &python, void PyLSConfigureAssistant::installPythonLanguageServer(const FilePath &python,
QPointer<TextEditor::TextDocument> document) QPointer<TextEditor::TextDocument> document)
{ {
@@ -479,8 +309,8 @@ void PyLSConfigureAssistant::installPythonLanguageServer(const FilePath &python,
connect(install, &PipInstallTask::finished, this, [=](const bool success) { connect(install, &PipInstallTask::finished, this, [=](const bool success) {
if (success) { if (success) {
if (Client *client = registerLanguageServer(python)) { if (document) {
if (document) if (PyLSClient *client = clientForPython(python))
LanguageClientManager::openDocumentWithClient(document, client); LanguageClientManager::openDocumentWithClient(document, client);
} }
} }
@@ -491,34 +321,18 @@ void PyLSConfigureAssistant::installPythonLanguageServer(const FilePath &python,
install->run(); install->run();
} }
static void setupPythonLanguageServer(const FilePath &python,
QPointer<TextEditor::TextDocument> document)
{
document->infoBar()->removeInfo(startPylsInfoBarId);
if (Client *client = registerLanguageServer(python))
LanguageClientManager::openDocumentWithClient(document, client);
}
static void enablePythonLanguageServer(const FilePath &python,
QPointer<TextEditor::TextDocument> document)
{
document->infoBar()->removeInfo(enablePylsInfoBarId);
if (const StdIOSettings *setting = PyLSConfigureAssistant::languageServerForPython(python)) {
LanguageClientManager::enableClientSettings(setting->m_id);
if (const StdIOSettings *setting = PyLSConfigureAssistant::languageServerForPython(python)) {
if (Client *client = LanguageClientManager::clientsForSetting(setting).value(0)) {
LanguageClientManager::openDocumentWithClient(document, client);
PyLSConfigureAssistant::updateEditorInfoBars(python, client);
}
}
}
}
void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python, void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
TextEditor::TextDocument *document) TextEditor::TextDocument *document)
{ {
using CheckPylsWatcher = QFutureWatcher<PythonLanguageServerState>; if (!PythonSettings::pylsEnabled())
return;
if (auto client = pythonClients().value(python)) {
LanguageClientManager::openDocumentWithClient(document, client);
return;
}
using CheckPylsWatcher = QFutureWatcher<PythonLanguageServerState>;
QPointer<CheckPylsWatcher> watcher = new CheckPylsWatcher(); QPointer<CheckPylsWatcher> watcher = new CheckPylsWatcher();
// cancel and delete watcher after a 10 second timeout // cancel and delete watcher after a 10 second timeout
@@ -547,19 +361,12 @@ void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,
{ {
if (state.state == PythonLanguageServerState::CanNotBeInstalled) if (state.state == PythonLanguageServerState::CanNotBeInstalled)
return; return;
if (state.state == PythonLanguageServerState::AlreadyConfigured) {
if (const StdIOSettings *setting = languageServerForPython(python)) {
if (Client *client = LanguageClientManager::clientsForSetting(setting).value(0))
LanguageClientManager::openDocumentWithClient(document, client);
}
return;
}
resetEditorInfoBar(document); resetEditorInfoBar(document);
Utils::InfoBar *infoBar = document->infoBar(); Utils::InfoBar *infoBar = document->infoBar();
if (state.state == PythonLanguageServerState::CanBeInstalled if (state.state == PythonLanguageServerState::CanBeInstalled
&& infoBar->canInfoBeAdded(installPylsInfoBarId)) { && infoBar->canInfoBeAdded(installPylsInfoBarId)) {
auto message = tr("Install and set up Python language server (PyLS) for %1 (%2). " auto message = tr("Install Python language server (PyLS) for %1 (%2). "
"The language server provides Python specific completion and annotation.") "The language server provides Python specific completion and annotation.")
.arg(pythonName(python), python.toUserOutput()); .arg(pythonName(python), python.toUserOutput());
Utils::InfoBarEntry info(installPylsInfoBarId, Utils::InfoBarEntry info(installPylsInfoBarId,
@@ -569,27 +376,9 @@ void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,
[=]() { installPythonLanguageServer(python, document); }); [=]() { installPythonLanguageServer(python, document); });
infoBar->addInfo(info); infoBar->addInfo(info);
m_infoBarEntries[python] << document; m_infoBarEntries[python] << document;
} else if (state.state == PythonLanguageServerState::AlreadyInstalled } else if (state.state == PythonLanguageServerState::AlreadyInstalled) {
&& infoBar->canInfoBeAdded(startPylsInfoBarId)) { if (auto client = clientForPython(python))
auto message = tr("Found a Python language server for %1 (%2). " LanguageClientManager::openDocumentWithClient(document, client);
"Set it up for this document?")
.arg(pythonName(python), python.toUserOutput());
Utils::InfoBarEntry info(startPylsInfoBarId,
message,
Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.addCustomButton(tr("Set Up"), [=]() { setupPythonLanguageServer(python, document); });
infoBar->addInfo(info);
m_infoBarEntries[python] << document;
} else if (state.state == PythonLanguageServerState::ConfiguredButDisabled
&& infoBar->canInfoBeAdded(enablePylsInfoBarId)) {
auto message = tr("Enable Python language server for %1 (%2)?")
.arg(pythonName(python), python.toUserOutput());
Utils::InfoBarEntry info(enablePylsInfoBarId,
message,
Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.addCustomButton(tr("Enable"), [=]() { enablePythonLanguageServer(python, document); });
infoBar->addInfo(info);
m_infoBarEntries[python] << document;
} }
} }
@@ -606,10 +395,7 @@ void PyLSConfigureAssistant::resetEditorInfoBar(TextEditor::TextDocument *docume
{ {
for (QList<TextEditor::TextDocument *> &documents : m_infoBarEntries) for (QList<TextEditor::TextDocument *> &documents : m_infoBarEntries)
documents.removeAll(document); documents.removeAll(document);
Utils::InfoBar *infoBar = document->infoBar(); document->infoBar()->removeInfo(installPylsInfoBarId);
infoBar->removeInfo(installPylsInfoBarId);
infoBar->removeInfo(startPylsInfoBarId);
infoBar->removeInfo(enablePylsInfoBarId);
} }
PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent) PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent)

View File

@@ -46,6 +46,7 @@ class PyLSClient : public LanguageClient::Client
Q_OBJECT Q_OBJECT
public: public:
explicit PyLSClient(LanguageClient::BaseClientInterface *interface); explicit PyLSClient(LanguageClient::BaseClientInterface *interface);
~PyLSClient();
void openDocument(TextEditor::TextDocument *document) override; void openDocument(TextEditor::TextDocument *document) override;
void projectClosed(ProjectExplorer::Project *project) override; void projectClosed(ProjectExplorer::Project *project) override;
@@ -54,9 +55,9 @@ public:
const QList<PySideUicExtraCompiler *> &extraCompilers); const QList<PySideUicExtraCompiler *> &extraCompilers);
static PyLSClient *clientForPython(const Utils::FilePath &python); static PyLSClient *clientForPython(const Utils::FilePath &python);
void updateConfiguration();
private: private:
void updateConfiguration();
void updateExtraCompilerContents(ProjectExplorer::ExtraCompiler *compiler, void updateExtraCompilerContents(ProjectExplorer::ExtraCompiler *compiler,
const Utils::FilePath &file); const Utils::FilePath &file);
void closeExtraDoc(const Utils::FilePath &file); void closeExtraDoc(const Utils::FilePath &file);
@@ -68,40 +69,12 @@ private:
QHash<ProjectExplorer::Project *, QList<ProjectExplorer::ExtraCompiler *>> m_extraCompilers; QHash<ProjectExplorer::Project *, QList<ProjectExplorer::ExtraCompiler *>> m_extraCompilers;
}; };
class PyLSSettings : public LanguageClient::StdIOSettings
{
public:
PyLSSettings();
QString interpreterId() const { return m_interpreterId; }
void setInterpreter(const QString &interpreterId);
bool isValid() const final;
QVariantMap toMap() const final;
void fromMap(const QVariantMap &map) final;
bool applyFromSettingsWidget(QWidget *widget) final;
QWidget *createSettingsWidget(QWidget *parent) const final;
LanguageClient::BaseSettings *copy() const final;
LanguageClient::Client *createClient(LanguageClient::BaseClientInterface *interface) const final;
private:
LanguageClient::BaseClientInterface *createInterface(
ProjectExplorer::Project *project) const override;
QString m_interpreterId;
PyLSSettings(const PyLSSettings &other) = default;
};
class PyLSConfigureAssistant : public QObject class PyLSConfigureAssistant : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static PyLSConfigureAssistant *instance(); static PyLSConfigureAssistant *instance();
static const LanguageClient::StdIOSettings *languageServerForPython(
const Utils::FilePath &python);
static void updateEditorInfoBars(const Utils::FilePath &python, static void updateEditorInfoBars(const Utils::FilePath &python,
LanguageClient::Client *client); LanguageClient::Client *client);
static void openDocumentWithPython(const Utils::FilePath &python, static void openDocumentWithPython(const Utils::FilePath &python,

View File

@@ -75,10 +75,6 @@ public:
PythonPlugin::PythonPlugin() PythonPlugin::PythonPlugin()
{ {
m_instance = this; m_instance = this;
LanguageClient::LanguageClientSettings::registerClientType({Constants::PYLS_SETTINGS_ID,
tr("Python Language Server"),
[]() { return new PyLSSettings; }});
} }
PythonPlugin::~PythonPlugin() PythonPlugin::~PythonPlugin()

View File

@@ -397,23 +397,26 @@ public:
: m_editor(LanguageClient::jsonEditor()) : m_editor(LanguageClient::jsonEditor())
, m_advancedLabel(new QLabel) , m_advancedLabel(new QLabel)
, m_pluginsGroup(new QGroupBox(tr("Plugins:"))) , m_pluginsGroup(new QGroupBox(tr("Plugins:")))
, m_mainGroup(new QGroupBox(tr("Use Python Language Server")))
{ {
auto mainLayout = new QVBoxLayout; m_mainGroup->setCheckable(true);
auto pluginsLayout = new QGridLayout; auto mainGroupLayout = new QVBoxLayout;
auto pluginsLayout = new QVBoxLayout;
m_pluginsGroup->setLayout(pluginsLayout); m_pluginsGroup->setLayout(pluginsLayout);
int i = 0; m_pluginsGroup->setFlat(true);
for (const QString &plugin : plugins()) { for (const QString &plugin : plugins()) {
auto checkBox = new QCheckBox(plugin, this); auto checkBox = new QCheckBox(plugin, this);
connect(checkBox, &QCheckBox::clicked, this, [this, plugin, checkBox](bool enabled) { connect(checkBox, &QCheckBox::clicked, this, [this, plugin, checkBox]() {
updatePluginEnabled(checkBox->checkState(), plugin); updatePluginEnabled(checkBox->checkState(), plugin);
}); });
m_checkBoxes[plugin] = checkBox; m_checkBoxes[plugin] = checkBox;
pluginsLayout->addWidget(checkBox, i / 4, i % 4); pluginsLayout->addWidget(checkBox);
++i;
} }
mainLayout->addWidget(m_pluginsGroup);
mainGroupLayout->addWidget(m_pluginsGroup);
const QString labelText = tr( const QString labelText = tr(
"For a complete list of avilable options, consult the <a " "For a complete list of avilable options, consult the <a "
@@ -422,12 +425,12 @@ public:
m_advancedLabel->setText(labelText); m_advancedLabel->setText(labelText);
m_advancedLabel->setOpenExternalLinks(true); m_advancedLabel->setOpenExternalLinks(true);
mainLayout->addWidget(m_advancedLabel); mainGroupLayout->addWidget(m_advancedLabel);
mainLayout->addWidget(m_editor->editorWidget(), 1); mainGroupLayout->addWidget(m_editor->editorWidget(), 1);
setAdvanced(false); setAdvanced(false);
mainLayout->addStretch(); mainGroupLayout->addStretch();
auto advanced = new QCheckBox(tr("Advanced")); auto advanced = new QCheckBox(tr("Advanced"));
advanced->setChecked(false); advanced->setChecked(false);
@@ -437,18 +440,25 @@ public:
this, this,
&PyLSConfigureWidget::setAdvanced); &PyLSConfigureWidget::setAdvanced);
mainLayout->addWidget(advanced); mainGroupLayout->addWidget(advanced);
m_mainGroup->setLayout(mainGroupLayout);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(m_mainGroup);
setLayout(mainLayout); setLayout(mainLayout);
} }
void setConfiguration(const QString &configuration) void initialize(bool enabled, const QString &configuration)
{ {
m_editor->textDocument()->setPlainText(configuration); m_editor->textDocument()->setPlainText(configuration);
m_mainGroup->setChecked(enabled);
updateCheckboxes(); updateCheckboxes();
} }
void apply() void apply()
{ {
PythonSettings::setPylsEnabled(m_mainGroup->isChecked());
PythonSettings::setPyLSConfiguration(m_editor->textDocument()->plainText()); PythonSettings::setPyLSConfiguration(m_editor->textDocument()->plainText());
} }
private: private:
@@ -504,6 +514,7 @@ private:
TextEditor::BaseTextEditor *m_editor = nullptr; TextEditor::BaseTextEditor *m_editor = nullptr;
QLabel *m_advancedLabel = nullptr; QLabel *m_advancedLabel = nullptr;
QGroupBox *m_pluginsGroup = nullptr; QGroupBox *m_pluginsGroup = nullptr;
QGroupBox *m_mainGroup = nullptr;
}; };
@@ -512,6 +523,9 @@ class PyLSOptionsPage : public Core::IOptionsPage
public: public:
PyLSOptionsPage(); PyLSOptionsPage();
bool enabled() const { return m_enabled; }
void setEnabled(bool enabled);
void setConfiguration(const QString &configuration) { m_configuration = configuration; } void setConfiguration(const QString &configuration) { m_configuration = configuration; }
QString configuration() const { return m_configuration; } QString configuration() const { return m_configuration; }
@@ -521,6 +535,7 @@ public:
private: private:
QPointer<PyLSConfigureWidget> m_widget; QPointer<PyLSConfigureWidget> m_widget;
bool m_enabled = true;
QString m_configuration; QString m_configuration;
}; };
@@ -535,7 +550,7 @@ QWidget *PyLSOptionsPage::widget()
{ {
if (!m_widget) { if (!m_widget) {
m_widget = new PyLSConfigureWidget(); m_widget = new PyLSConfigureWidget();
m_widget->setConfiguration(m_configuration); m_widget->initialize(m_enabled, m_configuration);
} }
return m_widget; return m_widget;
} }
@@ -552,6 +567,11 @@ void PyLSOptionsPage::finish()
m_widget = nullptr; m_widget = nullptr;
} }
void PyLSOptionsPage::setEnabled(bool enabled)
{
m_enabled = enabled;
}
static PyLSOptionsPage &pylspOptionsPage() static PyLSOptionsPage &pylspOptionsPage()
{ {
static PyLSOptionsPage page; static PyLSOptionsPage page;
@@ -582,6 +602,7 @@ void InterpreterOptionsWidget::cleanUp()
constexpr char settingsGroupKey[] = "Python"; constexpr char settingsGroupKey[] = "Python";
constexpr char interpreterKey[] = "Interpeter"; constexpr char interpreterKey[] = "Interpeter";
constexpr char defaultKey[] = "DefaultInterpeter"; constexpr char defaultKey[] = "DefaultInterpeter";
constexpr char pylsEnabledKey[] = "PylsEnabled";
constexpr char pylsConfigurationKey[] = "PylsConfiguration"; constexpr char pylsConfigurationKey[] = "PylsConfiguration";
struct SavedSettings struct SavedSettings
@@ -589,6 +610,7 @@ struct SavedSettings
QList<Interpreter> pythons; QList<Interpreter> pythons;
QString defaultId; QString defaultId;
QString pylsConfiguration; QString pylsConfiguration;
bool pylsEnabled = true;
}; };
static QString defaultPylsConfiguration() static QString defaultPylsConfiguration()
@@ -651,6 +673,9 @@ static SavedSettings fromSettings(QSettings *settings)
result.defaultId = settings->value(defaultKey).toString(); result.defaultId = settings->value(defaultKey).toString();
QVariant pylsEnabled = settings->value(pylsEnabledKey);
if (!pylsEnabled.isNull())
result.pylsEnabled = pylsEnabled.toBool();
const QVariant pylsConfiguration = settings->value(pylsConfigurationKey); const QVariant pylsConfiguration = settings->value(pylsConfigurationKey);
if (!pylsConfiguration.isNull()) if (!pylsConfiguration.isNull())
result.pylsConfiguration = pylsConfiguration.toString(); result.pylsConfiguration = pylsConfiguration.toString();
@@ -675,6 +700,7 @@ static void toSettings(QSettings *settings, const SavedSettings &savedSettings)
settings->setValue(interpreterKey, interpretersVar); settings->setValue(interpreterKey, interpretersVar);
settings->setValue(defaultKey, savedSettings.defaultId); settings->setValue(defaultKey, savedSettings.defaultId);
settings->setValue(pylsConfigurationKey, savedSettings.pylsConfiguration); settings->setValue(pylsConfigurationKey, savedSettings.pylsConfiguration);
settings->setValue(pylsEnabledKey, savedSettings.pylsEnabled);
settings->endGroup(); settings->endGroup();
} }
@@ -773,6 +799,7 @@ void PythonSettings::init()
const SavedSettings &settings = fromSettings(Core::ICore::settings()); const SavedSettings &settings = fromSettings(Core::ICore::settings());
pylspOptionsPage().setConfiguration(settings.pylsConfiguration); pylspOptionsPage().setConfiguration(settings.pylsConfiguration);
pylspOptionsPage().setEnabled(settings.pylsEnabled);
QList<Interpreter> pythons = settings.pythons; QList<Interpreter> pythons = settings.pythons;
@@ -805,6 +832,20 @@ void PythonSettings::setPyLSConfiguration(const QString &configuration)
emit instance()->pylsConfigurationChanged(configuration); emit instance()->pylsConfigurationChanged(configuration);
} }
void PythonSettings::setPylsEnabled(const bool &enabled)
{
if (enabled == pylspOptionsPage().enabled())
return;
pylspOptionsPage().setEnabled(enabled);
saveSettings();
emit instance()->pylsEnabledChanged(enabled);
}
bool PythonSettings::pylsEnabled()
{
return pylspOptionsPage().enabled();
}
QString PythonSettings::pyLSConfiguration() QString PythonSettings::pyLSConfiguration()
{ {
return pylspOptionsPage().configuration(); return pylspOptionsPage().configuration();
@@ -866,7 +907,8 @@ void PythonSettings::saveSettings()
const QList<Interpreter> &interpreters = interpreterOptionsPage().interpreters(); const QList<Interpreter> &interpreters = interpreterOptionsPage().interpreters();
const QString defaultId = interpreterOptionsPage().defaultInterpreter().id; const QString defaultId = interpreterOptionsPage().defaultInterpreter().id;
const QString pylsConfiguration = pylspOptionsPage().configuration(); const QString pylsConfiguration = pylspOptionsPage().configuration();
toSettings(Core::ICore::settings(), {interpreters, defaultId, pylsConfiguration}); const bool pylsEnabled = pylspOptionsPage().enabled();
toSettings(Core::ICore::settings(), {interpreters, defaultId, pylsConfiguration, pylsEnabled});
if (QTC_GUARD(settingsInstance)) if (QTC_GUARD(settingsInstance))
emit settingsInstance->interpretersChanged(interpreters, defaultId); emit settingsInstance->interpretersChanged(interpreters, defaultId);
} }

View File

@@ -49,6 +49,8 @@ public:
static void setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId); static void setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId);
static void addInterpreter(const Interpreter &interpreter, bool isDefault = false); static void addInterpreter(const Interpreter &interpreter, bool isDefault = false);
static void setPyLSConfiguration(const QString &configuration); static void setPyLSConfiguration(const QString &configuration);
static bool pylsEnabled();
static void setPylsEnabled(const bool &enabled);
static QString pyLSConfiguration(); static QString pyLSConfiguration();
static PythonSettings *instance(); static PythonSettings *instance();
@@ -57,6 +59,7 @@ public:
signals: signals:
void interpretersChanged(const QList<Interpreter> &interpreters, const QString &defaultId); void interpretersChanged(const QList<Interpreter> &interpreters, const QString &defaultId);
void pylsConfigurationChanged(const QString &configuration); void pylsConfigurationChanged(const QString &configuration);
void pylsEnabledChanged(const bool enabled);
private: private:
PythonSettings(); PythonSettings();