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.sliced(idx + 2);
125 auto includeDef = def.repo->definitionForName(defName);
126 if (includeDef.isValid()) {
127 auto listName = kw_include.sliced(0, 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 trimmed() const const
int compare(QChar ch) const const
qsizetype size() const const
QString toString() const const
CaseSensitivity
QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const const
bool atEnd() const const
QXmlStreamAttributes attributes() const const
QStringView name() const const
QString readElementText(ReadElementTextBehaviour behaviour)
TokenType readNext()
bool readNextStartElement()
TokenType tokenType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 29 2024 11:57:07 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.