diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/python/pythonconstants.h | 2 | ||||
-rw-r--r-- | src/plugins/python/pythonlanguageclient.cpp | 145 | ||||
-rw-r--r-- | src/plugins/python/pythonlanguageclient.h | 31 | ||||
-rw-r--r-- | src/plugins/python/pythonplugin.cpp | 7 |
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); |