// Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "client.h" #include "languageclient_global.h" #include "languageclientsettings.h" #include "lspinspector.h" #include #include #include #include #include namespace Core { class IEditor; class IDocument; } namespace ProjectExplorer { class BuildConfiguration; class Project; } namespace LanguageClient { class LanguageClientManagerPrivate; class LanguageClientMark; class LANGUAGECLIENT_EXPORT LanguageClientManager : public QObject { Q_OBJECT Q_DISABLE_COPY_MOVE(LanguageClientManager) public: ~LanguageClientManager() override; static void clientStarted(Client *client); static void clientFinished(Client *client); static Client *startClient(const BaseSettings *setting, ProjectExplorer::BuildConfiguration *bc = nullptr); static const QList clients(); static void addClient(Client *client); static void restartClient(Client *client); static void shutdownClient(Client *client); static void deleteClient(Client *client, bool unexpected = false); static void shutdown(); static bool isShutdownFinished(); static LanguageClientManager *instance(); static QList clientsSupportingDocument( const TextEditor::TextDocument *doc, bool onlyReachable = true); static void applySettings(); static void applySettings(const QString &settingsId); static void applySettings(BaseSettings *settings); static void writeSettings(); static QList currentSettings(); static void registerClientSettings(BaseSettings *settings); static void enableClientSettings(const QString &settingsId, bool enable = true); static QList clientsForSetting(const BaseSettings *setting); static QList clientsForSettingId(const QString &settingsId); static const BaseSettings *settingForClient(Client *setting); static QList clientsByName(const QString &name); static void updateWorkspaceConfiguration(const ProjectExplorer::Project *project, const QJsonValue &json); static Client *clientForDocument(TextEditor::TextDocument *document); static Client *clientForFilePath(const Utils::FilePath &filePath); static const QList clientsForBuildConfiguration(const ProjectExplorer::BuildConfiguration *bc); template static bool hasClients(); /// /// \brief openDocumentWithClient /// makes sure the document is opened and activated with the client and /// deactivates the document for a potential previous active client /// static void openDocumentWithClient(TextEditor::TextDocument *document, Client *client); static void logJsonRpcMessage(const LspLogMessage::MessageSender sender, const QString &clientName, const LanguageServerProtocol::JsonRpcMessage &message); static void showInspector(); public slots: // These slots are called automatically if the a file is opened via the usual EditorManager // methods. If you create an editor manually, you need to call these slots manually as well. void editorOpened(Core::IEditor *editor); void documentOpened(Core::IDocument *document); void documentClosed(Core::IDocument *document); signals: void clientAdded(Client *client); void clientInitialized(Client *client); void clientRemoved(Client *client, bool unexpected); void shutdownFinished(); void openCallHierarchy(); private: LanguageClientManager(); friend void setupLanguageClientManager(); void updateProject(ProjectExplorer::BuildConfiguration *bc); void buildConfigurationAdded(ProjectExplorer::BuildConfiguration *bc); void trackClientDeletion(Client *client); QList reachableClients(); QList m_clients; QSet m_restartingClients; QList m_currentSettings; // owned QMap> m_clientsForSetting; QHash> m_clientForDocument; std::unique_ptr d; LspInspector m_inspector; QSet m_scheduledForDeletion; }; template bool LanguageClientManager::hasClients() { return Utils::contains(instance()->m_clients, [](const Client *c) { return qobject_cast(c); }); } void setupLanguageClientManager(); } // namespace LanguageClient