Fix highlighting of debugger disassembly view

The disassembly view uses a custom MIME type that derives from x-asm,
but that didn't trigger highlighting.

Make the generic highlighter look at the parent MIME types if no
highlighting was found for the MIME type itself.

Generalize this "go breadth-first through the parents" that was already
used for resolving editor factories.

Change-Id: Ia054058a8c06b9d8849384e79ee3b83fbc12279c
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2023-01-03 11:54:05 +01:00
parent 15fa9e7096
commit b41abc94bb
4 changed files with 49 additions and 30 deletions

View File

@@ -100,4 +100,34 @@ void setMagicRulesForMimeType(const MimeType &mimeType, const QMap<int, QList<Mi
d->setMagicRulesForMimeType(mimeType, rules); d->setMagicRulesForMimeType(mimeType, rules);
} }
void visitMimeParents(const MimeType &mimeType,
const std::function<bool(const MimeType &mimeType)> &visitor)
{
// search breadth-first through parent hierarchy, e.g. for hierarchy
// * application/x-ruby
// * application/x-executable
// * application/octet-stream
// * text/plain
QList<MimeType> queue;
QSet<QString> seen;
queue.append(mimeType);
seen.insert(mimeType.name());
while (!queue.isEmpty()) {
const MimeType mt = queue.takeFirst();
if (!visitor(mt))
break;
// add parent mime types
const QStringList parentNames = mt.parentMimeTypes();
for (const QString &parentName : parentNames) {
const MimeType parent = mimeTypeForName(parentName);
if (parent.isValid()) {
int seenSize = seen.size();
seen.insert(parent.name());
if (seen.size() != seenSize) // not seen before, so add
queue.append(parent);
}
}
}
}
} // namespace Utils } // namespace Utils

View File

@@ -8,6 +8,8 @@
#include <mimemagicrule_p.h> #include <mimemagicrule_p.h>
#include <mimetype.h> #include <mimetype.h>
#include <functional>
namespace Utils { namespace Utils {
class FilePath; class FilePath;
@@ -49,4 +51,8 @@ QTCREATOR_UTILS_EXPORT void setGlobPatternsForMimeType(const MimeType &mimeType,
QTCREATOR_UTILS_EXPORT void setMagicRulesForMimeType( QTCREATOR_UTILS_EXPORT void setMagicRulesForMimeType(
const MimeType &mimeType, const QMap<int, QList<MimeMagicRule>> &rules); // priority -> rules const MimeType &mimeType, const QMap<int, QList<MimeMagicRule>> &rules); // priority -> rules
// visits all parents breadth-first
// visitor should return false to break the loop, true to continue
QTCREATOR_UTILS_EXPORT void visitMimeParents(
const MimeType &mimeType, const std::function<bool(const MimeType &mimeType)> &visitor);
} // namespace Utils } // namespace Utils

View File

@@ -25,17 +25,7 @@ static void mimeTypeFactoryLookup(const Utils::MimeType &mimeType,
QList<EditorTypeLike *> *list) QList<EditorTypeLike *> *list)
{ {
QSet<EditorTypeLike *> matches; QSet<EditorTypeLike *> matches;
// search breadth-first through parent hierarchy, e.g. for hierarchy Utils::visitMimeParents(mimeType, [&](const Utils::MimeType &mt) -> bool {
// * application/x-ruby
// * application/x-executable
// * application/octet-stream
// * text/plain
QList<Utils::MimeType> queue;
QSet<QString> seen;
queue.append(mimeType);
seen.insert(mimeType.name());
while (!queue.isEmpty()) {
Utils::MimeType mt = queue.takeFirst();
// check for matching factories // check for matching factories
for (EditorTypeLike *factory : allFactories) { for (EditorTypeLike *factory : allFactories) {
if (!matches.contains(factory)) { if (!matches.contains(factory)) {
@@ -48,18 +38,8 @@ static void mimeTypeFactoryLookup(const Utils::MimeType &mimeType,
} }
} }
} }
// add parent mime types return true; // continue
const QStringList parentNames = mt.parentMimeTypes(); });
for (const QString &parentName : parentNames) {
const Utils::MimeType parent = Utils::mimeTypeForName(parentName);
if (parent.isValid()) {
int seenSize = seen.size();
seen.insert(parent.name());
if (seen.size() != seenSize) // not seen before, so add
queue.append(parent);
}
}
}
} }
} // Internal } // Internal

View File

@@ -120,13 +120,16 @@ Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument
if (definitions.isEmpty()) { if (definitions.isEmpty()) {
const MimeType &mimeType = Utils::mimeTypeForName(document->mimeType()); const MimeType &mimeType = Utils::mimeTypeForName(document->mimeType());
if (mimeType.isValid()) { if (mimeType.isValid()) {
Utils::visitMimeParents(mimeType, [&](const MimeType &mt) -> bool {
// highlight definitions might not use the canonical name but an alias // highlight definitions might not use the canonical name but an alias
const QStringList names = QStringList(mimeType.name()) + mimeType.aliases(); const QStringList names = QStringList(mt.name()) + mt.aliases();
for (const QString &name : names) { for (const QString &name : names) {
definitions = definitionsForMimeType(name); definitions = definitionsForMimeType(name);
if (!definitions.isEmpty()) if (!definitions.isEmpty())
break; return false; // stop
} }
return true; // continue
});
} }
} }