KSyntaxHighlighting

keywordlist.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
3 SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
4
5 SPDX-License-Identifier: MIT
6*/
7
8#include "definition_p.h"
9#include "keywordlist_p.h"
10#include "ksyntaxhighlighting_logging.h"
11#include "repository.h"
12
13#include <QXmlStreamReader>
14
15#include <algorithm>
16
17using namespace KSyntaxHighlighting;
18
19namespace
20{
21struct KeywordComparator {
22 Qt::CaseSensitivity caseSensitive;
23
24 bool operator()(QStringView a, QStringView b) const
25 {
26 if (a.size() < b.size()) {
27 return true;
28 }
29
30 if (a.size() > b.size()) {
31 return false;
32 }
33
34 return a.compare(b, caseSensitive) < 0;
35 }
36};
37
38}
39
40bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) const
41{
42 /**
43 * get right vector to search in
44 */
45 const auto &vectorToSearch = (caseSensitive == Qt::CaseSensitive) ? m_keywordsSortedCaseSensitive : m_keywordsSortedCaseInsensitive;
46
47 /**
48 * search with right predicate
49 */
50 return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), str, KeywordComparator{caseSensitive});
51}
52
53void KeywordList::load(QXmlStreamReader &reader)
54{
55 Q_ASSERT(reader.name() == QLatin1String("list"));
56 Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
57
58 m_name = reader.attributes().value(QLatin1String("name")).toString();
59
60 while (!reader.atEnd()) {
61 switch (reader.tokenType()) {
63 if (reader.name() == QLatin1String("item")) {
64 m_keywords.append(reader.readElementText().trimmed());
65 reader.readNextStartElement();
66 break;
67 } else if (reader.name() == QLatin1String("include")) {
68 m_includes.append(reader.readElementText().trimmed());
69 reader.readNextStartElement();
70 break;
71 }
72 reader.readNext();
73 break;
75 reader.readNext();
76 return;
77 default:
78 reader.readNext();
79 break;
80 }
81 }
82}
83
84void KeywordList::setCaseSensitivity(Qt::CaseSensitivity caseSensitive)
85{
86 /**
87 * remember default case-sensitivity and init lookup for it
88 */
89 m_caseSensitive = caseSensitive;
90 initLookupForCaseSensitivity(m_caseSensitive);
91}
92
93void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive)
94{
95 /**
96 * get right vector to sort, if non-empty, we are done
97 */
98 auto &vectorToSort = (caseSensitive == Qt::CaseSensitive) ? m_keywordsSortedCaseSensitive : m_keywordsSortedCaseInsensitive;
99 if (!vectorToSort.empty()) {
100 return;
101 }
102
103 /**
104 * fill vector with refs to keywords
105 */
106 vectorToSort.assign(m_keywords.constBegin(), m_keywords.constEnd());
107
108 /**
109 * sort with right predicate
110 */
111 std::sort(vectorToSort.begin(), vectorToSort.end(), KeywordComparator{caseSensitive});
112}
113
114void KeywordList::resolveIncludeKeywords(DefinitionData &def)
115{
116 while (!m_includes.isEmpty()) {
117 const auto kw_include = std::move(m_includes.back());
118 m_includes.pop_back();
119
120 const auto idx = kw_include.indexOf(QLatin1String("##"));
121 KeywordList *keywords = nullptr;
122
123 if (idx >= 0) {
124 auto defName = kw_include.mid(idx + 2);
125 auto includeDef = def.repo->definitionForName(defName);
126 if (includeDef.isValid()) {
127 auto listName = kw_include.left(idx);
128 auto defData = DefinitionData::get(includeDef);
129 defData->load(DefinitionData::OnlyKeywords(true));
130 keywords = defData->keywordList(listName);
131 } else {
132 qCWarning(Log) << "Unable to resolve external include keyword for definition" << defName << "in" << def.name;
133 }
134 } else {
135 keywords = def.keywordList(kw_include);
136 }
137
138 if (keywords) {
139 if (this != keywords) {
140 keywords->resolveIncludeKeywords(def);
141 }
142 m_keywords += keywords->m_keywords;
143 } else {
144 qCWarning(Log) << "Unresolved include keyword" << kw_include << "in" << def.name;
145 }
146 }
147}
Syntax highlighting engine for Kate syntax definitions.
QString & append(QChar ch)
QString trimmed() const const
QString toString() const const
int compare(QStringView str, Qt::CaseSensitivity cs) const const
qsizetype size() const const
CaseSensitivity
QStringRef value(const QString &namespaceUri, const QString &name) const const
bool atEnd() const const
QXmlStreamAttributes attributes() const const
QStringRef name() const const
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
QXmlStreamReader::TokenType readNext()
bool readNextStartElement()
QXmlStreamReader::TokenType tokenType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:46:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.