From 9d1fe1df14f9fcd5443d4d4e5a5c869419a1c793 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 14 Mar 2022 10:09:55 +0100 Subject: [PATCH] Python: ensure opened file is inside a workspace The Python language server seems to dislike files that are not part of a workspace resulting in very long lookup times for specific symbols. Fixes: QTCREATORBUG-26230 Fixes: QTCREATORBUG-24704 Fixes: QTCREATORBUG-24140 Change-Id: Iceb7a2b3d57aea6554225a74587f619e530e10c9 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.h | 2 +- src/plugins/python/pythonlanguageclient.cpp | 49 +++++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 3327437d41f..88e27afbf20 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -143,7 +143,7 @@ public: bool isSupportedDocument(const TextEditor::TextDocument *document) const; bool isSupportedFile(const Utils::FilePath &filePath, const QString &mimeType) const; bool isSupportedUri(const LanguageServerProtocol::DocumentUri &uri) const; - void openDocument(TextEditor::TextDocument *document); + virtual void openDocument(TextEditor::TextDocument *document); void closeDocument(TextEditor::TextDocument *document); void activateDocument(TextEditor::TextDocument *document); void deactivateDocument(TextEditor::TextDocument *document); diff --git a/src/plugins/python/pythonlanguageclient.cpp b/src/plugins/python/pythonlanguageclient.cpp index 153f7e03bf7..7e7827faf6b 100644 --- a/src/plugins/python/pythonlanguageclient.cpp +++ b/src/plugins/python/pythonlanguageclient.cpp @@ -27,18 +27,18 @@ #include "pythonconstants.h" #include "pythonplugin.h" +#include "pythonproject.h" #include "pythonsettings.h" #include "pythonutils.h" #include #include #include - #include - +#include +#include #include #include - #include #include #include @@ -471,9 +471,50 @@ void PyLSSettings::setInterpreter(const QString &interpreterId) m_executable = interpreter.command; } +static PythonProject *projectForFile(const FilePath &pythonFile) +{ + for (ProjectExplorer::Project *project : ProjectExplorer::SessionManager::projects()) { + if (auto pythonProject = qobject_cast(project)) { + if (pythonProject->isKnownFile(pythonFile)) + return pythonProject; + } + } + return nullptr; +} + +class PyLSClient : public Client +{ +public: + using Client::Client; + void openDocument(TextEditor::TextDocument *document) override + { + using namespace LanguageServerProtocol; + if (reachable()) { + const FilePath documentPath = document->filePath(); + if (isSupportedDocument(document) && !projectForFile(documentPath)) { + const FilePath workspacePath = documentPath.parentDir(); + if (!extraWorkspaceDirs.contains(workspacePath)) { + WorkspaceFoldersChangeEvent event; + event.setAdded({WorkSpaceFolder(DocumentUri::fromFilePath(workspacePath), + workspacePath.fileName())}); + DidChangeWorkspaceFoldersParams params; + params.setEvent(event); + DidChangeWorkspaceFoldersNotification change(params); + sendContent(change); + extraWorkspaceDirs.append(workspacePath); + } + } + } + Client::openDocument(document); + } + +private: + FilePaths extraWorkspaceDirs; +}; + Client *PyLSSettings::createClient(BaseClientInterface *interface) const { - return new Client(interface); + return new PyLSClient(interface); } QJsonObject PyLSSettings::defaultConfiguration()