aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/python/pythonutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/python/pythonutils.cpp')
-rw-r--r--src/plugins/python/pythonutils.cpp97
1 files changed, 75 insertions, 22 deletions
diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp
index e584a90e4d..bd28d749b7 100644
--- a/src/plugins/python/pythonutils.cpp
+++ b/src/plugins/python/pythonutils.cpp
@@ -32,7 +32,6 @@
#include "pythonsettings.h"
#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/infobar.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <languageclient/languageclientmanager.h>
@@ -43,6 +42,9 @@
#include <texteditor/textdocument.h>
+#include <utils/consoleprocess.h>
+#include <utils/infobar.h>
+#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
@@ -116,8 +118,8 @@ FilePath getPylsModulePath(CommandLine pylsCommand)
QRegularExpression::MultilineOption);
const QString &output = response.allOutput();
- for (auto regex : {regexCached, regexNotCached}) {
- QRegularExpressionMatch result = regex.match(output);
+ for (const auto &regex : {regexCached, regexNotCached}) {
+ const QRegularExpressionMatch result = regex.match(output);
if (result.hasMatch()) {
const FilePath &modulePath = FilePath::fromUserInput(result.captured(1));
cache[pylsCommand.executable()] = modulePath;
@@ -170,8 +172,10 @@ static FilePath detectPython(const FilePath &documentPath)
{
FilePath python;
- PythonProject *project = qobject_cast<PythonProject *>(
- ProjectExplorer::SessionManager::projectForFile(documentPath));
+ PythonProject *project = documentPath.isEmpty()
+ ? nullptr
+ : qobject_cast<PythonProject *>(
+ ProjectExplorer::SessionManager::projectForFile(documentPath));
if (!project)
project = qobject_cast<PythonProject *>(ProjectExplorer::SessionManager::startupProject());
@@ -285,7 +289,7 @@ private:
m_future.reportFinished();
if (exitStatus == QProcess::NormalExit && exitCode == 0) {
if (Client *client = registerLanguageServer(m_python))
- LanguageClientManager::reOpenDocumentWithClient(m_document, client);
+ LanguageClientManager::openDocumentWithClient(m_document, client);
} else {
Core::MessageManager::write(
tr("Installing the Python language server failed with exit code %1").arg(exitCode));
@@ -334,7 +338,7 @@ static void setupPythonLanguageServer(const FilePath &python,
{
document->infoBar()->removeInfo(startPylsInfoBarId);
if (Client *client = registerLanguageServer(python))
- LanguageClientManager::reOpenDocumentWithClient(document, client);
+ LanguageClientManager::openDocumentWithClient(document, client);
}
static void enablePythonLanguageServer(const FilePath &python,
@@ -345,7 +349,7 @@ static void enablePythonLanguageServer(const FilePath &python,
LanguageClientManager::enableClientSettings(setting->m_id);
if (const StdIOSettings *setting = PyLSConfigureAssistant::languageServerForPython(python)) {
if (Client *client = LanguageClientManager::clientForSetting(setting).value(0)) {
- LanguageClientManager::reOpenDocumentWithClient(document, client);
+ LanguageClientManager::openDocumentWithClient(document, client);
PyLSConfigureAssistant::updateEditorInfoBars(python, client);
}
}
@@ -402,21 +406,21 @@ void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,
if (state.state == PythonLanguageServerState::AlreadyConfigured) {
if (const StdIOSettings *setting = languageServerForPython(python)) {
if (Client *client = LanguageClientManager::clientForSetting(setting).value(0))
- LanguageClientManager::reOpenDocumentWithClient(document, client);
+ LanguageClientManager::openDocumentWithClient(document, client);
}
return;
}
resetEditorInfoBar(document);
- Core::InfoBar *infoBar = document->infoBar();
+ Utils::InfoBar *infoBar = document->infoBar();
if (state.state == PythonLanguageServerState::CanBeInstalled
&& infoBar->canInfoBeAdded(installPylsInfoBarId)) {
auto message = tr("Install and set up Python language server (PyLS) for %1 (%2). "
"The language server provides Python specific completion and annotation.")
.arg(pythonName(python), python.toUserOutput());
- Core::InfoBarEntry info(installPylsInfoBarId,
- message,
- Core::InfoBarEntry::GlobalSuppression::Enabled);
+ Utils::InfoBarEntry info(installPylsInfoBarId,
+ message,
+ Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.setCustomButtonInfo(tr("Install"),
[=]() { installPythonLanguageServer(python, document); });
infoBar->addInfo(info);
@@ -426,10 +430,10 @@ void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,
auto message = tr("Found a Python language server for %1 (%2). "
"Set it up for this document?")
.arg(pythonName(python), python.toUserOutput());
- Core::InfoBarEntry info(startPylsInfoBarId,
- message,
- Core::InfoBarEntry::GlobalSuppression::Enabled);
- info.setCustomButtonInfo(tr("Setup"),
+ Utils::InfoBarEntry info(startPylsInfoBarId,
+ message,
+ Utils::InfoBarEntry::GlobalSuppression::Enabled);
+ info.setCustomButtonInfo(tr("Set Up"),
[=]() { setupPythonLanguageServer(python, document); });
infoBar->addInfo(info);
m_infoBarEntries[python] << document;
@@ -437,9 +441,9 @@ void PyLSConfigureAssistant::handlePyLSState(const FilePath &python,
&& infoBar->canInfoBeAdded(enablePylsInfoBarId)) {
auto message = tr("Enable Python language server for %1 (%2)?")
.arg(pythonName(python), python.toUserOutput());
- Core::InfoBarEntry info(enablePylsInfoBarId,
- message,
- Core::InfoBarEntry::GlobalSuppression::Enabled);
+ Utils::InfoBarEntry info(enablePylsInfoBarId,
+ message,
+ Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.setCustomButtonInfo(tr("Enable"),
[=]() { enablePythonLanguageServer(python, document); });
infoBar->addInfo(info);
@@ -452,7 +456,7 @@ void PyLSConfigureAssistant::updateEditorInfoBars(const FilePath &python, Client
for (TextEditor::TextDocument *document : instance()->m_infoBarEntries.take(python)) {
instance()->resetEditorInfoBar(document);
if (client)
- LanguageClientManager::reOpenDocumentWithClient(document, client);
+ LanguageClientManager::openDocumentWithClient(document, client);
}
}
@@ -460,7 +464,7 @@ void PyLSConfigureAssistant::resetEditorInfoBar(TextEditor::TextDocument *docume
{
for (QList<TextEditor::TextDocument *> &documents : m_infoBarEntries)
documents.removeAll(document);
- Core::InfoBar *infoBar = document->infoBar();
+ Utils::InfoBar *infoBar = document->infoBar();
infoBar->removeInfo(installPylsInfoBarId);
infoBar->removeInfo(startPylsInfoBarId);
infoBar->removeInfo(enablePylsInfoBarId);
@@ -480,6 +484,55 @@ PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent)
});
}
+static QStringList replImportArgs(const FilePath &pythonFile, ReplType type)
+{
+ using MimeTypes = QList<MimeType>;
+ 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