summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/python/pythonconstants.h2
-rw-r--r--src/plugins/python/pythonlanguageclient.cpp145
-rw-r--r--src/plugins/python/pythonlanguageclient.h31
-rw-r--r--src/plugins/python/pythonplugin.cpp7
4 files changed, 176 insertions, 9 deletions
diff --git a/src/plugins/python/pythonconstants.h b/src/plugins/python/pythonconstants.h
index eb01dc5fab..8d392acd20 100644
--- a/src/plugins/python/pythonconstants.h
+++ b/src/plugins/python/pythonconstants.h
@@ -41,6 +41,8 @@ const char PYTHON_OPEN_REPL[] = "Python.OpenRepl";
const char PYTHON_OPEN_REPL_IMPORT[] = "Python.OpenReplImport";
const char PYTHON_OPEN_REPL_IMPORT_TOPLEVEL[] = "Python.OpenReplImportToplevel";
+const char PYLS_SETTINGS_ID[] = "Python.PyLSSettingsID";
+
/*******************************************************************************
* MIME type
******************************************************************************/
diff --git a/src/plugins/python/pythonlanguageclient.cpp b/src/plugins/python/pythonlanguageclient.cpp
index ec82520f22..86906317ea 100644
--- a/src/plugins/python/pythonlanguageclient.cpp
+++ b/src/plugins/python/pythonlanguageclient.cpp
@@ -27,6 +27,7 @@
#include "pythonconstants.h"
#include "pythonplugin.h"
+#include "pythonsettings.h"
#include "pythonutils.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -39,8 +40,11 @@
#include <utils/infobar.h>
#include <utils/qtcprocess.h>
#include <utils/runextensions.h>
+#include <utils/variablechooser.h>
+#include <QComboBox>
#include <QFutureWatcher>
+#include <QGridLayout>
#include <QRegularExpression>
#include <QTimer>
@@ -163,6 +167,129 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho
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))
+ {
+ 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);
+
+ connect(PythonSettings::instance(),
+ &PythonSettings::interpretersChanged,
+ this,
+ &PyLSSettingsWidget::updateInterpreters);
+ }
+
+ 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:
+ QLineEdit *m_name = nullptr;
+ QComboBox *m_interpreter = 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);
+ 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);
+ 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;
+}
+
+Client *PyLSSettings::createClient(BaseClientInterface *interface) const
+{
+ return new Client(interface);
+}
+
PyLSConfigureAssistant *PyLSConfigureAssistant::instance()
{
static auto *instance = new PyLSConfigureAssistant(PythonPlugin::instance());
@@ -180,12 +307,22 @@ const StdIOSettings *PyLSConfigureAssistant::languageServerForPython(const FileP
static Client *registerLanguageServer(const FilePath &python)
{
- auto *settings = new StdIOSettings();
- settings->m_executable = python;
- settings->m_arguments = "-m pylsp";
+ 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);
+ }
settings->m_name = PyLSConfigureAssistant::tr("Python Language Server (%1)")
.arg(pythonName(python));
- settings->m_languageFilter.mimeTypes = QStringList(Constants::C_PY_MIMETYPE);
LanguageClientManager::registerClientSettings(settings);
Client *client = LanguageClientManager::clientForSetting(settings).value(0);
PyLSConfigureAssistant::updateEditorInfoBars(python, client);
diff --git a/src/plugins/python/pythonlanguageclient.h b/src/plugins/python/pythonlanguageclient.h
index 30bc834a51..67e0e5f104 100644
--- a/src/plugins/python/pythonlanguageclient.h
+++ b/src/plugins/python/pythonlanguageclient.h
@@ -27,18 +27,41 @@
#include <utils/fileutils.h>
+#include <languageclient/client.h>
+#include <languageclient/languageclientsettings.h>
+
namespace Core { class IDocument; }
-namespace LanguageClient {
-class Client;
-class StdIOSettings;
-}
+namespace LanguageClient { class Client; }
namespace TextEditor { class TextDocument; }
namespace Python {
namespace Internal {
+class Interpreter;
struct PythonLanguageServerState;
+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:
+ QString m_interpreterId;
+
+ PyLSSettings(const PyLSSettings &other) = default;
+};
+
class PyLSConfigureAssistant : public QObject
{
Q_OBJECT
diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp
index dc89abf2b0..15b656b2e4 100644
--- a/src/plugins/python/pythonplugin.cpp
+++ b/src/plugins/python/pythonplugin.cpp
@@ -25,6 +25,7 @@
#include "pythonplugin.h"
+#include "pythonconstants.h"
#include "pythoneditor.h"
#include "pythonlanguageclient.h"
#include "pythonproject.h"
@@ -71,6 +72,10 @@ public:
PythonPlugin::PythonPlugin()
{
m_instance = this;
+
+ LanguageClient::LanguageClientSettings::registerClientType({Constants::PYLS_SETTINGS_ID,
+ tr("Python Language Server"),
+ []() { return new PyLSSettings; }});
}
PythonPlugin::~PythonPlugin()
@@ -102,7 +107,7 @@ void PythonPlugin::extensionsInitialized()
{
// Add MIME overlay icons (these icons displayed at Project dock panel)
QString imageFile = Utils::creatorTheme()->imageFile(Utils::Theme::IconOverlayPro,
- Constants::FILEOVERLAY_PY);
+ ::Constants::FILEOVERLAY_PY);
Core::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
TaskHub::addCategory(PythonErrorTaskCategory, "Python", true);