KSyntaxHighlighting

definition.cpp
1 /*
2  Copyright (C) 2016 Volker Krause <[email protected]>
3  Copyright (C) 2018 Dominik Haumann <[email protected]>
4  Copyright (C) 2018 Christoph Cullmann <[email protected]>
5 
6  Permission is hereby granted, free of charge, to any person obtaining
7  a copy of this software and associated documentation files (the
8  "Software"), to deal in the Software without restriction, including
9  without limitation the rights to use, copy, modify, merge, publish,
10  distribute, sublicense, and/or sell copies of the Software, and to
11  permit persons to whom the Software is furnished to do so, subject to
12  the following conditions:
13 
14  The above copyright notice and this permission notice shall be included
15  in all copies or substantial portions of the Software.
16 
17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 
26 #include "definition.h"
27 #include "definition_p.h"
28 #include "definitionref_p.h"
29 
30 #include "context_p.h"
31 #include "format.h"
32 #include "format_p.h"
33 #include "ksyntaxhighlighting_logging.h"
34 #include "ksyntaxhighlighting_version.h"
35 #include "repository.h"
36 #include "repository_p.h"
37 #include "rule_p.h"
38 #include "xml_p.h"
39 
40 #include <QCborMap>
41 #include <QCoreApplication>
42 #include <QFile>
43 #include <QHash>
44 #include <QStringList>
45 #include <QVector>
46 #include <QXmlStreamReader>
47 
48 #include <algorithm>
49 
50 using namespace KSyntaxHighlighting;
51 
52 DefinitionData::DefinitionData()
53  : wordDelimiters(QStringLiteral("\t !%&()*+,-./:;<=>?[\\]^{|}~")) // must be sorted!
54  , wordWrapDelimiters(wordDelimiters)
55 {
56 }
57 
58 DefinitionData::~DefinitionData()
59 {
60  qDeleteAll(contexts);
61 }
62 
63 DefinitionData *DefinitionData::get(const Definition &def)
64 {
65  return def.d.get();
66 }
67 
69  : d(new DefinitionData)
70 {
71 }
72 
74  : d(other.d)
75 {
76  d->q = *this;
77 }
78 
79 Definition::Definition(const std::shared_ptr<DefinitionData> &dd)
80  : d(dd)
81 {
82 }
83 
85 {
86 }
87 
89 {
90  d = rhs.d;
91  return *this;
92 }
93 
94 bool Definition::operator==(const Definition &other) const
95 {
96  return d->fileName == other.d->fileName;
97 }
98 
99 bool Definition::operator!=(const Definition &other) const
100 {
101  return d->fileName != other.d->fileName;
102 }
103 
105 {
106  return d->repo && !d->fileName.isEmpty() && !d->name.isEmpty();
107 }
108 
110 {
111  return d->fileName;
112 }
113 
115 {
116  return d->name;
117 }
118 
120 {
121  return QCoreApplication::instance()->translate("Language", d->name.toUtf8().constData());
122 }
123 
125 {
126  return d->section;
127 }
128 
130 {
131  return QCoreApplication::instance()->translate("Language Section", d->section.toUtf8().constData());
132 }
133 
135 {
136  return d->mimetypes;
137 }
138 
140 {
141  return d->extensions;
142 }
143 
145 {
146  return d->version;
147 }
148 
150 {
151  return d->priority;
152 }
153 
155 {
156  return d->hidden;
157 }
158 
160 {
161  return d->style;
162 }
163 
165 {
166  return d->indenter;
167 }
168 
170 {
171  return d->author;
172 }
173 
175 {
176  return d->license;
177 }
178 
180 {
181  d->load();
182  return d->isWordDelimiter(c);
183 }
184 
186 {
187  d->load();
188  return std::binary_search(d->wordWrapDelimiters.constBegin(), d->wordWrapDelimiters.constEnd(), c);
189 }
190 
192 {
193  d->load();
194  if (d->hasFoldingRegions || indentationBasedFoldingEnabled()) {
195  return true;
196  }
197 
198  // check included definitions
199  const auto defs = includedDefinitions();
200  for (const auto &def : defs) {
201  if (def.foldingEnabled()) {
202  d->hasFoldingRegions = true;
203  break;
204  }
205  }
206 
207  return d->hasFoldingRegions;
208 }
209 
211 {
212  d->load();
213  return d->indentationBasedFolding;
214 }
215 
217 {
218  d->load();
219  return d->foldingIgnoreList;
220 }
221 
223 {
224  d->load(DefinitionData::OnlyKeywords(true));
225  return d->keywordLists.keys();
226 }
227 
229 {
230  d->load(DefinitionData::OnlyKeywords(true));
231  const auto list = d->keywordList(name);
232  return list ? list->keywords() : QStringList();
233 }
234 
236 {
237  d->load(DefinitionData::OnlyKeywords(true));
238  KeywordList *list = d->keywordList(name);
239  if (list) {
240  list->setKeywordList(content);
241  return true;
242  } else
243  return false;
244 }
245 
247 {
248  d->load();
249 
250  // sort formats so that the order matches the order of the itemDatas in the xml files.
251  auto formatList = QVector<Format>::fromList(d->formats.values());
252  std::sort(formatList.begin(), formatList.end(), [](const KSyntaxHighlighting::Format &lhs, const KSyntaxHighlighting::Format &rhs) { return lhs.id() < rhs.id(); });
253 
254  return formatList;
255 }
256 
258 {
259  d->load();
260 
261  // init worklist and result used as guard with this definition
262  QVector<Definition> queue {*this};
263  QVector<Definition> definitions {*this};
264  while (!queue.isEmpty()) {
265  // Iterate all context rules to find associated Definitions. This will
266  // automatically catch other Definitions referenced with IncludeRuldes or ContextSwitch.
267  const auto definition = queue.takeLast();
268  for (const auto &context : qAsConst(definition.d->contexts)) {
269  // handle context switch attributes of this context itself
270  for (const auto switchContext : {context->lineEndContext().context(), context->lineEmptyContext().context(), context->fallthroughContext().context()}) {
271  if (switchContext) {
272  if (!definitions.contains(switchContext->definition())) {
273  queue.push_back(switchContext->definition());
274  definitions.push_back(switchContext->definition());
275  }
276  }
277  }
278 
279  // handle the embedded rules
280  for (const auto &rule : context->rules()) {
281  // handle include rules like inclusion
282  if (!definitions.contains(rule->definition())) {
283  queue.push_back(rule->definition());
284  definitions.push_back(rule->definition());
285  }
286 
287  // handle context switch context inclusion
288  if (auto switchContext = rule->context().context()) {
289  if (!definitions.contains(switchContext->definition())) {
290  queue.push_back(switchContext->definition());
291  definitions.push_back(switchContext->definition());
292  }
293  }
294  }
295  }
296  }
297 
298  // remove the 1st entry, since it is this Definition
299  definitions.pop_front();
300 
301  return definitions;
302 }
303 
305 {
306  d->load();
307  return d->singleLineCommentMarker;
308 }
309 
311 {
312  d->load();
313  return d->singleLineCommentPosition;
314 }
315 
317 {
318  d->load();
319  return {d->multiLineCommentStartMarker, d->multiLineCommentEndMarker};
320 }
321 
323 {
324  d->load();
325  return d->characterEncodings;
326 }
327 
328 Context *DefinitionData::initialContext() const
329 {
330  Q_ASSERT(!contexts.isEmpty());
331  return contexts.first();
332 }
333 
334 Context *DefinitionData::contextByName(const QString &wantedName) const
335 {
336  for (const auto context : contexts) {
337  if (context->name() == wantedName)
338  return context;
339  }
340  return nullptr;
341 }
342 
343 KeywordList *DefinitionData::keywordList(const QString &wantedName)
344 {
345  auto it = keywordLists.find(wantedName);
346  return (it == keywordLists.end()) ? nullptr : &it.value();
347 }
348 
349 bool DefinitionData::isWordDelimiter(QChar c) const
350 {
351  return std::binary_search(wordDelimiters.constBegin(), wordDelimiters.constEnd(), c);
352 }
353 
354 Format DefinitionData::formatByName(const QString &wantedName) const
355 {
356  const auto it = formats.constFind(wantedName);
357  if (it != formats.constEnd())
358  return it.value();
359 
360  return Format();
361 }
362 
363 bool DefinitionData::isLoaded() const
364 {
365  return !contexts.isEmpty();
366 }
367 
368 bool DefinitionData::load(OnlyKeywords onlyKeywords)
369 {
370  if (fileName.isEmpty())
371  return false;
372 
373  if (isLoaded())
374  return true;
375 
376  if (bool(onlyKeywords) && keywordIsLoaded)
377  return true;
378 
379  QFile file(fileName);
380  if (!file.open(QFile::ReadOnly))
381  return false;
382 
383  QXmlStreamReader reader(&file);
384  while (!reader.atEnd()) {
385  const auto token = reader.readNext();
386  if (token != QXmlStreamReader::StartElement)
387  continue;
388 
389  if (reader.name() == QLatin1String("highlighting")) {
390  loadHighlighting(reader, onlyKeywords);
391  if (bool(onlyKeywords)) {
392  return true;
393  }
394  }
395 
396  else if (reader.name() == QLatin1String("general"))
397  loadGeneral(reader);
398  }
399 
400  for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
401  it->setCaseSensitivity(caseSensitive);
402  }
403 
404  for (const auto context : qAsConst(contexts)) {
405  context->resolveContexts();
406  context->resolveIncludes();
407  context->resolveAttributeFormat();
408  }
409 
410  Q_ASSERT(std::is_sorted(wordDelimiters.constBegin(), wordDelimiters.constEnd()));
411  return true;
412 }
413 
414 void DefinitionData::clear()
415 {
416  // keep only name and repo, so we can re-lookup to make references persist over repo reloads
418  qDeleteAll(contexts);
419  contexts.clear();
420  formats.clear();
421 
422  fileName.clear();
423  section.clear();
424  style.clear();
425  indenter.clear();
426  author.clear();
427  license.clear();
428  mimetypes.clear();
429  extensions.clear();
430  wordDelimiters = QStringLiteral("\t !%&()*+,-./:;<=>?[\\]^{|}~"); // must be sorted!
431  wordWrapDelimiters = wordDelimiters;
432  caseSensitive = Qt::CaseSensitive;
433  version = 0.0f;
434  priority = 0;
435  hidden = false;
436 }
437 
438 bool DefinitionData::loadMetaData(const QString &definitionFileName)
439 {
440  fileName = definitionFileName;
441 
442  QFile file(definitionFileName);
443  if (!file.open(QFile::ReadOnly))
444  return false;
445 
446  QXmlStreamReader reader(&file);
447  while (!reader.atEnd()) {
448  const auto token = reader.readNext();
449  if (token != QXmlStreamReader::StartElement)
450  continue;
451  if (reader.name() == QLatin1String("language")) {
452  return loadLanguage(reader);
453  }
454  }
455 
456  return false;
457 }
458 
459 bool DefinitionData::loadMetaData(const QString &file, const QCborMap &obj)
460 {
461  name = obj.value(QLatin1String("name")).toString();
462  section = obj.value(QLatin1String("section")).toString();
463  version = obj.value(QLatin1String("version")).toInteger();
464  priority = obj.value(QLatin1String("priority")).toInteger();
465  style = obj.value(QLatin1String("style")).toString();
466  author = obj.value(QLatin1String("author")).toString();
467  license = obj.value(QLatin1String("license")).toString();
468  indenter = obj.value(QLatin1String("indenter")).toString();
469  hidden = obj.value(QLatin1String("hidden")).toBool();
470  fileName = file;
471 
472  const auto exts = obj.value(QLatin1String("extensions")).toString();
473 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
474  for (const auto &ext : exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
475 #else
476  for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
477 #endif
478  extensions.push_back(ext);
479  const auto mts = obj.value(QLatin1String("mimetype")).toString();
480 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
481  for (const auto &mt : mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
482 #else
483  for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
484 #endif
485  mimetypes.push_back(mt);
486 
487  return true;
488 }
489 
490 bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
491 {
492  Q_ASSERT(reader.name() == QLatin1String("language"));
493  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
494 
495  if (!checkKateVersion(reader.attributes().value(QStringLiteral("kateversion"))))
496  return false;
497 
498  name = reader.attributes().value(QStringLiteral("name")).toString();
499  section = reader.attributes().value(QStringLiteral("section")).toString();
500  // toFloat instead of toInt for backward compatibility with old Kate files
501  version = reader.attributes().value(QStringLiteral("version")).toFloat();
502  priority = reader.attributes().value(QStringLiteral("priority")).toInt();
503  hidden = Xml::attrToBool(reader.attributes().value(QStringLiteral("hidden")));
504  style = reader.attributes().value(QStringLiteral("style")).toString();
505  indenter = reader.attributes().value(QStringLiteral("indenter")).toString();
506  author = reader.attributes().value(QStringLiteral("author")).toString();
507  license = reader.attributes().value(QStringLiteral("license")).toString();
508  const auto exts = reader.attributes().value(QStringLiteral("extensions")).toString();
509 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
510  for (const auto &ext : exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
511 #else
512  for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
513 #endif
514  extensions.push_back(ext);
515  const auto mts = reader.attributes().value(QStringLiteral("mimetype")).toString();
516 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
517  for (const auto &mt : mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
518 #else
519  for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
520 #endif
521  mimetypes.push_back(mt);
522  if (reader.attributes().hasAttribute(QStringLiteral("casesensitive")))
523  caseSensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
524  return true;
525 }
526 
527 void DefinitionData::loadHighlighting(QXmlStreamReader &reader, OnlyKeywords onlyKeywords)
528 {
529  Q_ASSERT(reader.name() == QLatin1String("highlighting"));
530  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
531 
532  // skip highlighting
533  reader.readNext();
534 
535  while (!reader.atEnd()) {
536  switch (reader.tokenType()) {
538  if (reader.name() == QLatin1String("list")) {
539  if (!keywordIsLoaded) {
540  KeywordList keywords;
541  keywords.load(reader);
542  keywordLists.insert(keywords.name(), keywords);
543  } else {
544  reader.skipCurrentElement();
545  reader.readNext(); // Skip </list>
546  }
547  } else if (bool(onlyKeywords)) {
548  resolveIncludeKeywords();
549  return;
550  } else if (reader.name() == QLatin1String("contexts")) {
551  resolveIncludeKeywords();
552  loadContexts(reader);
553  reader.readNext();
554  } else if (reader.name() == QLatin1String("itemDatas")) {
555  loadItemData(reader);
556  } else {
557  reader.readNext();
558  }
559  break;
561  return;
562  default:
563  reader.readNext();
564  break;
565  }
566  }
567 }
568 
569 void DefinitionData::resolveIncludeKeywords()
570 {
571  if (keywordIsLoaded) {
572  return;
573  }
574 
575  keywordIsLoaded = true;
576 
577  for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
578  it->resolveIncludeKeywords(*this);
579  }
580 }
581 
582 void DefinitionData::loadContexts(QXmlStreamReader &reader)
583 {
584  Q_ASSERT(reader.name() == QLatin1String("contexts"));
585  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
586 
587  while (!reader.atEnd()) {
588  switch (reader.tokenType()) {
590  if (reader.name() == QLatin1String("context")) {
591  auto context = new Context;
592  context->setDefinition(q);
593  context->load(reader);
594  contexts.push_back(context);
595  }
596  reader.readNext();
597  break;
599  return;
600  default:
601  reader.readNext();
602  break;
603  }
604  }
605 }
606 
607 void DefinitionData::loadItemData(QXmlStreamReader &reader)
608 {
609  Q_ASSERT(reader.name() == QLatin1String("itemDatas"));
610  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
611 
612  while (!reader.atEnd()) {
613  switch (reader.tokenType()) {
615  if (reader.name() == QLatin1String("itemData")) {
616  Format f;
617  auto formatData = FormatPrivate::detachAndGet(f);
618  formatData->definition = q;
619  formatData->load(reader);
620  formatData->id = RepositoryPrivate::get(repo)->nextFormatId();
621  formats.insert(f.name(), f);
622  reader.readNext();
623  }
624  reader.readNext();
625  break;
627  return;
628  default:
629  reader.readNext();
630  break;
631  }
632  }
633 }
634 
635 void DefinitionData::loadGeneral(QXmlStreamReader &reader)
636 {
637  Q_ASSERT(reader.name() == QLatin1String("general"));
638  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
639  reader.readNext();
640 
641  // reference counter to count XML child elements, to not return too early
642  int elementRefCounter = 1;
643 
644  while (!reader.atEnd()) {
645  switch (reader.tokenType()) {
647  ++elementRefCounter;
648 
649  if (reader.name() == QLatin1String("keywords")) {
650  if (reader.attributes().hasAttribute(QStringLiteral("casesensitive")))
651  caseSensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
652 
653  // adapt sorted wordDelimiters
654  wordDelimiters += reader.attributes().value(QStringLiteral("additionalDeliminator"));
655  std::sort(wordDelimiters.begin(), wordDelimiters.end());
656  auto it = std::unique(wordDelimiters.begin(), wordDelimiters.end());
657  wordDelimiters.truncate(std::distance(wordDelimiters.begin(), it));
658  for (const auto c : reader.attributes().value(QLatin1String("weakDeliminator")))
659  wordDelimiters.remove(c);
660 
661  // adaptWordWrapDelimiters, and sort
662  wordWrapDelimiters = reader.attributes().value(QStringLiteral("wordWrapDeliminator")).toString();
663  std::sort(wordWrapDelimiters.begin(), wordWrapDelimiters.end());
664  if (wordWrapDelimiters.isEmpty())
665  wordWrapDelimiters = wordDelimiters;
666  } else if (reader.name() == QLatin1String("folding")) {
667  if (reader.attributes().hasAttribute(QStringLiteral("indentationsensitive")))
668  indentationBasedFolding = Xml::attrToBool(reader.attributes().value(QStringLiteral("indentationsensitive")));
669  } else if (reader.name() == QLatin1String("emptyLines")) {
670  loadFoldingIgnoreList(reader);
671  } else if (reader.name() == QLatin1String("comments")) {
672  loadComments(reader);
673  } else if (reader.name() == QLatin1String("spellchecking")) {
674  loadSpellchecking(reader);
675  } else {
676  reader.skipCurrentElement();
677  }
678  reader.readNext();
679  break;
681  --elementRefCounter;
682  if (elementRefCounter == 0)
683  return;
684  reader.readNext();
685  break;
686  default:
687  reader.readNext();
688  break;
689  }
690  }
691 }
692 
693 void DefinitionData::loadComments(QXmlStreamReader &reader)
694 {
695  Q_ASSERT(reader.name() == QLatin1String("comments"));
696  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
697  reader.readNext();
698 
699  // reference counter to count XML child elements, to not return too early
700  int elementRefCounter = 1;
701 
702  while (!reader.atEnd()) {
703  switch (reader.tokenType()) {
705  ++elementRefCounter;
706  if (reader.name() == QLatin1String("comment")) {
707  const bool isSingleLine = reader.attributes().value(QStringLiteral("name")) == QStringLiteral("singleLine");
708  if (isSingleLine) {
709  singleLineCommentMarker = reader.attributes().value(QStringLiteral("start")).toString();
710  const bool afterWhiteSpace = reader.attributes().value(QStringLiteral("position")).toString() == QStringLiteral("afterwhitespace");
712  } else {
713  multiLineCommentStartMarker = reader.attributes().value(QStringLiteral("start")).toString();
714  multiLineCommentEndMarker = reader.attributes().value(QStringLiteral("end")).toString();
715  }
716  }
717  reader.readNext();
718  break;
720  --elementRefCounter;
721  if (elementRefCounter == 0)
722  return;
723  reader.readNext();
724  break;
725  default:
726  reader.readNext();
727  break;
728  }
729  }
730 }
731 
732 void DefinitionData::loadFoldingIgnoreList(QXmlStreamReader &reader)
733 {
734  Q_ASSERT(reader.name() == QLatin1String("emptyLines"));
735  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
736  reader.readNext();
737 
738  // reference counter to count XML child elements, to not return too early
739  int elementRefCounter = 1;
740 
741  while (!reader.atEnd()) {
742  switch (reader.tokenType()) {
744  ++elementRefCounter;
745  if (reader.name() == QLatin1String("emptyLine")) {
746  foldingIgnoreList << reader.attributes().value(QStringLiteral("regexpr")).toString();
747  }
748  reader.readNext();
749  break;
751  --elementRefCounter;
752  if (elementRefCounter == 0)
753  return;
754  reader.readNext();
755  break;
756  default:
757  reader.readNext();
758  break;
759  }
760  }
761 }
762 
763 void DefinitionData::loadSpellchecking(QXmlStreamReader &reader)
764 {
765  Q_ASSERT(reader.name() == QLatin1String("spellchecking"));
766  Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
767  reader.readNext();
768 
769  // reference counter to count XML child elements, to not return too early
770  int elementRefCounter = 1;
771 
772  while (!reader.atEnd()) {
773  switch (reader.tokenType()) {
775  ++elementRefCounter;
776  if (reader.name() == QLatin1String("encoding")) {
777  const auto charRef = reader.attributes().value(QStringLiteral("char"));
778  if (!charRef.isEmpty()) {
779  const auto str = reader.attributes().value(QStringLiteral("string")).toString();
780  characterEncodings.push_back({charRef[0], str});
781  }
782  }
783  reader.readNext();
784  break;
786  --elementRefCounter;
787  if (elementRefCounter == 0)
788  return;
789  reader.readNext();
790  break;
791  default:
792  reader.readNext();
793  break;
794  }
795  }
796 }
797 
798 bool DefinitionData::checkKateVersion(const QStringRef &verStr)
799 {
800  const auto idx = verStr.indexOf(QLatin1Char('.'));
801  if (idx <= 0) {
802  qCWarning(Log) << "Skipping" << fileName << "due to having no valid kateversion attribute:" << verStr;
803  return false;
804  }
805  const auto major = verStr.left(idx).toInt();
806  const auto minor = verStr.mid(idx + 1).toInt();
807 
808  if (major > SyntaxHighlighting_VERSION_MAJOR || (major == SyntaxHighlighting_VERSION_MAJOR && minor > SyntaxHighlighting_VERSION_MINOR)) {
809  qCWarning(Log) << "Skipping" << fileName << "due to being too new, version:" << verStr;
810  return false;
811  }
812 
813  return true;
814 }
815 
816 quint16 DefinitionData::foldingRegionId(const QString &foldName)
817 {
818  hasFoldingRegions = true;
819  return RepositoryPrivate::get(repo)->foldingRegionId(name, foldName);
820 }
821 
822 DefinitionRef::DefinitionRef()
823 {
824 }
825 
826 DefinitionRef::DefinitionRef(const Definition &def)
827  : d(def.d)
828 {
829 }
830 
831 DefinitionRef::~DefinitionRef()
832 {
833 }
834 
835 DefinitionRef &DefinitionRef::operator=(const Definition &def)
836 {
837  d = def.d;
838  return *this;
839 }
840 
841 Definition DefinitionRef::definition() const
842 {
843  if (!d.expired())
844  return Definition(d.lock());
845  return Definition();
846 }
847 
848 bool DefinitionRef::operator==(const DefinitionRef &other) const
849 {
850  if (d.expired() != other.d.expired()) {
851  return false;
852  }
853 
854  return d.expired() || d.lock().get() == other.d.lock().get();
855 }
QVector< T > fromList(const QList< T > &list)
void clear()
bool atEnd() const const
int toInt(bool *ok, int base) const const
QStringList keywordList(const QString &name) const
Returns the list of keywords for the keyword list name.
Definition: definition.cpp:228
QString filePath() const
Returns the full path to the definition XML file containing the syntax definition.
Definition: definition.cpp:109
int priority() const
Returns the definition priority.
Definition: definition.cpp:149
Represents a syntax definition.
Definition: definition.h:103
bool foldingEnabled() const
Returns whether the highlighting supports code folding.
Definition: definition.cpp:191
QString name() const
Name of the syntax.
Definition: definition.cpp:114
QVector< QString > extensions() const
File extensions associated with this syntax definition.
Definition: definition.cpp:139
QString toString() const const
QCborValue value(qint64 key) const const
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
Definition()
Default constructor, creating an empty (invalid) Definition instance.
Definition: definition.cpp:68
Definition & operator=(const Definition &rhs)
Assignment operator.
Definition: definition.cpp:88
QStringList keywordLists() const
Returns the section names of keywords.
Definition: definition.cpp:222
QStringList foldingIgnoreList() const
If indentationBasedFoldingEnabled() returns true, this function returns a list of regular expressions...
Definition: definition.cpp:216
The comment marker is inserted at the beginning of a line at column 0.
CommentPosition
Defines the insert position when commenting code.
Definition: definition.h:53
int indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const const
QStringRef value(const QString &namespaceUri, const QString &name) const const
QPair< QString, QString > multiLineCommentMarker() const
Returns the markers that start and end multiline comments.
Definition: definition.cpp:316
bool isValid() const
Checks whether this object refers to a valid syntax definition.
Definition: definition.cpp:104
QString toString(const QString &defaultValue) const const
bool operator==(const Definition &other) const
Checks two definitions for equality.
Definition: definition.cpp:94
int version() const
Returns the definition version.
Definition: definition.cpp:144
QString translatedName() const
Translated name for display.
Definition: definition.cpp:119
T value(int i) const const
void clear()
void truncate(int position)
QString style() const
Generalized language style, used for indentation.
Definition: definition.cpp:159
void skipCurrentElement()
void clear()
QString author() const
Name and email of the author of this syntax definition.
Definition: definition.cpp:169
QString license() const
License of this syntax definition.
Definition: definition.cpp:174
CaseSensitive
float toFloat(bool *ok) const const
Syntax highlighting engine for Kate syntax definitions.
QVector< Format > formats() const
Returns a list of all Format items used by this definition.
Definition: definition.cpp:246
QCoreApplication * instance()
QStringRef left(int n) const const
QXmlStreamReader::TokenType readNext()
QVector< QString > mimeTypes() const
Mime types associated with this syntax definition.
Definition: definition.cpp:134
QXmlStreamReader::TokenType tokenType() const const
virtual bool open(QIODevice::OpenMode mode) override
T takeLast()
void push_back(QChar ch)
QString translatedSection() const
Translated group name for display.
Definition: definition.cpp:129
QList::iterator end()
QString name() const
The name of this format as used in the syntax definition file.
Definition: format.cpp:99
SkipEmptyParts
bool isWordDelimiter(QChar c) const
Returns whether the character c is a word delimiter.
Definition: definition.cpp:179
bool hasAttribute(const QString &qualifiedName) const const
QVector< QPair< QChar, QString > > characterEncodings() const
Returns a list of character/string mapping that can be used for spell checking.
Definition: definition.cpp:322
CommentPosition singleLineCommentPosition() const
Returns the insert position of the comment marker for sinle line comments.
Definition: definition.cpp:310
bool indentationBasedFoldingEnabled() const
Returns whether indentation-based folding is enabled.
Definition: definition.cpp:210
bool operator!=(const Definition &other) const
Checks two definitions for inequality.
Definition: definition.cpp:99
void insert(int i, const T &value)
bool isHidden() const
Returns true if this is an internal definition that should not be displayed to the user...
Definition: definition.cpp:154
The comment marker is inserted after leading whitespaces right befire the first non-whitespace charac...
quint16 id() const
Returns a unique identifier of this format.
Definition: format.cpp:104
bool setKeywordList(const QString &name, const QStringList &content)
Set the contents of the keyword list name to content.
Definition: definition.cpp:235
QStringRef mid(int position, int n) const const
void push_back(const T &value)
QXmlStreamAttributes attributes() const const
bool toBool(bool defaultValue) const const
QVector< Definition > includedDefinitions() const
Returns a list of Definitions that are referenced with the IncludeRules rule.
Definition: definition.cpp:257
QString indenter() const
Indentation style to be used for this syntax.
Definition: definition.cpp:164
qint64 toInteger(qint64 defaultValue) const const
QStringRef name() const const
Describes the format to be used for a specific text fragment.
Definition: format.h:50
QList::iterator begin()
QString singleLineCommentMarker() const
Returns the marker that starts a single line comment.
Definition: definition.cpp:304
QString section() const
The group this syntax definition belongs to.
Definition: definition.cpp:124
bool isWordWrapDelimiter(QChar c) const
Returns whether it is safe to break a line at before the character .
Definition: definition.cpp:185
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jul 10 2020 22:57:27 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.