9#include "definition_p.h"
10#include "ksyntaxhighlighting_logging.h"
11#include "repository_p.h"
13#include "themedata_p.h"
14#include "wildcardmatcher.h"
18#include <QDirIterator>
25#ifndef NO_STANDARD_PATHS
26#include <QStandardPaths>
45 const auto strings = def.extensions();
46 return std::any_of(strings.cbegin(), strings.cend(), [str](
QStringView wildcard) {
47 return WildcardMatcher::exactMatch(str, wildcard);
55 const auto strings = def.mimeTypes();
56 return std::any_of(strings.cbegin(), strings.cend(), [mimeTypeName](
QStringView name) {
57 return mimeTypeName == name;
64template<
typename UnaryPredicate>
68 auto matchPriority = std::numeric_limits<int>::lowest();
70 const auto defPriority = def.priority();
71 if (defPriority > matchPriority && predicate(def)) {
73 matchPriority = defPriority;
79template<
typename UnaryPredicate>
83 std::copy_if(defs.
cbegin(), defs.
cend(), std::back_inserter(matches), predicate);
85 return lhs.priority() > rhs.priority();
91static void initResource()
93#ifdef HAS_SYNTAX_RESOURCE
94 Q_INIT_RESOURCE(syntax_data);
96 Q_INIT_RESOURCE(theme_data);
99RepositoryPrivate *RepositoryPrivate::get(
Repository *repo)
101 return repo->d.get();
104Repository::Repository()
105 : d(new RepositoryPrivate)
111Repository::~Repository()
115 for (
const auto &def :
std::as_const(d->m_sortedDefs)) {
116 DefinitionData::get(def)->repo =
nullptr;
122 return d->m_fullDefs.value(defName.
toLower());
127 return findHighestPriorityDefinitionIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
132 return findDefinitionsIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
137 return findHighestPriorityDefinitionIf(d->m_defs, anyMimeTypeEquals(mimeType));
142 return findDefinitionsIf(d->m_defs, anyMimeTypeEquals(mimeType));
147 return d->m_sortedDefs;
158 return lhs.name() < rhs;
164 const auto &themes = d->m_themes;
165 const auto it = lowerBoundTheme(themes, themeName);
166 if (it != themes.end() && (*it).name() == themeName) {
175 return theme(QStringLiteral(
"Breeze Dark"));
177 return theme(QStringLiteral(
"Breeze Light"));
186 const Theme *firstMatchingTheme =
nullptr;
187 for (
const auto &
theme : std::as_const(d->m_themes)) {
189 if (background == base.rgb()) {
192 if (selection == highlight) {
195 if (!firstMatchingTheme) {
196 firstMatchingTheme = &
theme;
200 if (firstMatchingTheme) {
201 return *firstMatchingTheme;
214#ifndef NO_STANDARD_PATHS
216#ifndef HAS_SYNTAX_RESOURCE
218 QStringLiteral(
"org.kde.syntax-highlighting/syntax-bundled"),
220 if (!loadSyntaxFolderFromIndex(repo, dir)) {
221 loadSyntaxFolder(repo, dir);
227 QStringLiteral(
"org.kde.syntax-highlighting/syntax"),
229 loadSyntaxFolder(repo, dir);
234 loadSyntaxFolderFromIndex(repo, QStringLiteral(
":/org.kde.syntax-highlighting/syntax"));
237 loadSyntaxFolder(repo, QStringLiteral(
":/org.kde.syntax-highlighting/syntax-addons"));
240 for (
const auto &path :
std::as_const(m_customSearchPaths)) {
241 loadSyntaxFolder(repo, path + QStringLiteral(
"/syntax"));
244 m_sortedDefs.reserve(m_defs.size());
245 for (
auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it) {
246 m_sortedDefs.push_back(it.value());
248 std::sort(m_sortedDefs.begin(), m_sortedDefs.end(), [](
const Definition &left,
const Definition &right) {
249 auto comparison = left.translatedSection().compare(right.translatedSection(), Qt::CaseInsensitive);
250 if (comparison == 0) {
251 comparison = left.translatedName().compare(right.translatedName(), Qt::CaseInsensitive);
253 return comparison < 0;
256 for (
auto it = m_sortedDefs.constBegin(); it != m_sortedDefs.constEnd(); ++it) {
257 m_fullDefs.insert(it->name().toLower(), *it);
258 for (
const auto &altName : it->alternativeNames()) {
259 m_fullDefs.insert(altName.toLower(), *it);
266#ifndef NO_STANDARD_PATHS
268 QStringLiteral(
"org.kde.syntax-highlighting/themes"),
270 loadThemeFolder(dir);
275 loadThemeFolder(QStringLiteral(
":/org.kde.syntax-highlighting/themes"));
278 loadThemeFolder(QStringLiteral(
":/org.kde.syntax-highlighting/themes-addons"));
281 for (
const auto &path :
std::as_const(m_customSearchPaths)) {
282 loadThemeFolder(path + QStringLiteral(
"/themes"));
289 while (it.hasNext()) {
291 auto defData = DefinitionData::get(def);
292 defData->repo = repo;
293 if (defData->loadMetaData(it.next())) {
299bool RepositoryPrivate::loadSyntaxFolderFromIndex(
Repository *repo,
const QString &path)
307 const auto index = indexDoc.toMap();
308 for (
auto it = index.begin(); it != index.end(); ++it) {
309 if (!it.value().isMap()) {
313 const auto defMap = it.value().toMap();
315 auto defData = DefinitionData::get(def);
316 defData->repo = repo;
317 if (defData->loadMetaData(fileName, defMap)) {
325void RepositoryPrivate::addDefinition(
const Definition &def)
327 const auto it = m_defs.constFind(def.name());
328 if (it == m_defs.constEnd()) {
329 m_defs.insert(def.name(), def);
333 if (it.value().version() >= def.
version()) {
336 m_defs.insert(def.name(), def);
339void RepositoryPrivate::loadThemeFolder(
const QString &path)
342 while (it.hasNext()) {
343 auto themeData = std::unique_ptr<ThemeData>(
new ThemeData);
344 if (themeData->load(it.next())) {
345 addTheme(
Theme(themeData.release()));
350static int themeRevision(
const Theme &theme)
352 auto data = ThemeData::get(theme);
353 return data->revision();
356void RepositoryPrivate::addTheme(
const Theme &theme)
358 const auto &constThemes = m_themes;
359 const auto themeName = theme.name();
360 const auto constIt = lowerBoundTheme(constThemes, themeName);
361 const auto index = constIt - constThemes.begin();
362 if (constIt == constThemes.end() || (*constIt).name() != themeName) {
363 m_themes.insert(index, theme);
366 if (themeRevision(*constIt) < themeRevision(theme)) {
367 m_themes[index] = theme;
371int RepositoryPrivate::foldingRegionId(
const QString &defName,
const QString &foldName)
373 const auto it = m_foldingRegionIds.constFind(qMakePair(defName, foldName));
374 if (it != m_foldingRegionIds.constEnd()) {
377 Q_ASSERT(m_foldingRegionId < std::numeric_limits<int>::max());
378 m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId);
379 return m_foldingRegionId;
382int RepositoryPrivate::nextFormatId()
384 Q_ASSERT(m_formatId < std::numeric_limits<int>::max());
392 for (
const auto &def : std::as_const(d->m_sortedDefs)) {
393 DefinitionData::get(def)->clear();
396 d->m_sortedDefs.clear();
397 d->m_fullDefs.clear();
401 d->m_foldingRegionId = 0;
402 d->m_foldingRegionIds.clear();
413 d->m_customSearchPaths.append(path);
419 return d->m_customSearchPaths;
422#include "moc_repository.cpp"
Represents a syntax definition.
int version() const
Returns the definition version.
Syntax highlighting repository.
DefaultTheme
Built-in default theme types.
@ DarkTheme
Theme with a dark background color.
@ LightTheme
Theme with a light background color.
Q_INVOKABLE QList< KSyntaxHighlighting::Definition > definitionsForMimeType(const QString &mimeType) const
Returns all Definitions to the type named mimeType sorted by priority.
void reload()
Reloads the repository.
void addCustomSearchPath(const QString &path)
Add a custom search path to the repository.
Q_INVOKABLE KSyntaxHighlighting::Theme defaultTheme(DefaultTheme t=LightTheme) const
Returns a default theme instance of the given type.
void aboutToReload()
This signal is emitted before the reload is started.
Theme themeForPalette(const QPalette &palette) const
Returns the best matching theme for the given palette.
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType) const
Returns the best matching Definition to the type named mimeType.
Q_INVOKABLE QList< KSyntaxHighlighting::Definition > definitionsForFileName(const QString &fileName) const
Returns all Definitions for the file named fileName sorted by priority.
Q_INVOKABLE KSyntaxHighlighting::Theme theme(const QString &themeName) const
Returns the theme called themeName.
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForName(const QString &defName) const
Returns the Definition named defName.
QList< QString > customSearchPaths() const
Returns the list of custom search paths added to the repository.
void reloaded()
This signal is emitted when the reload is finished.
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName) const
Returns the best matching Definition for the file named fileName.
Color theme definition used for highlighting.
@ BackgroundColor
Background color for the editing area.
@ TextSelection
Background color for selected text.
QRgb editorColor(EditorColorRole role) const
Returns the editor color for the requested role.
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
Syntax highlighting engine for Kate syntax definitions.
QCborValue fromCbor(QCborStreamReader &reader)
const_iterator cbegin() const const
const_iterator cend() const const
const QColor & color(ColorGroup group, ColorRole role) const const
QString toLower() const const