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 = ';'; };