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 <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2020-05-11 15:00:07 +02:00
parent 172833bb1e
commit cdeac76df3
4 changed files with 41 additions and 7 deletions

View File

@@ -842,7 +842,12 @@ const ProjectExplorer::Project *Client::project() const
void Client::setCurrentProject(ProjectExplorer::Project *project) void Client::setCurrentProject(ProjectExplorer::Project *project)
{ {
using namespace ProjectExplorer;
if (m_project)
disconnect(m_project, &Project::fileListChanged, this, &Client::projectFileListChanged);
m_project = project; m_project = project;
if (m_project)
connect(m_project, &Project::fileListChanged, this, &Client::projectFileListChanged);
} }
void Client::projectOpened(ProjectExplorer::Project *project) void Client::projectOpened(ProjectExplorer::Project *project)
@@ -878,6 +883,19 @@ void Client::projectClosed(ProjectExplorer::Project *project)
sendContent(change); sendContent(change);
} }
void Client::projectFileListChanged()
{
for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) {
if (m_project->isKnownFile(doc->filePath())) {
if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(doc)) {
openDocument(textDocument);
if (!LanguageClientManager::clientForDocument(textDocument))
LanguageClientManager::reOpenDocumentWithClient(textDocument, this);
}
}
}
}
void Client::setSupportedLanguage(const LanguageFilter &filter) void Client::setSupportedLanguage(const LanguageFilter &filter)
{ {
m_languagFilter = filter; m_languagFilter = filter;

View File

@@ -130,6 +130,7 @@ public:
const ProjectExplorer::Project *project() const; const ProjectExplorer::Project *project() const;
void projectOpened(ProjectExplorer::Project *project); void projectOpened(ProjectExplorer::Project *project);
void projectClosed(ProjectExplorer::Project *project); void projectClosed(ProjectExplorer::Project *project);
void projectFileListChanged();
void sendContent(const LanguageServerProtocol::IContent &content); void sendContent(const LanguageServerProtocol::IContent &content);
void sendContent(const LanguageServerProtocol::DocumentUri &uri, void sendContent(const LanguageServerProtocol::DocumentUri &uri,

View File

@@ -35,6 +35,7 @@
#include <languageserverprotocol/messages.h> #include <languageserverprotocol/messages.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <texteditor/textmark.h> #include <texteditor/textmark.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
@@ -75,7 +76,7 @@ LanguageClientManager::LanguageClientManager(QObject *parent)
connect(EditorManager::instance(), &EditorManager::aboutToSave, connect(EditorManager::instance(), &EditorManager::aboutToSave,
this, &LanguageClientManager::documentWillSave); this, &LanguageClientManager::documentWillSave);
connect(SessionManager::instance(), &SessionManager::projectAdded, connect(SessionManager::instance(), &SessionManager::projectAdded,
this, &LanguageClientManager::projectAdded); this, &LanguageClientManager::updateProject);
connect(SessionManager::instance(), &SessionManager::projectRemoved, connect(SessionManager::instance(), &SessionManager::projectRemoved,
this, &LanguageClientManager::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) { for (BaseSettings *setting : m_currentSettings) {
if (setting->isValid() if (setting->isValid()
@@ -618,22 +619,36 @@ void LanguageClientManager::projectAdded(ProjectExplorer::Project *project)
[project](QPointer<Client> client) { [project](QPointer<Client> client) {
return client->project() == project; return client->project() == project;
}) })
== nullptr) { == nullptr) {
Client *newClient = nullptr;
for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) { for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) {
if (setting->m_languageFilter.isSupported(doc)) { if (setting->m_languageFilter.isSupported(doc)
if (project->isKnownFile(doc->filePath())) && project->isKnownFile(doc->filePath())) {
startClient(setting, project); if (auto textDoc = qobject_cast<TextEditor::TextDocument *>(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()) for (Client *interface : reachableClients())
interface->projectOpened(project); interface->projectOpened(project);
} }
void LanguageClientManager::projectRemoved(ProjectExplorer::Project *project) void LanguageClientManager::projectRemoved(ProjectExplorer::Project *project)
{ {
project->disconnect(this);
for (Client *interface : m_clients) for (Client *interface : m_clients)
interface->projectClosed(project); interface->projectClosed(project);
} }

View File

@@ -106,7 +106,7 @@ private:
Utils::ProcessLinkCallback callback, const bool resolveTarget); Utils::ProcessLinkCallback callback, const bool resolveTarget);
void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor); void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor);
void projectAdded(ProjectExplorer::Project *project); void updateProject(ProjectExplorer::Project *project);
void projectRemoved(ProjectExplorer::Project *project); void projectRemoved(ProjectExplorer::Project *project);
QVector<Client *> reachableClients(); QVector<Client *> reachableClients();