From cdeac76df3f17a737b919e1bd4e405329f3f1d0c Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 11 May 2020 15:00:07 +0200 Subject: [PATCH] LSP: react on file list changed signal from project Fixes opening projects that lazy load their file lists. For example CMake projects open without a file list. This list will be generated after a successful configuration of the project. When a session is loaded that contains an open document from a project the document and project open signal is triggered when there is still no connection between these two. So recheck the project for documents after the file list got updated. Also add documents that are already opened before they are assigned to a project. Change-Id: I6f2bde0edf88a505116b05efe5564318f2cfb892 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.cpp | 18 +++++++++++++ src/plugins/languageclient/client.h | 1 + .../languageclient/languageclientmanager.cpp | 27 ++++++++++++++----- .../languageclient/languageclientmanager.h | 2 +- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 7aa1cf70c5c..5fad0bac464 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -842,7 +842,12 @@ const ProjectExplorer::Project *Client::project() const void Client::setCurrentProject(ProjectExplorer::Project *project) { + using namespace ProjectExplorer; + if (m_project) + disconnect(m_project, &Project::fileListChanged, this, &Client::projectFileListChanged); m_project = project; + if (m_project) + connect(m_project, &Project::fileListChanged, this, &Client::projectFileListChanged); } void Client::projectOpened(ProjectExplorer::Project *project) @@ -878,6 +883,19 @@ void Client::projectClosed(ProjectExplorer::Project *project) sendContent(change); } +void Client::projectFileListChanged() +{ + for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) { + if (m_project->isKnownFile(doc->filePath())) { + if (auto textDocument = qobject_cast(doc)) { + openDocument(textDocument); + if (!LanguageClientManager::clientForDocument(textDocument)) + LanguageClientManager::reOpenDocumentWithClient(textDocument, this); + } + } + } +} + void Client::setSupportedLanguage(const LanguageFilter &filter) { m_languagFilter = filter; diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 1f682555415..e311d750af7 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -130,6 +130,7 @@ public: const ProjectExplorer::Project *project() const; void projectOpened(ProjectExplorer::Project *project); void projectClosed(ProjectExplorer::Project *project); + void projectFileListChanged(); void sendContent(const LanguageServerProtocol::IContent &content); void sendContent(const LanguageServerProtocol::DocumentUri &uri, diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index dc686dd9d8a..7e42c5c070d 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,7 @@ LanguageClientManager::LanguageClientManager(QObject *parent) connect(EditorManager::instance(), &EditorManager::aboutToSave, this, &LanguageClientManager::documentWillSave); connect(SessionManager::instance(), &SessionManager::projectAdded, - this, &LanguageClientManager::projectAdded); + this, &LanguageClientManager::updateProject); connect(SessionManager::instance(), &SessionManager::projectRemoved, this, &LanguageClientManager::projectRemoved); } @@ -608,7 +609,7 @@ void LanguageClientManager::findUsages(TextEditor::TextDocument *document, const } } -void LanguageClientManager::projectAdded(ProjectExplorer::Project *project) +void LanguageClientManager::updateProject(ProjectExplorer::Project *project) { for (BaseSettings *setting : m_currentSettings) { if (setting->isValid() @@ -618,22 +619,36 @@ void LanguageClientManager::projectAdded(ProjectExplorer::Project *project) [project](QPointer client) { return client->project() == project; }) - == nullptr) { + == nullptr) { + Client *newClient = nullptr; for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) { - if (setting->m_languageFilter.isSupported(doc)) { - if (project->isKnownFile(doc->filePath())) - startClient(setting, project); + if (setting->m_languageFilter.isSupported(doc) + && project->isKnownFile(doc->filePath())) { + if (auto textDoc = qobject_cast(doc)) { + if (!newClient) + newClient = startClient(setting, project); + if (!newClient) + break; + openDocumentWithClient(textDoc, newClient); + if (m_clientForDocument.value(textDoc) == nullptr) + m_clientForDocument[textDoc] = newClient; + } } } } } } + connect(project, &ProjectExplorer::Project::fileListChanged, this, [this, project]() { + updateProject(project); + }); + for (Client *interface : reachableClients()) interface->projectOpened(project); } void LanguageClientManager::projectRemoved(ProjectExplorer::Project *project) { + project->disconnect(this); for (Client *interface : m_clients) interface->projectClosed(project); } diff --git a/src/plugins/languageclient/languageclientmanager.h b/src/plugins/languageclient/languageclientmanager.h index ae30540f44b..0af23e6b0e5 100644 --- a/src/plugins/languageclient/languageclientmanager.h +++ b/src/plugins/languageclient/languageclientmanager.h @@ -106,7 +106,7 @@ private: Utils::ProcessLinkCallback callback, const bool resolveTarget); void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor); - void projectAdded(ProjectExplorer::Project *project); + void updateProject(ProjectExplorer::Project *project); void projectRemoved(ProjectExplorer::Project *project); QVector reachableClients();