diff options
author | David Schulz <david.schulz@qt.io> | 2019-03-15 11:25:48 +0100 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2019-04-29 09:52:02 +0000 |
commit | 0ea840c2bda03251318263aa96c5b1bc9b4a94e1 (patch) | |
tree | d6c33d6456c89da2fffbfad81fcc0d4a3ecd4ecf /src/plugins/languageclient/languageclientmanager.cpp | |
parent | 132d813343bd8dece5a39ed86db845f10f9dce47 (diff) |
LanguageClient: add option to start client per project
Some server like rust or haskell require a project at server startup.
Add option that postpones the server start until we can assign a project
to an open file.
Change-Id: Iaa475289e833b27a730a90ea228f5d85ecc30338
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins/languageclient/languageclientmanager.cpp')
-rw-r--r-- | src/plugins/languageclient/languageclientmanager.cpp | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 6f3249b9ec..75fae98545 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -112,15 +112,16 @@ void LanguageClientManager::startClient(Client *client) managerInstance->clientFinished(client); } -void LanguageClientManager::startClient(BaseSettings *setting) +void LanguageClientManager::startClient(BaseSettings *setting, ProjectExplorer::Project *project) { QTC_ASSERT(managerInstance, return); QTC_ASSERT(setting, return); QTC_ASSERT(setting->isValid(), return); Client *client = setting->createClient(); QTC_ASSERT(client, return); + client->setCurrentProject(project); startClient(client); - managerInstance->m_clientsForSetting[setting->m_id] = client; + managerInstance->m_clientsForSetting[setting->m_id].append(QPointer<Client>(client)); } QVector<Client *> LanguageClientManager::clients() @@ -207,14 +208,42 @@ void LanguageClientManager::applySettings() }); for (BaseSettings *setting : restarts) { - if (auto client = clientForSetting(setting)) { + for (const QPointer<Client> &client : clientForSetting(setting)) { if (client->reachable()) client->shutdown(); else deleteClient(client); } - if (setting->canStartClient()) + if (!setting->isValid() || !setting->m_enabled) + continue; + switch (setting->m_startBehavior) { + case BaseSettings::AlwaysOn: startClient(setting); + break; + case BaseSettings::RequiresFile: + if (Utils::anyOf(Core::DocumentModel::openedDocuments(), + [filter = setting->m_languageFilter](Core::IDocument *doc) { + return filter.isSupported(doc); + })) { + startClient(setting); + } + break; + case BaseSettings::RequiresProject: { + for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) { + if (setting->m_languageFilter.isSupported(doc)) { + const Utils::FileName filePath = doc->filePath(); + for (ProjectExplorer::Project *project : + ProjectExplorer::SessionManager::projects()) { + if (project->isKnownFile(filePath)) + startClient(setting, project); + } + } + } + break; + } + default: + break; + } } } @@ -224,10 +253,26 @@ QList<BaseSettings *> LanguageClientManager::currentSettings() return managerInstance->m_currentSettings; } -Client *LanguageClientManager::clientForSetting(const BaseSettings *setting) +QVector<QPointer<Client>> LanguageClientManager::clientForSetting(const BaseSettings *setting) +{ + QTC_ASSERT(managerInstance, return {}); + return managerInstance->m_clientsForSetting.value(setting->m_id); +} + +const BaseSettings *LanguageClientManager::settingForClient(Client *client) { QTC_ASSERT(managerInstance, return nullptr); - return managerInstance->m_clientsForSetting.value(setting->m_id, nullptr); + for (const QString &id : managerInstance->m_clientsForSetting.keys()) { + for (const QPointer<Client> &settingClient : managerInstance->m_clientsForSetting[id]) { + if (settingClient == client) { + return Utils::findOrDefault(managerInstance->m_currentSettings, + [id](BaseSettings *setting) { + return setting->m_id == id; + }); + } + } + } + return nullptr; } QVector<Client *> LanguageClientManager::reachableClients() @@ -255,7 +300,7 @@ void LanguageClientManager::clientFinished(Client *client) client->disconnect(this); client->log(tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS), Core::MessageManager::Flash); - QTimer::singleShot(restartTimeoutS * 1000, client, [client](){ startClient(client); }); + QTimer::singleShot(restartTimeoutS * 1000, client, [client]() { startClient(client); }); } else { if (unexpectedFinish && !m_shuttingDown) client->log(tr("Unexpectedly finished."), Core::MessageManager::Flash); @@ -299,9 +344,32 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor) void LanguageClientManager::documentOpened(Core::IDocument *document) { + // check whether we have to start servers for this document for (BaseSettings *setting : LanguageClientSettings::currentPageSettings()) { - if (clientForSetting(setting) == nullptr && setting->canStartClient()) - startClient(setting); + const QVector<QPointer<Client>> clients = clientForSetting(setting); + if (setting->isValid() && setting->m_enabled + && setting->m_languageFilter.isSupported(document)) { + if (setting->m_startBehavior == BaseSettings::RequiresProject) { + const Utils::FileName filePath = document->filePath(); + for (ProjectExplorer::Project *project : + ProjectExplorer::SessionManager::projects()) { + // check whether file is part of this project + if (!project->isKnownFile(filePath)) + continue; + + // check whether we already have a client running for this project + if (Utils::findOrDefault(clients, + [project](QPointer<Client> client) { + return client->project() == project; + })) { + continue; + } + startClient(setting, project); + } + } else if (setting->m_startBehavior == BaseSettings::RequiresFile && clients.isEmpty()) { + startClient(setting); + } + } } for (Client *interface : reachableClients()) interface->openDocument(document); @@ -427,13 +495,31 @@ void LanguageClientManager::findUsages(const Utils::FileName &filePath, const QT void LanguageClientManager::projectAdded(ProjectExplorer::Project *project) { + for (BaseSettings *setting : m_currentSettings) { + if (setting->isValid() + && setting->m_enabled + && setting->m_startBehavior == BaseSettings::RequiresProject) { + if (Utils::findOrDefault(clientForSetting(setting), + [project](QPointer<Client> client) { + return client->project() == project; + }) + .isNull()) { + for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) { + if (setting->m_languageFilter.isSupported(doc)) { + if (project->isKnownFile(doc->filePath())) + startClient(setting, project); + } + } + } + } + } for (Client *interface : reachableClients()) interface->projectOpened(project); } void LanguageClientManager::projectRemoved(ProjectExplorer::Project *project) { - for (Client *interface : reachableClients()) + for (Client *interface : m_clients) interface->projectClosed(project); } |