diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 7ceb40011f8..85c2d1318bc 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -85,6 +86,13 @@ static CppEditor::CppModelManager *cppModelManager() return CppEditor::CppModelManager::instance(); } +static ProjectExplorer::Project *fallbackProject() +{ + if (ProjectExplorer::Project * const p = ProjectExplorer::ProjectTree::currentProject()) + return p; + return ProjectExplorer::SessionManager::startupProject(); +} + static const QList allCppEditors() { QList cppEditors; @@ -148,10 +156,7 @@ ClangModelManagerSupport::ClangModelManagerSupport() connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject, this, &ClangModelManagerSupport::onAboutToRemoveProject); connect(sessionManager, &ProjectExplorer::SessionManager::projectRemoved, - this, [this] { - if (ClangdClient * const fallbackClient = clientForProject(nullptr)) - claimNonProjectSources(fallbackClient); - }); + this, [this] { claimNonProjectSources(clientForProject(fallbackProject())); }); CppEditor::ClangdSettings::setDefaultClangdPath(Core::ICore::clangdExecutable(CLANG_BINDIR)); connect(&CppEditor::ClangdSettings::instance(), &CppEditor::ClangdSettings::changed, @@ -369,12 +374,15 @@ void ClangModelManagerSupport::updateLanguageClient( // Acquaint the client with all open C++ documents for this project. bool hasDocuments = false; for (TextEditor::BaseTextEditor * const editor : allCppEditors()) { - const Utils::FilePath filePath = editor->textDocument()->filePath(); - if (!project->isKnownFile(filePath)) - continue; - LanguageClientManager::openDocumentWithClient(editor->textDocument(), client); - ClangEditorDocumentProcessor::clearTextMarks(filePath); - hasDocuments = true; + TextEditor::TextDocument * const doc = editor->textDocument(); + const Client * const currentClient = LanguageClientManager::clientForDocument(doc); + if (!currentClient || !currentClient->project() + || currentClient->state() != Client::Initialized + || project->isKnownFile(doc->filePath())) { + LanguageClientManager::openDocumentWithClient(editor->textDocument(), client); + ClangEditorDocumentProcessor::clearTextMarks(doc->filePath()); + hasDocuments = true; + } } if (client->state() == Client::Initialized) @@ -443,7 +451,7 @@ ClangdClient *ClangModelManagerSupport::clientForProject( ClangdClient *ClangModelManagerSupport::clientForFile(const Utils::FilePath &file) const { - return clientForProject(ProjectExplorer::SessionManager::projectForFile(file)); + return qobject_cast(LanguageClientManager::clientForFilePath(file)); } ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *project, @@ -454,15 +462,19 @@ ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *p return client; } -void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *fallbackClient) +void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client) { + if (!client) + return; for (TextEditor::BaseTextEditor * const editor : allCppEditors()) { - if (ProjectExplorer::SessionManager::projectForFile(editor->textDocument()->filePath())) + if (Client * const currentClient = LanguageClientManager::clientForDocument( + editor->textDocument()); + currentClient && currentClient->state() == Client::Initialized + && (currentClient == client || currentClient->project())) { continue; - if (!fallbackClient->documentOpen(editor->textDocument())) { - ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath()); - fallbackClient->openDocument(editor->textDocument()); } + ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath()); + client->openDocument(editor->textDocument()); } } @@ -562,8 +574,10 @@ void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor) // TODO: Ensure that not fully loaded documents are updated? - ProjectExplorer::Project * const project + ProjectExplorer::Project * project = ProjectExplorer::SessionManager::projectForFile(document->filePath()); + if (!project) + project = fallbackProject(); if (ClangdClient * const client = clientForProject(project)) LanguageClientManager::openDocumentWithClient(textDocument, client); } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 8307ece252f..b957ae69b90 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -134,7 +134,7 @@ private: void updateLanguageClient(ProjectExplorer::Project *project, const CppEditor::ProjectInfo::ConstPtr &projectInfo); ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir); - void claimNonProjectSources(ClangdClient *fallbackClient); + void claimNonProjectSources(ClangdClient *client); void watchForExternalChanges(); void watchForInternalChanges(); diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 44f71140cee..d03fcc2c896 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -2036,7 +2036,7 @@ void ClangdTestExternalChanges::test() QVERIFY(waitForSignalOrTimeout(ClangModelManagerSupport::instance(), &ClangModelManagerSupport::createdClient, timeOutInMs())); ClangdClient * const newClient = ClangModelManagerSupport::instance() - ->clientForFile(filePath("main.cpp")); + ->clientForProject(project()); QVERIFY(newClient); QVERIFY(newClient != oldClient); newClient->enableTesting();