SyntaxHighlighter: Move static functions to other namespace

- Created HighlighterHelper namespace and static functions
were moved there from the highlighter class

Change-Id: Ib93785a3819317d7c1d5cc480652d4635cb9339b
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Artem Sokolovskii
2023-11-01 10:08:31 +01:00
parent e53308eb7d
commit b26c43f133
8 changed files with 281 additions and 229 deletions

View File

@@ -3,12 +3,8 @@
#include "highlighter.h"
#include "highlightersettings.h"
#include "tabsettings.h"
#include "textdocumentlayout.h"
#include "texteditor.h"
#include "texteditortr.h"
#include "texteditorsettings.h"
#include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/icore.h>
@@ -18,6 +14,7 @@
#include <utils/qtcassert.h>
#include <utils/stylehelper.h>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/DefinitionDownloader>
#include <KSyntaxHighlighting/FoldingRegion>
#include <KSyntaxHighlighting/Format>
@@ -33,23 +30,6 @@ namespace TextEditor {
static Q_LOGGING_CATEGORY(highlighterLog, "qtc.editor.highlighter", QtWarningMsg)
const char kDefinitionForMimeType[] = "definitionForMimeType";
const char kDefinitionForExtension[] = "definitionForExtension";
const char kDefinitionForFilePath[] = "definitionForFilePath";
static KSyntaxHighlighting::Repository *highlightRepository()
{
static KSyntaxHighlighting::Repository *repository = nullptr;
if (!repository) {
repository = new KSyntaxHighlighting::Repository();
repository->addCustomSearchPath(TextEditorSettings::highlighterSettings().definitionFilesPath().toString());
const FilePath dir = Core::ICore::resourcePath("generic-highlighter/syntax");
if (dir.exists())
repository->addCustomSearchPath(dir.parentDir().path());
}
return repository;
}
TextStyle categoryForTextStyle(int style)
{
switch (style) {
@@ -94,175 +74,6 @@ Highlighter::Highlighter()
&categoryForTextStyle);
}
Highlighter::Definition Highlighter::definitionForName(const QString &name)
{
return highlightRepository()->definitionForName(name);
}
Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document)
{
QTC_ASSERT(document, return {});
// First try to find definitions for the file path, only afterwards try the MIME type.
// An example where that is important is if there was a definition for "*.rb.xml", which
// cannot be referred to with a MIME type (since there is none), but there is the definition
// for XML files, which specifies a MIME type in addition to a glob pattern.
// If we check the MIME type first and then skip the pattern, the definition for "*.rb.xml" is
// never considered.
// The KSyntaxHighlighting CLI also completely ignores MIME types.
const FilePath &filePath = document->filePath();
Definitions definitions = definitionsForFileName(filePath);
if (definitions.isEmpty()) {
// check for *.in filename since those are usually used for
// cmake configure_file input filenames without the .in extension
if (filePath.endsWith(".in"))
definitions = definitionsForFileName(FilePath::fromString(filePath.completeBaseName()));
if (filePath.fileName() == "qtquickcontrols2.conf")
definitions = definitionsForFileName(filePath.stringAppended(".ini"));
}
if (definitions.isEmpty()) {
const MimeType &mimeType = Utils::mimeTypeForName(document->mimeType());
if (mimeType.isValid()) {
Utils::visitMimeParents(mimeType, [&](const MimeType &mt) -> bool {
// highlight definitions might not use the canonical name but an alias
const QStringList names = QStringList(mt.name()) + mt.aliases();
for (const QString &name : names) {
definitions = definitionsForMimeType(name);
if (!definitions.isEmpty())
return false; // stop
}
return true; // continue
});
}
}
return definitions;
}
static Highlighter::Definition definitionForSetting(const Key &settingsKey,
const QString &mapKey)
{
QtcSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
const QString &definitionName = settings->value(settingsKey).toMap().value(mapKey).toString();
settings->endGroup();
return Highlighter::definitionForName(definitionName);
}
Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType)
{
Definitions definitions = highlightRepository()->definitionsForMimeType(mimeType).toList();
if (definitions.size() > 1) {
const Definition &rememberedDefinition = definitionForSetting(kDefinitionForMimeType,
mimeType);
if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition))
definitions = {rememberedDefinition};
}
return definitions;
}
Highlighter::Definitions Highlighter::definitionsForFileName(const FilePath &fileName)
{
Definitions definitions
= highlightRepository()->definitionsForFileName(fileName.fileName()).toList();
if (definitions.size() > 1) {
const QString &fileExtension = fileName.completeSuffix();
const Definition &rememberedDefinition
= fileExtension.isEmpty()
? definitionForSetting(kDefinitionForFilePath,
fileName.absoluteFilePath().toString())
: definitionForSetting(kDefinitionForExtension, fileExtension);
if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition))
definitions = {rememberedDefinition};
}
return definitions;
}
void Highlighter::rememberDefinitionForDocument(const Highlighter::Definition &definition,
const TextDocument *document)
{
QTC_ASSERT(document, return );
if (!definition.isValid())
return;
const QString &mimeType = document->mimeType();
const FilePath &path = document->filePath();
const QString &fileExtension = path.completeSuffix();
QtcSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
const Definitions &fileNameDefinitions = definitionsForFileName(path);
if (fileNameDefinitions.contains(definition)) {
if (!fileExtension.isEmpty()) {
const Key id(kDefinitionForExtension);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(fileExtension, definition.name());
settings->setValue(id, map);
} else if (!path.isEmpty()) {
const Key id(kDefinitionForFilePath);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(path.absoluteFilePath().toString(), definition.name());
settings->setValue(id, map);
}
} else if (!mimeType.isEmpty()) {
const Key id(kDefinitionForMimeType);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(mimeType, definition.name());
settings->setValue(id, map);
}
settings->endGroup();
}
void Highlighter::clearDefinitionForDocumentCache()
{
QtcSettings *settings = Core::ICore::settings();
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
settings->remove(kDefinitionForMimeType);
settings->remove(kDefinitionForExtension);
settings->remove(kDefinitionForFilePath);
settings->endGroup();
}
void Highlighter::addCustomHighlighterPath(const FilePath &path)
{
highlightRepository()->addCustomSearchPath(path.toString());
}
void Highlighter::downloadDefinitions(std::function<void()> callback)
{
auto downloader =
new KSyntaxHighlighting::DefinitionDownloader(highlightRepository());
connect(downloader, &KSyntaxHighlighting::DefinitionDownloader::done, [downloader, callback]() {
Core::MessageManager::writeFlashing(Tr::tr("Highlighter updates: done"));
downloader->deleteLater();
reload();
if (callback)
callback();
});
connect(downloader,
&KSyntaxHighlighting::DefinitionDownloader::informationMessage,
[](const QString &message) {
Core::MessageManager::writeSilently(Tr::tr("Highlighter updates:") + ' ' + message);
});
Core::MessageManager::writeDisrupting(Tr::tr("Highlighter updates: starting"));
downloader->start();
}
void Highlighter::reload()
{
highlightRepository()->reload();
for (auto editor : Core::DocumentModel::editorsForOpenedDocuments()) {
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
if (qobject_cast<Highlighter *>(textEditor->textDocument()->syntaxHighlighter()))
textEditor->editorWidget()->configureGenericHighlighter();
}
}
}
void Highlighter::handleShutdown()
{
delete highlightRepository();
}
static bool isOpeningParenthesis(QChar c)
{
return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('(');