KSyntaxHighlighting

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

KDE's Doxygen guidelines are available online.