forked from qt-creator/qt-creator
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:
@@ -65,6 +65,7 @@ add_qtc_plugin(TextEditor
|
|||||||
formatter.h
|
formatter.h
|
||||||
formattexteditor.cpp formattexteditor.h
|
formattexteditor.cpp formattexteditor.h
|
||||||
highlighter.cpp highlighter.h
|
highlighter.cpp highlighter.h
|
||||||
|
highlighterhelper.cpp highlighterhelper.h
|
||||||
highlightersettings.cpp highlightersettings.h
|
highlightersettings.cpp highlightersettings.h
|
||||||
highlightersettingspage.cpp highlightersettingspage.h
|
highlightersettingspage.cpp highlightersettingspage.h
|
||||||
icodestylepreferences.cpp icodestylepreferences.h
|
icodestylepreferences.cpp icodestylepreferences.h
|
||||||
|
|||||||
@@ -3,12 +3,8 @@
|
|||||||
|
|
||||||
#include "highlighter.h"
|
#include "highlighter.h"
|
||||||
|
|
||||||
#include "highlightersettings.h"
|
|
||||||
#include "tabsettings.h"
|
#include "tabsettings.h"
|
||||||
#include "textdocumentlayout.h"
|
#include "textdocumentlayout.h"
|
||||||
#include "texteditor.h"
|
|
||||||
#include "texteditortr.h"
|
|
||||||
#include "texteditorsettings.h"
|
|
||||||
|
|
||||||
#include <coreplugin/editormanager/documentmodel.h>
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -18,6 +14,7 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
#include <KSyntaxHighlighting/Definition>
|
||||||
#include <KSyntaxHighlighting/DefinitionDownloader>
|
#include <KSyntaxHighlighting/DefinitionDownloader>
|
||||||
#include <KSyntaxHighlighting/FoldingRegion>
|
#include <KSyntaxHighlighting/FoldingRegion>
|
||||||
#include <KSyntaxHighlighting/Format>
|
#include <KSyntaxHighlighting/Format>
|
||||||
@@ -33,23 +30,6 @@ namespace TextEditor {
|
|||||||
|
|
||||||
static Q_LOGGING_CATEGORY(highlighterLog, "qtc.editor.highlighter", QtWarningMsg)
|
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)
|
TextStyle categoryForTextStyle(int style)
|
||||||
{
|
{
|
||||||
switch (style) {
|
switch (style) {
|
||||||
@@ -94,175 +74,6 @@ Highlighter::Highlighter()
|
|||||||
&categoryForTextStyle);
|
&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)
|
static bool isOpeningParenthesis(QChar c)
|
||||||
{
|
{
|
||||||
return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('(');
|
return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('(');
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
#include <KSyntaxHighlighting/AbstractHighlighter>
|
#include <KSyntaxHighlighting/AbstractHighlighter>
|
||||||
#include <KSyntaxHighlighting/Definition>
|
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
class TextDocument;
|
class TextDocument;
|
||||||
@@ -18,26 +17,8 @@ class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::Abstra
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter)
|
Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter)
|
||||||
public:
|
public:
|
||||||
using Definition = KSyntaxHighlighting::Definition;
|
|
||||||
using Definitions = QList<Definition>;
|
|
||||||
Highlighter();
|
Highlighter();
|
||||||
|
|
||||||
static Definition definitionForName(const QString &name);
|
|
||||||
|
|
||||||
static Definitions definitionsForDocument(const TextDocument *document);
|
|
||||||
static Definitions definitionsForMimeType(const QString &mimeType);
|
|
||||||
static Definitions definitionsForFileName(const Utils::FilePath &fileName);
|
|
||||||
|
|
||||||
static void rememberDefinitionForDocument(const Definition &definition,
|
|
||||||
const TextDocument *document);
|
|
||||||
static void clearDefinitionForDocumentCache();
|
|
||||||
|
|
||||||
static void addCustomHighlighterPath(const Utils::FilePath &path);
|
|
||||||
static void downloadDefinitions(std::function<void()> callback = nullptr);
|
|
||||||
static void reload();
|
|
||||||
|
|
||||||
static void handleShutdown();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text) override;
|
void highlightBlock(const QString &text) override;
|
||||||
void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override;
|
void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override;
|
||||||
|
|||||||
223
src/plugins/texteditor/highlighterhelper.cpp
Normal file
223
src/plugins/texteditor/highlighterhelper.cpp
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "highlighterhelper.h"
|
||||||
|
|
||||||
|
#include "highlighter.h"
|
||||||
|
#include "highlightersettings.h"
|
||||||
|
#include "textdocument.h"
|
||||||
|
#include "texteditor.h"
|
||||||
|
#include "texteditorsettings.h"
|
||||||
|
#include "texteditortr.h"
|
||||||
|
|
||||||
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/messagemanager.h>
|
||||||
|
|
||||||
|
#include <utils/mimeutils.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcsettings.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
#include <KSyntaxHighlighting/DefinitionDownloader>
|
||||||
|
#include <KSyntaxHighlighting/FoldingRegion>
|
||||||
|
#include <KSyntaxHighlighting/Format>
|
||||||
|
#include <KSyntaxHighlighting/Repository>
|
||||||
|
#include <KSyntaxHighlighting/SyntaxHighlighter>
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace TextEditor::HighlighterHelper {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Definition definitionForName(const QString &name)
|
||||||
|
{
|
||||||
|
return highlightRepository()->definitionForName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Definitions definitionsForDocument(const TextEditor::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 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 HighlighterHelper::definitionForName(definitionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Definitions 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Definitions 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 rememberDefinitionForDocument(const Definition &definition,
|
||||||
|
const TextEditor::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 clearDefinitionForDocumentCache()
|
||||||
|
{
|
||||||
|
QtcSettings *settings = Core::ICore::settings();
|
||||||
|
settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY);
|
||||||
|
settings->remove(kDefinitionForMimeType);
|
||||||
|
settings->remove(kDefinitionForExtension);
|
||||||
|
settings->remove(kDefinitionForFilePath);
|
||||||
|
settings->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addCustomHighlighterPath(const FilePath &path)
|
||||||
|
{
|
||||||
|
highlightRepository()->addCustomSearchPath(path.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void downloadDefinitions(std::function<void()> callback)
|
||||||
|
{
|
||||||
|
auto downloader = new KSyntaxHighlighting::DefinitionDownloader(highlightRepository());
|
||||||
|
QObject::connect(downloader,
|
||||||
|
&KSyntaxHighlighting::DefinitionDownloader::done,
|
||||||
|
[downloader, callback]() {
|
||||||
|
Core::MessageManager::writeFlashing(Tr::tr("Highlighter updates: done"));
|
||||||
|
downloader->deleteLater();
|
||||||
|
reload();
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
QObject::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 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 handleShutdown()
|
||||||
|
{
|
||||||
|
delete highlightRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TextEditor::HighlighterHelper
|
||||||
35
src/plugins/texteditor/highlighterhelper.h
Normal file
35
src/plugins/texteditor/highlighterhelper.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <KSyntaxHighlighting/Definition>
|
||||||
|
|
||||||
|
namespace TextEditor {
|
||||||
|
class TextDocument;
|
||||||
|
|
||||||
|
namespace HighlighterHelper {
|
||||||
|
|
||||||
|
using Definition = KSyntaxHighlighting::Definition;
|
||||||
|
using Definitions = QList<Definition>;
|
||||||
|
|
||||||
|
Definition definitionForName(const QString &name);
|
||||||
|
|
||||||
|
Definitions definitionsForDocument(const TextDocument *document);
|
||||||
|
Definitions definitionsForMimeType(const QString &mimeType);
|
||||||
|
Definitions definitionsForFileName(const Utils::FilePath &fileName);
|
||||||
|
|
||||||
|
void rememberDefinitionForDocument(const Definition &definition, const TextDocument *document);
|
||||||
|
void clearDefinitionForDocumentCache();
|
||||||
|
|
||||||
|
void addCustomHighlighterPath(const Utils::FilePath &path);
|
||||||
|
void downloadDefinitions(std::function<void()> callback = nullptr);
|
||||||
|
void reload();
|
||||||
|
|
||||||
|
void handleShutdown();
|
||||||
|
|
||||||
|
} // namespace HighlighterHelper
|
||||||
|
|
||||||
|
} // namespace TextEditor
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#include "highlightersettingspage.h"
|
#include "highlightersettingspage.h"
|
||||||
|
|
||||||
#include "highlightersettings.h"
|
|
||||||
#include "highlighter.h"
|
#include "highlighter.h"
|
||||||
|
#include "highlighterhelper.h"
|
||||||
|
#include "highlightersettings.h"
|
||||||
#include "texteditortr.h"
|
#include "texteditortr.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -114,17 +115,17 @@ public:
|
|||||||
|
|
||||||
connect(downloadDefinitions, &QPushButton::pressed,
|
connect(downloadDefinitions, &QPushButton::pressed,
|
||||||
[label = QPointer<QLabel>(updateStatus)]() {
|
[label = QPointer<QLabel>(updateStatus)]() {
|
||||||
Highlighter::downloadDefinitions([label] {
|
HighlighterHelper::downloadDefinitions([label] {
|
||||||
if (label)
|
if (label)
|
||||||
label->setText(Tr::tr("Download finished"));
|
label->setText(Tr::tr("Download finished"));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(reloadDefinitions, &QPushButton::pressed, this, [] {
|
connect(reloadDefinitions, &QPushButton::pressed, this, [] {
|
||||||
Highlighter::reload();
|
HighlighterHelper::reload();
|
||||||
});
|
});
|
||||||
connect(resetCache, &QPushButton::clicked, this, [] {
|
connect(resetCache, &QPushButton::clicked, this, [] {
|
||||||
Highlighter::clearDefinitionForDocumentCache();
|
HighlighterHelper::clearDefinitionForDocumentCache();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "extraencodingsettings.h"
|
#include "extraencodingsettings.h"
|
||||||
#include "fontsettings.h"
|
#include "fontsettings.h"
|
||||||
#include "highlighter.h"
|
#include "highlighter.h"
|
||||||
|
#include "highlighterhelper.h"
|
||||||
#include "highlightersettings.h"
|
#include "highlightersettings.h"
|
||||||
#include "icodestylepreferences.h"
|
#include "icodestylepreferences.h"
|
||||||
#include "marginsettings.h"
|
#include "marginsettings.h"
|
||||||
@@ -724,7 +725,7 @@ public:
|
|||||||
void updateFileLineEndingVisible();
|
void updateFileLineEndingVisible();
|
||||||
|
|
||||||
void reconfigure();
|
void reconfigure();
|
||||||
void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName);
|
void updateSyntaxInfoBar(const HighlighterHelper::Definitions &definitions, const QString &fileName);
|
||||||
void removeSyntaxInfoBar();
|
void removeSyntaxInfoBar();
|
||||||
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
|
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
|
||||||
void setupFromDefinition(const KSyntaxHighlighting::Definition &definition);
|
void setupFromDefinition(const KSyntaxHighlighting::Definition &definition);
|
||||||
@@ -1930,7 +1931,7 @@ void TextEditorWidgetPrivate::foldLicenseHeader()
|
|||||||
QStringList commentMarker;
|
QStringList commentMarker;
|
||||||
if (auto highlighter = qobject_cast<Highlighter *>(
|
if (auto highlighter = qobject_cast<Highlighter *>(
|
||||||
q->textDocument()->syntaxHighlighter())) {
|
q->textDocument()->syntaxHighlighter())) {
|
||||||
const Highlighter::Definition def = highlighter->definition();
|
const HighlighterHelper::Definition def = highlighter->definition();
|
||||||
for (const QString &marker :
|
for (const QString &marker :
|
||||||
{def.singleLineCommentMarker(), def.multiLineCommentMarker().first}) {
|
{def.singleLineCommentMarker(), def.multiLineCommentMarker().first}) {
|
||||||
if (!marker.isEmpty())
|
if (!marker.isEmpty())
|
||||||
@@ -3638,7 +3639,7 @@ void TextEditorWidgetPrivate::reconfigure()
|
|||||||
q->configureGenericHighlighter();
|
q->configureGenericHighlighter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions &definitions,
|
void TextEditorWidgetPrivate::updateSyntaxInfoBar(const HighlighterHelper::Definitions &definitions,
|
||||||
const QString &fileName)
|
const QString &fileName)
|
||||||
{
|
{
|
||||||
Id missing(Constants::INFO_MISSING_SYNTAX_DEFINITION);
|
Id missing(Constants::INFO_MISSING_SYNTAX_DEFINITION);
|
||||||
@@ -3653,7 +3654,7 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions
|
|||||||
InfoBarEntry::GlobalSuppression::Enabled);
|
InfoBarEntry::GlobalSuppression::Enabled);
|
||||||
info.addCustomButton(Tr::tr("Download Definitions"), [missing, this]() {
|
info.addCustomButton(Tr::tr("Download Definitions"), [missing, this]() {
|
||||||
m_document->infoBar()->removeInfo(missing);
|
m_document->infoBar()->removeInfo(missing);
|
||||||
Highlighter::downloadDefinitions();
|
HighlighterHelper::downloadDefinitions();
|
||||||
});
|
});
|
||||||
|
|
||||||
infoBar->removeInfo(multiple);
|
infoBar->removeInfo(multiple);
|
||||||
@@ -3662,9 +3663,9 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions
|
|||||||
InfoBarEntry info(multiple,
|
InfoBarEntry info(multiple,
|
||||||
Tr::tr("More than one highlight definition was found for this file. "
|
Tr::tr("More than one highlight definition was found for this file. "
|
||||||
"Which one should be used to highlight this file?"));
|
"Which one should be used to highlight this file?"));
|
||||||
info.setComboInfo(Utils::transform(definitions, &Highlighter::Definition::name),
|
info.setComboInfo(Utils::transform(definitions, &HighlighterHelper::Definition::name),
|
||||||
[this](const InfoBarEntry::ComboInfo &info) {
|
[this](const InfoBarEntry::ComboInfo &info) {
|
||||||
this->configureGenericHighlighter(Highlighter::definitionForName(info.displayText));
|
this->configureGenericHighlighter(HighlighterHelper::definitionForName(info.displayText));
|
||||||
});
|
});
|
||||||
|
|
||||||
info.addCustomButton(Tr::tr("Remember My Choice"), [multiple, this]() {
|
info.addCustomButton(Tr::tr("Remember My Choice"), [multiple, this]() {
|
||||||
@@ -3733,9 +3734,9 @@ KSyntaxHighlighting::Definition TextEditorWidgetPrivate::currentDefinition()
|
|||||||
|
|
||||||
void TextEditorWidgetPrivate::rememberCurrentSyntaxDefinition()
|
void TextEditorWidgetPrivate::rememberCurrentSyntaxDefinition()
|
||||||
{
|
{
|
||||||
const Highlighter::Definition &definition = currentDefinition();
|
const HighlighterHelper::Definition &definition = currentDefinition();
|
||||||
if (definition.isValid())
|
if (definition.isValid())
|
||||||
Highlighter::rememberDefinitionForDocument(definition, m_document.data());
|
HighlighterHelper::rememberDefinitionForDocument(definition, m_document.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidgetPrivate::openLinkUnderCursor(bool openInNextSplit)
|
void TextEditorWidgetPrivate::openLinkUnderCursor(bool openInNextSplit)
|
||||||
@@ -9250,23 +9251,23 @@ QString TextEditorWidget::textAt(int from, int to) const
|
|||||||
|
|
||||||
void TextEditorWidget::configureGenericHighlighter()
|
void TextEditorWidget::configureGenericHighlighter()
|
||||||
{
|
{
|
||||||
Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument());
|
HighlighterHelper::Definitions definitions = HighlighterHelper::definitionsForDocument(textDocument());
|
||||||
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
|
d->configureGenericHighlighter(definitions.isEmpty() ? HighlighterHelper::Definition()
|
||||||
: definitions.first());
|
: definitions.first());
|
||||||
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());
|
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::configureGenericHighlighter(const Utils::MimeType &mimeType)
|
void TextEditorWidget::configureGenericHighlighter(const Utils::MimeType &mimeType)
|
||||||
{
|
{
|
||||||
Highlighter::Definitions definitions = Highlighter::definitionsForMimeType(mimeType.name());
|
HighlighterHelper::Definitions definitions = HighlighterHelper::definitionsForMimeType(mimeType.name());
|
||||||
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
|
d->configureGenericHighlighter(definitions.isEmpty() ? HighlighterHelper::Definition()
|
||||||
: definitions.first());
|
: definitions.first());
|
||||||
d->removeSyntaxInfoBar();
|
d->removeSyntaxInfoBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_str<void> TextEditorWidget::configureGenericHighlighter(const QString &definitionName)
|
expected_str<void> TextEditorWidget::configureGenericHighlighter(const QString &definitionName)
|
||||||
{
|
{
|
||||||
Highlighter::Definition definition = TextEditor::Highlighter::definitionForName(definitionName);
|
HighlighterHelper::Definition definition = TextEditor::HighlighterHelper::definitionForName(definitionName);
|
||||||
if (!definition.isValid())
|
if (!definition.isValid())
|
||||||
return make_unexpected(Tr::tr("Could not find definition."));
|
return make_unexpected(Tr::tr("Could not find definition."));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "findinfiles.h"
|
#include "findinfiles.h"
|
||||||
#include "findinopenfiles.h"
|
#include "findinopenfiles.h"
|
||||||
#include "fontsettings.h"
|
#include "fontsettings.h"
|
||||||
#include "highlighter.h"
|
#include "highlighterhelper.h"
|
||||||
#include "icodestylepreferences.h"
|
#include "icodestylepreferences.h"
|
||||||
#include "jsoneditor.h"
|
#include "jsoneditor.h"
|
||||||
#include "linenumberfilter.h"
|
#include "linenumberfilter.h"
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "snippets/snippetprovider.h"
|
#include "snippets/snippetprovider.h"
|
||||||
#include "tabsettings.h"
|
#include "tabsettings.h"
|
||||||
#include "textdocument.h"
|
#include "textdocument.h"
|
||||||
#include "textdocument.h"
|
|
||||||
#include "texteditor.h"
|
#include "texteditor.h"
|
||||||
#include "texteditorconstants.h"
|
#include "texteditorconstants.h"
|
||||||
#include "texteditorsettings.h"
|
#include "texteditorsettings.h"
|
||||||
@@ -437,7 +436,7 @@ LineNumberFilter *TextEditorPlugin::lineNumberFilter()
|
|||||||
|
|
||||||
ExtensionSystem::IPlugin::ShutdownFlag TextEditorPlugin::aboutToShutdown()
|
ExtensionSystem::IPlugin::ShutdownFlag TextEditorPlugin::aboutToShutdown()
|
||||||
{
|
{
|
||||||
Highlighter::handleShutdown();
|
HighlighterHelper::handleShutdown();
|
||||||
return SynchronousShutdown;
|
return SynchronousShutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user