forked from qt-creator/qt-creator
LanguageClient: also check for inherited mime types
... when trying to auto setup language servers as well when matching the configured mime types against a document mime type. In particular this fixes showing the auto setup editor info bar for the newly introduced clang format mime type as well as starting the yaml server for those files, since this clang format mime type inherits the yaml mime type. Change-Id: Id3ec64b0a1a128b070eadbcad600b3aaf4e667c3 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Artem Sokolovskii <artem.sokolovskii@qt.io>
This commit is contained in:
@@ -537,6 +537,41 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QList<BaseSettings *> sortedSettingsForDocument(Core::IDocument *document)
|
||||||
|
{
|
||||||
|
const QList<BaseSettings *> prefilteredSettings
|
||||||
|
= Utils::filtered(LanguageClientManager::currentSettings(), [](BaseSettings *setting) {
|
||||||
|
return setting->isValid() && setting->m_enabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType());
|
||||||
|
if (mimeType.isValid()) {
|
||||||
|
QList<BaseSettings *> result;
|
||||||
|
// prefer exact mime type matches
|
||||||
|
result << Utils::filtered(prefilteredSettings, [mimeType](BaseSettings *setting) {
|
||||||
|
return setting->m_languageFilter.mimeTypes.contains(mimeType.name());
|
||||||
|
});
|
||||||
|
|
||||||
|
// add filePath matches next
|
||||||
|
result << Utils::filtered(prefilteredSettings, [document](BaseSettings *setting) {
|
||||||
|
return setting->m_languageFilter.isSupported(document->filePath(), {});
|
||||||
|
});
|
||||||
|
|
||||||
|
// add parent mime type matches last
|
||||||
|
Utils::visitMimeParents(mimeType, [&](const Utils::MimeType &mt) -> bool {
|
||||||
|
result << Utils::filtered(prefilteredSettings, [mt](BaseSettings *setting) {
|
||||||
|
return setting->m_languageFilter.mimeTypes.contains(mt.name());
|
||||||
|
});
|
||||||
|
return true; // continue
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils::filtered(prefilteredSettings, [document](BaseSettings *setting) {
|
||||||
|
return setting->m_languageFilter.isSupported(document);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void LanguageClientManager::documentOpened(Core::IDocument *document)
|
void LanguageClientManager::documentOpened(Core::IDocument *document)
|
||||||
{
|
{
|
||||||
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
||||||
@@ -544,40 +579,39 @@ void LanguageClientManager::documentOpened(Core::IDocument *document)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// check whether we have to start servers for this document
|
// check whether we have to start servers for this document
|
||||||
const QList<BaseSettings *> settings = currentSettings();
|
const QList<BaseSettings *> settings = sortedSettingsForDocument(document);
|
||||||
|
QList<Client *> allClients;
|
||||||
for (BaseSettings *setting : settings) {
|
for (BaseSettings *setting : settings) {
|
||||||
if (setting->isValid() && setting->m_enabled
|
QList<Client *> clients = clientsForSetting(setting);
|
||||||
&& setting->m_languageFilter.isSupported(document)) {
|
if (setting->m_startBehavior == BaseSettings::RequiresProject) {
|
||||||
QList<Client *> clients = clientsForSetting(setting);
|
const Utils::FilePath &filePath = document->filePath();
|
||||||
if (setting->m_startBehavior == BaseSettings::RequiresProject) {
|
for (ProjectExplorer::Project *project : ProjectExplorer::ProjectManager::projects()) {
|
||||||
const Utils::FilePath &filePath = document->filePath();
|
// check whether file is part of this project
|
||||||
for (ProjectExplorer::Project *project :
|
if (!project->isKnownFile(filePath))
|
||||||
ProjectExplorer::ProjectManager::projects()) {
|
continue;
|
||||||
// check whether file is part of this project
|
|
||||||
if (!project->isKnownFile(filePath))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// check whether we already have a client running for this project
|
// check whether we already have a client running for this project
|
||||||
Client *clientForProject = Utils::findOrDefault(clients,
|
Client *clientForProject
|
||||||
[project](Client *client) {
|
= Utils::findOrDefault(clients, Utils::equal(&Client::project, project));
|
||||||
return client->project()
|
if (!clientForProject)
|
||||||
== project;
|
clientForProject = startClient(setting, project);
|
||||||
});
|
|
||||||
if (!clientForProject)
|
|
||||||
clientForProject = startClient(setting, project);
|
|
||||||
|
|
||||||
QTC_ASSERT(clientForProject, continue);
|
QTC_ASSERT(clientForProject, continue);
|
||||||
openDocumentWithClient(textDocument, clientForProject);
|
openDocumentWithClient(textDocument, clientForProject);
|
||||||
// Since we already opened the document in this client we remove the client
|
// Since we already opened the document in this client we remove the client
|
||||||
// from the list of clients that receive the openDocument call
|
// from the list of clients that receive the openDocument call
|
||||||
clients.removeAll(clientForProject);
|
clients.removeAll(clientForProject);
|
||||||
}
|
|
||||||
} else if (setting->m_startBehavior == BaseSettings::RequiresFile && clients.isEmpty()) {
|
|
||||||
clients << startClient(setting);
|
|
||||||
}
|
}
|
||||||
for (auto client : std::as_const(clients))
|
} else if (setting->m_startBehavior == BaseSettings::RequiresFile && clients.isEmpty()) {
|
||||||
client->openDocument(textDocument);
|
clients << startClient(setting);
|
||||||
}
|
}
|
||||||
|
allClients << clients;
|
||||||
|
}
|
||||||
|
for (auto client : std::as_const(allClients)) {
|
||||||
|
if (m_clientForDocument[textDocument])
|
||||||
|
client->openDocument(textDocument);
|
||||||
|
else
|
||||||
|
openDocumentWithClient(textDocument, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -996,10 +996,16 @@ QString StdIOSettingsWidget::arguments() const
|
|||||||
return m_arguments->text();
|
return m_arguments->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LanguageFilter::isSupported(const Utils::FilePath &filePath, const QString &mimeType) const
|
bool LanguageFilter::isSupported(const Utils::FilePath &filePath, const QString &mimeTypeName) const
|
||||||
{
|
{
|
||||||
if (mimeTypes.contains(mimeType))
|
if (!mimeTypes.isEmpty()) {
|
||||||
return true;
|
const MimeType mimeType = Utils::mimeTypeForName(mimeTypeName);
|
||||||
|
if (Utils::anyOf(mimeTypes, [mimeType](const QString &supported) {
|
||||||
|
return mimeType.inherits(supported);
|
||||||
|
})) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (filePattern.isEmpty() && filePath.isEmpty())
|
if (filePattern.isEmpty() && filePath.isEmpty())
|
||||||
return mimeTypes.isEmpty();
|
return mimeTypes.isEmpty();
|
||||||
const QRegularExpression::PatternOptions options
|
const QRegularExpression::PatternOptions options
|
||||||
|
|||||||
@@ -470,11 +470,14 @@ private:
|
|||||||
QTimer m_killTimer;
|
QTimer m_killTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr QLatin1StringView YAML_MIME_TYPE{"application/x-yaml"};
|
||||||
|
constexpr QLatin1StringView JSON_MIME_TYPE{"application/json"};
|
||||||
|
|
||||||
void autoSetupLanguageServer(TextDocument *document)
|
void autoSetupLanguageServer(TextDocument *document)
|
||||||
{
|
{
|
||||||
const QString mimeType = document->mimeType();
|
const auto mimeType = Utils::mimeTypeForName(document->mimeType());
|
||||||
if (mimeType == "application/x-yaml" || mimeType == "application/json") {
|
const bool isYaml = mimeType.inherits(YAML_MIME_TYPE);
|
||||||
const bool isYaml = mimeType == "application/x-yaml";
|
if (isYaml || mimeType.inherits(JSON_MIME_TYPE)) {
|
||||||
// check whether the user suppressed the info bar
|
// check whether the user suppressed the info bar
|
||||||
const Id infoBarId = isYaml ? installYamlLsInfoBarId : installJsonLsInfoBarId;
|
const Id infoBarId = isYaml ? installYamlLsInfoBarId : installJsonLsInfoBarId;
|
||||||
|
|
||||||
@@ -531,7 +534,7 @@ void autoSetupLanguageServer(TextDocument *document)
|
|||||||
settings->m_executable = executable;
|
settings->m_executable = executable;
|
||||||
settings->m_arguments = "--stdio";
|
settings->m_arguments = "--stdio";
|
||||||
settings->m_name = Tr::tr("%1 Language Server").arg(language);
|
settings->m_name = Tr::tr("%1 Language Server").arg(language);
|
||||||
settings->m_languageFilter.mimeTypes = {mimeType};
|
settings->m_languageFilter.mimeTypes = {isYaml ? YAML_MIME_TYPE : JSON_MIME_TYPE};
|
||||||
|
|
||||||
LanguageClientSettings::addSettings(settings);
|
LanguageClientSettings::addSettings(settings);
|
||||||
LanguageClientManager::applySettings();
|
LanguageClientManager::applySettings();
|
||||||
|
|||||||
Reference in New Issue
Block a user