forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.11'
Conflicts: share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp Change-Id: I8ea57eba526ab830608fd928c28771c5441749f8
This commit is contained in:
@@ -257,8 +257,10 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
|
||||
connect(PythonSettings::instance(), &PythonSettings::interpretersChanged,
|
||||
interpreterAspect, &InterpreterAspect::updateInterpreters);
|
||||
|
||||
interpreterAspect->updateInterpreters(PythonSettings::interpreters());
|
||||
interpreterAspect->setDefaultInterpreter(PythonSettings::defaultInterpreter());
|
||||
QList<Interpreter> interpreters = PythonSettings::detectPythonVenvs(project()->projectDirectory());
|
||||
aspect<InterpreterAspect>()->updateInterpreters(PythonSettings::interpreters());
|
||||
aspect<InterpreterAspect>()->setDefaultInterpreter(
|
||||
interpreters.isEmpty() ? PythonSettings::defaultInterpreter() : interpreters.first());
|
||||
|
||||
auto scriptAspect = addAspect<MainScriptAspect>();
|
||||
scriptAspect->setSettingsKey("PythonEditor.RunConfiguation.Script");
|
||||
|
||||
@@ -211,6 +211,7 @@ public:
|
||||
InterpreterOptionsPage();
|
||||
|
||||
void setInterpreter(const QList<Interpreter> &interpreters) { m_interpreters = interpreters; }
|
||||
void addInterpreter(const Interpreter &interpreter) { m_interpreters << interpreter; }
|
||||
QList<Interpreter> interpreters() const { return m_interpreters; }
|
||||
void setDefaultInterpreter(const QString &defaultId)
|
||||
{ m_defaultInterpreterId = defaultId; }
|
||||
@@ -278,6 +279,7 @@ Interpreter::Interpreter(const FilePath &python, const QString &defaultName, boo
|
||||
{
|
||||
SynchronousProcess pythonProcess;
|
||||
pythonProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
pythonProcess.setTimeoutS(1);
|
||||
SynchronousProcessResponse response = pythonProcess.runBlocking(
|
||||
CommandLine(python, {"--version"}));
|
||||
if (response.result == SynchronousProcessResponse::Finished)
|
||||
@@ -465,11 +467,21 @@ void PythonSettings::init()
|
||||
|
||||
void PythonSettings::setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId)
|
||||
{
|
||||
if (defaultId == interpreterOptionsPage().defaultInterpreter().id
|
||||
&& interpreters == interpreterOptionsPage().interpreters()) {
|
||||
return;
|
||||
}
|
||||
interpreterOptionsPage().setInterpreter(interpreters);
|
||||
interpreterOptionsPage().setDefaultInterpreter(defaultId);
|
||||
toSettings(Core::ICore::settings(), {interpreters, defaultId});
|
||||
if (QTC_GUARD(settingsInstance))
|
||||
emit settingsInstance->interpretersChanged(interpreters, defaultId);
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void PythonSettings::addInterpreter(const Interpreter &interpreter, bool isDefault)
|
||||
{
|
||||
interpreterOptionsPage().addInterpreter(interpreter);
|
||||
if (isDefault)
|
||||
interpreterOptionsPage().setDefaultInterpreter(interpreter.id);
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
PythonSettings *PythonSettings::instance()
|
||||
@@ -478,6 +490,52 @@ PythonSettings *PythonSettings::instance()
|
||||
return settingsInstance;
|
||||
}
|
||||
|
||||
QList<Interpreter> PythonSettings::detectPythonVenvs(const FilePath &path)
|
||||
{
|
||||
QList<Interpreter> result;
|
||||
QDir dir = path.toFileInfo().isDir() ? QDir(path.toString()) : path.toFileInfo().dir();
|
||||
if (dir.exists()) {
|
||||
const QString venvPython = HostOsInfo::withExecutableSuffix("python");
|
||||
const QString activatePath = HostOsInfo::isWindowsHost() ? QString{"Scripts"}
|
||||
: QString{"bin"};
|
||||
do {
|
||||
for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
|
||||
if (dir.cd(directory)) {
|
||||
if (dir.cd(activatePath)) {
|
||||
if (dir.exists("activate") && dir.exists(venvPython)) {
|
||||
FilePath python = FilePath::fromString(dir.absoluteFilePath(venvPython));
|
||||
dir.cdUp();
|
||||
const QString defaultName = QString("Python (%1 Virtual Environment)")
|
||||
.arg(dir.dirName());
|
||||
Interpreter interpreter
|
||||
= Utils::findOrDefault(PythonSettings::interpreters(),
|
||||
Utils::equal(&Interpreter::command, python));
|
||||
if (interpreter.command.isEmpty()) {
|
||||
interpreter = Interpreter(python, defaultName);
|
||||
PythonSettings::addInterpreter(interpreter);
|
||||
}
|
||||
result << interpreter;
|
||||
} else {
|
||||
dir.cdUp();
|
||||
}
|
||||
}
|
||||
dir.cdUp();
|
||||
}
|
||||
}
|
||||
} while (dir.cdUp());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PythonSettings::saveSettings()
|
||||
{
|
||||
const QList<Interpreter> &interpreters = interpreterOptionsPage().interpreters();
|
||||
const QString &defaultId = interpreterOptionsPage().defaultInterpreter().id;
|
||||
toSettings(Core::ICore::settings(), {interpreters, defaultId});
|
||||
if (QTC_GUARD(settingsInstance))
|
||||
emit settingsInstance->interpretersChanged(interpreters, defaultId);
|
||||
}
|
||||
|
||||
QList<Interpreter> PythonSettings::interpreters()
|
||||
{
|
||||
return interpreterOptionsPage().interpreters();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
@@ -43,6 +44,11 @@ public:
|
||||
const QString &name,
|
||||
const Utils::FilePath &command);
|
||||
|
||||
inline bool operator==(const Interpreter &other) const
|
||||
{
|
||||
return id == other.id && name == other.name && command == other.command;
|
||||
}
|
||||
|
||||
QString id = QUuid::createUuid().toString();
|
||||
QString name;
|
||||
Utils::FilePath command;
|
||||
@@ -57,13 +63,18 @@ public:
|
||||
static QList<Interpreter> interpreters();
|
||||
static Interpreter defaultInterpreter();
|
||||
static void setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId);
|
||||
static void addInterpreter(const Interpreter &interpreter, bool isDefault = false);
|
||||
static PythonSettings *instance();
|
||||
|
||||
static QList<Interpreter> detectPythonVenvs(const Utils::FilePath &path);
|
||||
|
||||
signals:
|
||||
void interpretersChanged(const QList<Interpreter> &interpreters, const QString &defaultId);
|
||||
|
||||
private:
|
||||
PythonSettings();
|
||||
|
||||
static void saveSettings();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -175,6 +175,11 @@ static FilePath detectPython(const FilePath &documentPath)
|
||||
}
|
||||
}
|
||||
|
||||
// check whether this file is inside a python virtual environment
|
||||
QList<Interpreter> venvInterpreters = PythonSettings::detectPythonVenvs(documentPath);
|
||||
if (!python.exists())
|
||||
python = venvInterpreters.value(0).command;
|
||||
|
||||
if (!python.exists())
|
||||
python = PythonSettings::defaultInterpreter().command;
|
||||
|
||||
@@ -248,9 +253,15 @@ public:
|
||||
? QString{"python-language-server[pyflakes]"}
|
||||
: QString{"python-language-server[all]"};
|
||||
|
||||
m_process.start(m_python.toString(), {"-m", "pip", "install", "--user", pylsVersion});
|
||||
QStringList arguments = {"-m", "pip", "install", pylsVersion};
|
||||
|
||||
Core::MessageManager::write(tr("Running '%1 %2' to install python language server")
|
||||
// add --user to global pythons, but skip it for venv pythons
|
||||
if (!QDir(m_python.parentDir().toString()).exists("activate"))
|
||||
arguments << "--user";
|
||||
|
||||
m_process.start(m_python.toString(), arguments);
|
||||
|
||||
Core::MessageManager::write(tr("Running \"%1 %2\" to install Python language server")
|
||||
.arg(m_process.program(), m_process.arguments().join(' ')));
|
||||
|
||||
m_killTimer.setSingleShot(true);
|
||||
@@ -261,7 +272,7 @@ private:
|
||||
void cancel()
|
||||
{
|
||||
SynchronousProcess::stopProcess(m_process);
|
||||
Core::MessageManager::write(tr("The Python language server installation canceled by %1.")
|
||||
Core::MessageManager::write(tr("The Python language server installation was canceled by %1.")
|
||||
.arg(m_killTimer.isActive() ? tr("user") : tr("time out")));
|
||||
}
|
||||
|
||||
@@ -371,7 +382,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
|
||||
&& infoBar->canInfoBeAdded(installPylsInfoBarId)) {
|
||||
auto message
|
||||
= tr("Install and set up Python language server (PyLS) for %1 (%2). "
|
||||
"The language server provides Python specific completions and annotations.")
|
||||
"The language server provides Python specific completion and annotation.")
|
||||
.arg(pythonName(python), python.toUserOutput());
|
||||
Core::InfoBarEntry info(installPylsInfoBarId,
|
||||
message,
|
||||
@@ -383,7 +394,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
|
||||
} else if (lsState.state == PythonLanguageServerState::AlreadyInstalled
|
||||
&& infoBar->canInfoBeAdded(startPylsInfoBarId)) {
|
||||
auto message = tr("Found a Python language server for %1 (%2). "
|
||||
"Should this one be set up for this document?")
|
||||
"Set it up for this document?")
|
||||
.arg(pythonName(python), python.toUserOutput());
|
||||
Core::InfoBarEntry info(startPylsInfoBarId,
|
||||
message,
|
||||
|
||||
Reference in New Issue
Block a user