From 3b5fc296f26b9fa093d0d332654e6937fff7a132 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 10 Mar 2020 16:26:20 +0100 Subject: Python editor: Add buttons & actions for opening REPL Opens interactive Python, optionally with the current file imported, for testing and experimentation. Change-Id: Ieb120e3698bdba77a1445c40fe7fda533773a0cf Reviewed-by: David Schulz --- src/plugins/python/pythonutils.cpp | 57 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'src/plugins/python/pythonutils.cpp') diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp index e584a90e4d..de52e9413a 100644 --- a/src/plugins/python/pythonutils.cpp +++ b/src/plugins/python/pythonutils.cpp @@ -43,6 +43,8 @@ #include +#include +#include #include #include #include @@ -170,8 +172,10 @@ static FilePath detectPython(const FilePath &documentPath) { FilePath python; - PythonProject *project = qobject_cast( - ProjectExplorer::SessionManager::projectForFile(documentPath)); + PythonProject *project = documentPath.isEmpty() + ? nullptr + : qobject_cast( + ProjectExplorer::SessionManager::projectForFile(documentPath)); if (!project) project = qobject_cast(ProjectExplorer::SessionManager::startupProject()); @@ -480,6 +484,55 @@ PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent) }); } +static QStringList replImportArgs(const FilePath &pythonFile, ReplType type) +{ + using MimeTypes = QList; + const MimeTypes mimeTypes = pythonFile.isEmpty() || type == ReplType::Unmodified + ? MimeTypes() + : mimeTypesForFileName(pythonFile.toString()); + const bool isPython = Utils::anyOf(mimeTypes, [](const MimeType &mt) { + return mt.inherits("text/x-python") || mt.inherits("text/x-python3"); + }); + if (type == ReplType::Unmodified || !isPython) + return {}; + const auto import = type == ReplType::Import + ? QString("import %1").arg(pythonFile.toFileInfo().completeBaseName()) + : QString("from %1 import *") + .arg(pythonFile.toFileInfo().completeBaseName()); + return {"-c", QString("%1; print('Running \"%1\"')").arg(import)}; +} + +void openPythonRepl(const FilePath &file, ReplType type) +{ + static const auto workingDir = [](const FilePath &file) { + if (file.isEmpty()) { + if (ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject()) + return project->projectDirectory().toFileInfo().filePath(); + return QDir::currentPath(); + } + return file.toFileInfo().path(); + }; + + const auto args = QStringList{"-i"} + replImportArgs(file, type); + auto process = new ConsoleProcess; + const FilePath pythonCommand = detectPython(file); + process->setCommand({pythonCommand, args}); + process->setWorkingDirectory(workingDir(file)); + const QString commandLine = process->command().toUserOutput(); + QObject::connect(process, + &ConsoleProcess::processError, + process, + [process, commandLine](const QString &errorString) { + Core::MessageManager::write( + QCoreApplication::translate("Python", + "Failed to run Python (%1): \"%2\".") + .arg(commandLine, errorString)); + process->deleteLater(); + }); + QObject::connect(process, &ConsoleProcess::stubStopped, process, &QObject::deleteLater); + process->start(); +} + } // namespace Internal } // namespace Python -- cgit v1.2.1