From a6f0e564d4d80724f154fc1ab838cad9a337e8f4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 12 Mar 2019 11:01:25 +0100 Subject: [PATCH] LanguageClient: Add option to start server when needed Until now all servers where startet on creator startup. Change this default to start server when first file that matches the configured filter is opened. Additionally add an option that restores the old behavior of always on servers. Change-Id: I595e0ede1cf136cc803181377155bcd58ca1a83c Reviewed-by: Eike Ziller --- src/plugins/languageclient/client.cpp | 6 +-- .../languageclient/languageclientmanager.cpp | 4 ++ .../languageclient/languageclientsettings.cpp | 51 ++++++++++++++----- .../languageclient/languageclientsettings.h | 8 ++- 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 5553e58ecce..c67934bbdac 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -663,7 +663,7 @@ void Client::setSupportedLanguage(const LanguageFilter &filter) bool Client::isSupportedDocument(const Core::IDocument *document) const { QTC_ASSERT(document, return false); - return m_languagFilter.isSupported(document->filePath(), document->mimeType()); + return m_languagFilter.isSupported(document); } bool Client::isSupportedFile(const Utils::FileName &filePath, const QString &mimeType) const @@ -673,8 +673,8 @@ bool Client::isSupportedFile(const Utils::FileName &filePath, const QString &mim bool Client::isSupportedUri(const DocumentUri &uri) const { - return isSupportedFile(uri.toFileName(), - Utils::mimeTypeForFile(uri.toFileName().fileName()).name()); + return m_languagFilter.isSupported(uri.toFileName(), + Utils::mimeTypeForFile(uri.toFileName().fileName()).name()); } bool Client::needsRestart(const BaseSettings *settings) const diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 1cd162dc51a..e6b15210eb2 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -231,6 +231,10 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor) void LanguageClientManager::documentOpened(Core::IDocument *document) { + for (StdIOSettings *setting : LanguageClientSettings::currentSettings()) { + if (setting->m_client.isNull() && setting->m_languageFilter.isSupported(document)) + setting->startClient(); + } for (Client *interface : reachableClients()) interface->openDocument(document); } diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index a337a72b7b6..ddd00a272a7 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -30,7 +30,9 @@ #include "languageclient_global.h" #include "languageclientinterface.h" +#include #include +#include #include #include #include @@ -58,6 +60,7 @@ constexpr char nameKey[] = "name"; constexpr char enabledKey[] = "enabled"; +constexpr char alwaysOnKey[] = "alwaysOn"; constexpr char mimeTypeKey[] = "mimeType"; constexpr char filePatternKey[] = "filePattern"; constexpr char executableKey[] = "executable"; @@ -271,11 +274,15 @@ void LanguageClientSettingsPage::apply() } } for (StdIOSettings *setting : restarts) { - if (setting && setting->isValid() && setting->m_enabled) { - if (auto client = setting->createClient()) { - setting->m_client = client; - LanguageClientManager::startClient(client); - } + if (setting->isValid() && setting->m_enabled) { + const bool start = setting->m_alwaysOn + || Utils::anyOf(Core::DocumentModel::openedDocuments(), + [filter = setting->m_languageFilter]( + Core::IDocument *doc) { + return filter.isSupported(doc); + }); + if (start) + setting->startClient(); } } @@ -386,6 +393,7 @@ void BaseSettings::applyFromSettingsWidget(QWidget *widget) if (auto settingsWidget = qobject_cast(widget)) { m_name = settingsWidget->name(); m_languageFilter = settingsWidget->filter(); + m_alwaysOn = settingsWidget->alwaysOn(); } } @@ -404,16 +412,17 @@ bool BaseSettings::isValid() const return !m_name.isEmpty(); } -Client *BaseSettings::createClient() const +void BaseSettings::startClient() { + if (!isValid() || !m_enabled) + return; BaseClientInterface *interface = createInterface(); - if (QTC_GUARD(interface)) { - auto *client = new Client(interface); - client->setName(Utils::globalMacroExpander()->expand(m_name)); - client->setSupportedLanguage(m_languageFilter); - return client; - } - return nullptr; + QTC_ASSERT(interface, return); + auto *client = new Client(interface); + client->setName(Utils::globalMacroExpander()->expand(m_name)); + client->setSupportedLanguage(m_languageFilter); + m_client = client; + LanguageClientManager::startClient(client); } QVariantMap BaseSettings::toMap() const @@ -421,6 +430,7 @@ QVariantMap BaseSettings::toMap() const QVariantMap map; map.insert(nameKey, m_name); map.insert(enabledKey, m_enabled); + map.insert(alwaysOnKey, m_alwaysOn); map.insert(mimeTypeKey, m_languageFilter.mimeTypes); map.insert(filePatternKey, m_languageFilter.filePattern); return map; @@ -430,6 +440,7 @@ void BaseSettings::fromMap(const QVariantMap &map) { m_name = map[nameKey].toString(); m_enabled = map[enabledKey].toBool(); + m_alwaysOn = map.value(alwaysOnKey, false).toBool(); m_languageFilter.mimeTypes = map[mimeTypeKey].toStringList(); m_languageFilter.filePattern = map[filePatternKey].toStringList(); } @@ -546,6 +557,7 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa , m_name(new QLineEdit(settings->m_name, this)) , m_mimeTypes(new QLabel(settings->m_languageFilter.mimeTypes.join(filterSeparator), this)) , m_filePattern(new QLineEdit(settings->m_languageFilter.filePattern.join(filterSeparator), this)) + , m_alwaysOn(new QCheckBox()) { int row = 0; auto *mainLayout = new QGridLayout; @@ -562,6 +574,9 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa mainLayout->addLayout(mimeLayout, row, 1); m_filePattern->setPlaceholderText(tr("File pattern")); mainLayout->addWidget(m_filePattern, ++row, 1); + mainLayout->addWidget(new QLabel(tr("Always On:")), ++row, 0); + mainLayout->addWidget(m_alwaysOn, row, 1); + m_alwaysOn->setChecked(settings->m_alwaysOn); connect(addMimeTypeButton, &QPushButton::pressed, this, &BaseSettingsWidget::showAddMimeTypeDialog); @@ -604,6 +619,11 @@ LanguageFilter BaseSettingsWidget::filter() const m_filePattern->text().split(filterSeparator)}; } +bool BaseSettingsWidget::alwaysOn() const +{ + return m_alwaysOn->isChecked(); +} + class MimeTypeModel : public QStringListModel { public: @@ -741,4 +761,9 @@ bool LanguageFilter::isSupported(const Utils::FileName &filePath, const QString }); } +bool LanguageFilter::isSupported(const Core::IDocument *document) const +{ + return isSupported(document->filePath(), document->mimeType()); +} + } // namespace LanguageClient diff --git a/src/plugins/languageclient/languageclientsettings.h b/src/plugins/languageclient/languageclientsettings.h index dc4f61d6245..cf36d398f38 100644 --- a/src/plugins/languageclient/languageclientsettings.h +++ b/src/plugins/languageclient/languageclientsettings.h @@ -42,6 +42,8 @@ class FileName; class PathChooser; } // namespace Utils +namespace Core { class IDocument; } + namespace LanguageClient { constexpr char noLanguageFilter[] = "No Filter"; @@ -54,6 +56,7 @@ struct LanguageFilter QStringList mimeTypes; QStringList filePattern; bool isSupported(const Utils::FileName &filePath, const QString &mimeType) const; + bool isSupported(const Core::IDocument *document) const; }; class BaseSettings @@ -65,6 +68,7 @@ public: QString m_name = QString("New Language Server"); bool m_enabled = true; + bool m_alwaysOn = false; LanguageFilter m_languageFilter; QPointer m_client; // not owned @@ -73,7 +77,7 @@ public: virtual BaseSettings *copy() const { return new BaseSettings(*this); } virtual bool needsRestart() const; virtual bool isValid() const ; - Client *createClient() const; + void startClient(); virtual QVariantMap toMap() const; virtual void fromMap(const QVariantMap &map); @@ -135,6 +139,7 @@ public: QString name() const; LanguageFilter filter() const; + bool alwaysOn() const; private: void showAddMimeTypeDialog(); @@ -142,6 +147,7 @@ private: QLineEdit *m_name = nullptr; QLabel *m_mimeTypes = nullptr; QLineEdit *m_filePattern = nullptr; + QCheckBox *m_alwaysOn = nullptr; static constexpr char filterSeparator = ';'; };