diff --git a/src/syntax/katehighlight.cpp b/src/syntax/katehighlight.cpp index 5eba1712..3dc32684 100644 --- a/src/syntax/katehighlight.cpp +++ b/src/syntax/katehighlight.cpp @@ -1,684 +1,683 @@ /* This file is part of the KDE libraries Copyright (C) 2007 Mirko Stocker Copyright (C) 2007 Matthew Woehlke Copyright (C) 2003, 2004 Anders Lund Copyright (C) 2003 Hamish Rodda Copyright (C) 2001,2002 Joseph Wenninger Copyright (C) 2001 Christoph Cullmann Copyright (C) 1999 Jochen Wilhelmy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //BEGIN INCLUDES #include "katehighlight.h" #include "katetextline.h" #include "katedocument.h" #include "katerenderer.h" #include "kateglobal.h" #include "kateschema.h" #include "kateconfig.h" #include "kateextendedattribute.h" #include "katepartdebug.h" #include "katedefaultcolors.h" #include #include #include #include #include #include #include #include #include //END //BEGIN STATICS namespace { /** * convert from KSyntaxHighlighting => KTextEditor type * special handle non-1:1 things */ inline KTextEditor::DefaultStyle textStyleToDefaultStyle(const KSyntaxHighlighting::Theme::TextStyle textStyle) { // handle deviations if (textStyle == KSyntaxHighlighting::Theme::Error) { return KTextEditor::dsError; } if (textStyle == KSyntaxHighlighting::Theme::Others) { return KTextEditor::dsOthers; } // else: simple cast return static_cast(textStyle); } } //END //BEGIN KateHighlighting KateHighlighting::KateHighlighting(const KSyntaxHighlighting::Definition &def) { /** * get name and section, always works */ iName = def.name(); - iNameTranslated = def.translatedName(); iSection = def.translatedSection(); /** * handle the "no highlighting" case */ if (!def.isValid()) { // dummy hl info m_additionalData[iName]; m_hlIndex[0] = iName; // be done, all below is just for the real highlighting variants return; } /** * handle the real highlighting case */ noHl = false; iHidden = def.isHidden(); identifier = def.filePath(); iVersion = QString::number(def.version()); iStyle = def.style(); iAuthor = def.author(); iLicense = def.license(); m_indentation = def.indenter(); // FIXME folding = true; m_foldingIndentationSensitive = def.indentationBasedFoldingEnabled(); /** * tell the AbstractHighlighter the definition it shall use */ setDefinition(def); /** * get all included definitions, e.g. PHP for HTML highlighting */ auto definitions = definition().includedDefinitions(); /** * first: handle only really included definitions */ for (const auto &includedDefinition : definitions) embeddedHighlightingModes.push_back(includedDefinition.name()); /** * now: handle all, including this definition itself * create the format => attributes mapping * collect embedded highlightings, too * * we start with our definition as we want to have the default format * of the initial definition as attribute with index == 0 */ definitions.push_front(definition()); for (const auto & includedDefinition : definitions) { // FIXME: right values auto &properties = m_additionalData[includedDefinition.name()]; properties.definition = includedDefinition; for (const auto &emptyLine : includedDefinition.foldingIgnoreList()) properties.emptyLines.push_back(QRegularExpression(emptyLine)); properties.singleLineCommentMarker = includedDefinition.singleLineCommentMarker(); properties.singleLineCommentPosition = includedDefinition.singleLineCommentPosition(); const auto multiLineComment = includedDefinition.multiLineCommentMarker(); properties.multiLineCommentStart = multiLineComment.first; properties.multiLineCommentEnd = multiLineComment.second; // collect formats for (const auto & format : includedDefinition.formats()) { // register format id => internal attributes, we want no clashs const auto nextId = m_formats.size(); m_formatsIdToIndex.insert(std::make_pair(format.id(), nextId)).second; m_formats.push_back(format); m_hlIndex[nextId] = includedDefinition.name(); } } } KateHighlighting::~KateHighlighting() { } void KateHighlighting::doHighlight(const Kate::TextLineData *prevLine, Kate::TextLineData *textLine, const Kate::TextLineData *nextLine, bool &ctxChanged, int tabWidth) { // default: no context change ctxChanged = false; // no text line => nothing to do if (!textLine) { return; } // in all cases, remove old hl, or we will grow to infinite ;) textLine->clearAttributesAndFoldings(); // reset folding start textLine->clearMarkedAsFoldingStart(); // no hl set, nothing to do more than the above cleaning ;) if (noHl) { return; } /** * ensure we arrive in clean state */ Q_ASSERT(!m_textLineToHighlight); Q_ASSERT(!m_foldingStartToCount); /** * highlight the given line via the abstract highlighter * a bit ugly: we set the line to highlight as member to be able to update its stats in the applyFormat and applyFolding member functions */ m_textLineToHighlight = textLine; const KSyntaxHighlighting::State initialState (!prevLine ? KSyntaxHighlighting::State() : prevLine->highlightingState()); const KSyntaxHighlighting::State endOfLineState = highlightLine(textLine->string(), initialState); m_textLineToHighlight = nullptr; /** * update highlighting state if needed */ if (textLine->highlightingState() != endOfLineState) { textLine->setHighlightingState(endOfLineState); ctxChanged = true; } /** * handle folding info computed and cleanup hash again, if there * check if folding is not balanced and we have more starts then ends * then this line is a possible folding start! */ if (m_foldingStartToCount) { /** * possible folding start, if imbalanced, aka hash not empty! */ if (!m_foldingStartToCount->isEmpty()) { textLine->markAsFoldingStartAttribute(); } /** * kill hash */ delete m_foldingStartToCount; m_foldingStartToCount = nullptr; } /** * check for indentation based folding */ if (m_foldingIndentationSensitive && (tabWidth > 0) && !textLine->markedAsFoldingStartAttribute()) { /** * compute if we increase indentation in next line */ if (endOfLineState.indentationBasedFoldingEnabled() && !isEmptyLine(textLine) && !isEmptyLine(nextLine) && (textLine->indentDepth(tabWidth) < nextLine->indentDepth(tabWidth))) { textLine->markAsFoldingStartIndentation(); } } } void KateHighlighting::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) { // WE ATM assume ascending offset order Q_ASSERT(m_textLineToHighlight); Q_ASSERT(format.isValid()); // get internal attribute, must exist const auto it = m_formatsIdToIndex.find(format.id()); Q_ASSERT(it != m_formatsIdToIndex.end()); // remember highlighting info in our textline m_textLineToHighlight->addAttribute(Kate::TextLineData::Attribute(offset, length, it->second)); } void KateHighlighting::applyFolding(int offset, int, KSyntaxHighlighting::FoldingRegion region) { // WE ATM assume ascending offset order and don't care for length Q_ASSERT(m_textLineToHighlight); Q_ASSERT(region.isValid()); const int foldingValue = (region.type() == KSyntaxHighlighting::FoldingRegion::Begin) ? int(region.id()) : -int(region.id()); m_textLineToHighlight->addFolding(offset, foldingValue); /** * for each end region, decrement counter for that type, erase if count reaches 0! */ if ((foldingValue < 0) && m_foldingStartToCount) { QHash::iterator end = m_foldingStartToCount->find(foldingValue); if (end != m_foldingStartToCount->end()) { if (end.value() > 1) { --(end.value()); } else { m_foldingStartToCount->erase(end); } } } /** * increment counter for each begin region! */ if (foldingValue > 0) { // construct on demand! if (!m_foldingStartToCount) { m_foldingStartToCount = new QHash (); } ++(*m_foldingStartToCount)[foldingValue]; } } void KateHighlighting::getKateExtendedAttributeList(const QString &schema, QList &list, KConfig *cfg) { KConfigGroup config(cfg ? cfg : KateHlManager::self()->getKConfig(), QLatin1String("Highlighting ") + iName + QLatin1String(" - Schema ") + schema); list = attributesForDefinition(); foreach (KTextEditor::Attribute::Ptr p, list) { Q_ASSERT(p); QStringList s = config.readEntry(p->name(), QStringList()); // qCDebug(LOG_KTE)<name< 0) { while (s.count() < 10) { s << QString(); } QString name = p->name(); bool spellCheck = !p->skipSpellChecking(); p->clear(); p->setName(name); p->setSkipSpellChecking(!spellCheck); QString tmp = s[0]; if (!tmp.isEmpty()) { p->setDefaultStyle(static_cast (tmp.toInt())); } QRgb col; tmp = s[1]; if (!tmp.isEmpty()) { col = tmp.toUInt(nullptr, 16); p->setForeground(QColor(col)); } tmp = s[2]; if (!tmp.isEmpty()) { col = tmp.toUInt(nullptr, 16); p->setSelectedForeground(QColor(col)); } tmp = s[3]; if (!tmp.isEmpty()) { p->setFontBold(tmp != QLatin1String("0")); } tmp = s[4]; if (!tmp.isEmpty()) { p->setFontItalic(tmp != QLatin1String("0")); } tmp = s[5]; if (!tmp.isEmpty()) { p->setFontStrikeOut(tmp != QLatin1String("0")); } tmp = s[6]; if (!tmp.isEmpty()) { p->setFontUnderline(tmp != QLatin1String("0")); } tmp = s[7]; if (!tmp.isEmpty()) { col = tmp.toUInt(nullptr, 16); p->setBackground(QColor(col)); } tmp = s[8]; if (!tmp.isEmpty()) { col = tmp.toUInt(nullptr, 16); p->setSelectedBackground(QColor(col)); } tmp = s[9]; if (!tmp.isEmpty() && tmp != QLatin1String("---")) { p->setFontFamily(tmp); } } } } void KateHighlighting::getKateExtendedAttributeListCopy(const QString &schema, QList< KTextEditor::Attribute::Ptr > &list, KConfig *cfg) { QList attributes; getKateExtendedAttributeList(schema, attributes, cfg); list.clear(); foreach (const KTextEditor::Attribute::Ptr &attribute, attributes) { list.append(KTextEditor::Attribute::Ptr(new KTextEditor::Attribute(*attribute.data()))); } } void KateHighlighting::setKateExtendedAttributeList(const QString &schema, QList &list, KConfig *cfg, bool writeDefaultsToo) { KConfigGroup config(cfg ? cfg : KateHlManager::self()->getKConfig(), QLatin1String("Highlighting ") + iName + QLatin1String(" - Schema ") + schema); QStringList settings; KateAttributeList defList; KateHlManager::self()->getDefaults(schema, defList); foreach (const KTextEditor::Attribute::Ptr &p, list) { Q_ASSERT(p); settings.clear(); KTextEditor::DefaultStyle defStyle = p->defaultStyle(); KTextEditor::Attribute::Ptr a(defList[defStyle]); settings << QString::number(p->defaultStyle(), 10); settings << (p->hasProperty(QTextFormat::ForegroundBrush) ? QString::number(p->foreground().color().rgb(), 16) : (writeDefaultsToo ? QString::number(a->foreground().color().rgb(), 16) : QString())); settings << (p->hasProperty(SelectedForeground) ? QString::number(p->selectedForeground().color().rgb(), 16) : (writeDefaultsToo ? QString::number(a->selectedForeground().color().rgb(), 16) : QString())); settings << (p->hasProperty(QTextFormat::FontWeight) ? (p->fontBold() ? QStringLiteral("1") : QStringLiteral("0")) : (writeDefaultsToo ? (a->fontBold() ? QStringLiteral("1") : QStringLiteral("0")) : QString())); settings << (p->hasProperty(QTextFormat::FontItalic) ? (p->fontItalic() ? QStringLiteral("1") : QStringLiteral("0")) : (writeDefaultsToo ? (a->fontItalic() ? QStringLiteral("1") : QStringLiteral("0")) : QString())); settings << (p->hasProperty(QTextFormat::FontStrikeOut) ? (p->fontStrikeOut() ? QStringLiteral("1") : QStringLiteral("0")) : (writeDefaultsToo ? (a->fontStrikeOut() ? QStringLiteral("1") : QStringLiteral("0")) : QString())); settings << (p->hasProperty(QTextFormat::FontUnderline) ? (p->fontUnderline() ? QStringLiteral("1") : QStringLiteral("0")) : (writeDefaultsToo ? (a->fontUnderline() ? QStringLiteral("1") : QStringLiteral("0")) : QString())); settings << (p->hasProperty(QTextFormat::BackgroundBrush) ? QString::number(p->background().color().rgb(), 16) : ((writeDefaultsToo && a->hasProperty(QTextFormat::BackgroundBrush)) ? QString::number(a->background().color().rgb(), 16) : QString())); settings << (p->hasProperty(SelectedBackground) ? QString::number(p->selectedBackground().color().rgb(), 16) : ((writeDefaultsToo && a->hasProperty(SelectedBackground)) ? QString::number(a->selectedBackground().color().rgb(), 16) : QString())); settings << (p->hasProperty(QTextFormat::FontFamily) ? (p->fontFamily()) : (writeDefaultsToo ? a->fontFamily() : QString())); settings << QStringLiteral("---"); config.writeEntry(p->name(), settings); } } const QHash &KateHighlighting::getCharacterEncodings(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).characterEncodings; } const KatePrefixStore &KateHighlighting::getCharacterEncodingsPrefixStore(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).characterEncodingsPrefixStore; } const QHash &KateHighlighting::getReverseCharacterEncodings(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).reverseCharacterEncodings; } int KateHighlighting::getEncodedCharactersInsertionPolicy(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).encodedCharactersInsertionPolicy; } void KateHighlighting::addCharacterEncoding(const QString &key, const QString &encoding, const QChar &c) { m_additionalData[ key ].characterEncodingsPrefixStore.addPrefix(encoding); m_additionalData[ key ].characterEncodings[ encoding ] = c; m_additionalData[ key ].reverseCharacterEncodings[ c ] = encoding; } bool KateHighlighting::attributeRequiresSpellchecking(int attr) { if (attr >= 0 && attr < m_formats.size()) { return m_formats[attr].spellCheck(); } return true; } KTextEditor::DefaultStyle KateHighlighting::defaultStyleForAttribute(int attr) const { if (attr >= 0 && attr < m_formats.size()) { return textStyleToDefaultStyle(m_formats[attr].textStyle()); } return KTextEditor::dsNormal; } QString KateHighlighting::hlKeyForAttrib(int i) const { Q_ASSERT(i >= 0 && i < m_hlIndex.size()); return m_hlIndex[i]; } QString KateHighlighting::nameForAttrib(int attrib) const { Q_ASSERT(attrib >= 0 && attrib < m_formats.size()); return hlKeyForAttrib(attrib) + QLatin1Char(':') + m_formats[attrib].name(); } bool KateHighlighting::isInWord(QChar c, int attrib) const { return !additionalData(hlKeyForAttrib(attrib)).definition.isWordDelimiter(c) && !c.isSpace() && c != QLatin1Char('"') && c != QLatin1Char('\'') && c != QLatin1Char('`'); } bool KateHighlighting::canBreakAt(QChar c, int attrib) const { return additionalData(hlKeyForAttrib(attrib)).definition.isWordWrapDelimiter(c) && c != QLatin1Char('"') && c != QLatin1Char('\''); } const QVector &KateHighlighting::emptyLines(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).emptyLines; } bool KateHighlighting::canComment(int startAttrib, int endAttrib) const { QString k = hlKeyForAttrib(startAttrib); return (k == hlKeyForAttrib(endAttrib) && ((!additionalData(k).multiLineCommentStart.isEmpty() && !additionalData(k).multiLineCommentEnd.isEmpty()) || !additionalData(k).singleLineCommentMarker.isEmpty())); } QString KateHighlighting::getCommentStart(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).multiLineCommentStart; } QString KateHighlighting::getCommentEnd(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).multiLineCommentEnd; } QString KateHighlighting::getCommentSingleLineStart(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).singleLineCommentMarker; } KSyntaxHighlighting::CommentPosition KateHighlighting::getCommentSingleLinePosition(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).singleLineCommentPosition; } const QHash &KateHighlighting::characterEncodings(int attrib) const { return additionalData(hlKeyForAttrib(attrib)).characterEncodings; } void KateHighlighting::clearAttributeArrays() { // just clear the hashed attributes, we create them lazy again m_attributeArrays.clear(); } QList KateHighlighting::attributesForDefinition() { /** * create list of all known things */ QList array; if (m_formats.empty()) { KTextEditor::Attribute::Ptr newAttribute(new KTextEditor::Attribute(iName + QLatin1Char(':') + QLatin1String("Normal"), KTextEditor::dsNormal)); array.append(newAttribute); } else { for (const auto &format : m_formats) { /** * FIXME: atm we just set some theme here for later color generation */ setTheme(KateHlManager::self()->repository().defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); /** * create a KTextEditor attribute matching the given format */ KTextEditor::Attribute::Ptr newAttribute(new KTextEditor::Attribute(nameForAttrib(array.size()), textStyleToDefaultStyle(format.textStyle()))); if (format.hasTextColor(theme())) { newAttribute->setForeground(format.textColor(theme())); newAttribute->setSelectedForeground(format.selectedTextColor(theme())); } if (format.hasBackgroundColor(theme())) { newAttribute->setBackground(format.backgroundColor(theme())); newAttribute->setSelectedBackground(format.selectedBackgroundColor(theme())); } if (format.isBold(theme())) { newAttribute->setFontBold(true); } if (format.isItalic(theme())) { newAttribute->setFontItalic(true); } if (format.isUnderline(theme())) { newAttribute->setFontUnderline(true); } if (format.isStrikeThrough(theme())) { newAttribute->setFontStrikeOut(true); } newAttribute->setSkipSpellChecking(format.spellCheck()); array.append(newAttribute); } } return array; } QList KateHighlighting::attributes(const QString &schema) { // found it, already floating around if (m_attributeArrays.contains(schema)) { return m_attributeArrays[schema]; } // k, schema correct, let create the data QList array; KateAttributeList defaultStyleList; KateHlManager::self()->getDefaults(schema, defaultStyleList); QList itemDataList; getKateExtendedAttributeList(schema, itemDataList); uint nAttribs = itemDataList.count(); for (uint z = 0; z < nAttribs; z++) { KTextEditor::Attribute::Ptr itemData = itemDataList.at(z); KTextEditor::Attribute::Ptr newAttribute(new KTextEditor::Attribute(*defaultStyleList.at(itemData->defaultStyle()))); if (itemData && itemData->hasAnyProperty()) { *newAttribute += *itemData; } array.append(newAttribute); } m_attributeArrays.insert(schema, array); return array; } QStringList KateHighlighting::getEmbeddedHighlightingModes() const { return embeddedHighlightingModes; } bool KateHighlighting::isEmptyLine(const Kate::TextLineData *textline) const { const QString &txt = textline->string(); if (txt.isEmpty()) { return true; } const auto &l = emptyLines(textline->attribute(0)); if (l.isEmpty()) { return false; } foreach (const QRegularExpression &re, l) { const QRegularExpressionMatch match = re.match (txt, 0, QRegularExpression::NormalMatch, QRegularExpression::AnchoredMatchOption); if (match.hasMatch() && match.capturedLength() == txt.length()) { return true; } } return false; } int KateHighlighting::attributeForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor) { // Validate parameters to prevent out of range access if (cursor.line() < 0 || cursor.line() >= doc->lines() || cursor.column() < 0) { return 0; } // get highlighted line Kate::TextLine tl = doc->kateTextLine(cursor.line()); // make sure the textline is a valid pointer if (!tl) { return 0; } /** * either get char attribute or attribute of context still active at end of line */ if (cursor.column() < tl->length()) { return tl->attribute(cursor.column()); } else if (cursor.column() >= tl->length()) { if (!tl->attributesList().isEmpty()) { return tl->attributesList().back().attributeValue; } } return 0; } QStringList KateHighlighting::keywordsForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor) { // FIXME-SYNTAX: was before more precise, aka context level const auto &def = additionalData(m_hlIndex[attributeForLocation(doc, cursor)]).definition; QStringList keywords; for (const auto &keylist : def.keywordLists()) { keywords += def.keywordList(keylist); } return keywords; } bool KateHighlighting::spellCheckingRequiredForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor) { return m_formats[attributeForLocation(doc, cursor)].spellCheck(); } QString KateHighlighting::higlightingModeForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor) { return m_hlIndex[attributeForLocation(doc, cursor)]; } //END diff --git a/src/syntax/katehighlight.h b/src/syntax/katehighlight.h index 0f81c288..7532fb6b 100644 --- a/src/syntax/katehighlight.h +++ b/src/syntax/katehighlight.h @@ -1,411 +1,406 @@ /* This file is part of the KDE libraries Copyright (C) 2001,2002 Joseph Wenninger Copyright (C) 2001 Christoph Cullmann Copyright (C) 1999 Jochen Wilhelmy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef __KATE_HIGHLIGHT_H__ #define __KATE_HIGHLIGHT_H__ #include #include #include #include #include "katetextline.h" #include "kateextendedattribute.h" #include "katesyntaxmanager.h" #include "spellcheck/prefixstore.h" #include "range.h" #include #include #include #include #include #include #include #include #include #include class KConfig; namespace KTextEditor { class DocumentPrivate; } class KateHighlighting : private KSyntaxHighlighting::AbstractHighlighter { public: KateHighlighting(const KSyntaxHighlighting::Definition &def); ~KateHighlighting(); protected: /** * Reimplement this to apply formats to your output. The provided @p format * is valid for the interval [@p offset, @p offset + @p length). * * @param offset The start column of the interval for which @p format matches * @param length The length of the matching text * @param format The Format that applies to the range [offset, offset + length) * * @note Make sure to set a valid Definition, otherwise the parameter * @p format is invalid for the entire line passed to highlightLine() * (cf. Format::isValid()). * * @see applyFolding(), highlightLine() */ virtual void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; /** * Reimplement this to apply folding to your output. The provided * FoldingRegion @p region either stars or ends a code folding region in the * interval [@p offset, @p offset + @p length). * * @param offset The start column of the FoldingRegion * @param length The length of the matching text that starts / ends a * folding region * @param region The FoldingRegion that applies to the range [offset, offset + length) * * @note The FoldingRegion @p region is @e always either of type * FoldingRegion::Type::Begin or FoldingRegion::Type::End. * * @see applyFormat(), highlightLine(), FoldingRegion */ virtual void applyFolding(int offset, int length, KSyntaxHighlighting::FoldingRegion region) override; public: /** * Parse the text and fill in the context array and folding list array * * @param prevLine The previous line, the context array is picked up from that if present. * @param textLine The text line to parse * @param nextLine The next line, to check if indentation changed for indentation based folding. * @param ctxChanged will be set to reflect if the context changed * @param tabWidth tab width for indentation based folding, if wanted, else 0 */ void doHighlight(const Kate::TextLineData *prevLine, Kate::TextLineData *textLine, const Kate::TextLineData *nextLine, bool &ctxChanged, int tabWidth = 0); /** * Saves the attribute definitions to the config file. * * @param schema The id of the schema group to save * @param list QList containing the data to be used */ void setKateExtendedAttributeList(const QString &schema, QList &list, KConfig *cfg = nullptr /*if 0 standard kate config*/, bool writeDefaultsToo = false); const QString &name() const { return iName; } - const QString &nameTranslated() const - { - return iNameTranslated; - } const QString §ion() const { return iSection; } bool hidden() const { return iHidden; } const QString &version() const { return iVersion; } const QString &style() const { return iStyle; } const QString &author() const { return iAuthor; } const QString &license() const { return iLicense; } const QString &getIdentifier() const { return identifier; } /** * @return true if the character @p c is not a deliminator character * for the corresponding highlight. */ bool isInWord(QChar c, int attrib = 0) const; /** * @return true if the character @p c is a wordwrap deliminator as specified * in the general keyword section of the xml file. */ bool canBreakAt(QChar c, int attrib = 0) const; /** * */ const QVector &emptyLines(int attribute = 0) const; bool isEmptyLine(const Kate::TextLineData *textline) const; /** * @return true if @p beginAttr and @p endAttr are members of the same * highlight, and there are comment markers of either type in that. */ bool canComment(int startAttr, int endAttr) const; /** * @return the mulitiline comment start marker for the highlight * corresponding to @p attrib. */ QString getCommentStart(int attrib = 0) const; /** * @return the muiltiline comment end marker for the highlight corresponding * to @p attrib. */ QString getCommentEnd(int attrib = 0) const; /** * @return the single comment marker for the highlight corresponding * to @p attrib. */ QString getCommentSingleLineStart(int attrib = 0) const; const QHash &characterEncodings(int attrib = 0) const; /** * @return the single comment marker position for the highlight corresponding * to @p attrib. */ KSyntaxHighlighting::CommentPosition getCommentSingleLinePosition(int attrib = 0) const; bool attributeRequiresSpellchecking(int attr); /** * map attribute to its highlighting file. * the returned string is used as key for m_additionalData. */ QString hlKeyForAttrib(int attrib) const; /** * map attribute to its name * @return name of the attribute */ QString nameForAttrib(int attrib) const; /** * Get attribute for the given cursor position. * @param doc document to use * @param cursor cursor position in the given document * @return attribute valid at that location, default is 0 */ int attributeForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor); /** * Get all keywords valid for the given cursor position. * @param doc document to use * @param cursor cursor position in the given document * @return all keywords valid at that location */ QStringList keywordsForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor); /** * Is spellchecking required for the tiven cursor position? * @param doc document to use * @param cursor cursor position in the given document * @return spell checking required? */ bool spellCheckingRequiredForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor); /** * Get highlighting mode for the given cursor position. * @param doc document to use * @param cursor cursor position in the given document * @return mode valid at that location */ QString higlightingModeForLocation(KTextEditor::DocumentPrivate* doc, const KTextEditor::Cursor& cursor); KTextEditor::DefaultStyle defaultStyleForAttribute(int attr) const; void clearAttributeArrays(); QList attributes(const QString &schema); inline bool noHighlighting() const { return noHl; } /** * Indentation mode, e.g. c-style, .... * @return indentation mode */ const QString &indentation() const { return m_indentation; } void getKateExtendedAttributeList(const QString &schema, QList &, KConfig *cfg = nullptr); void getKateExtendedAttributeListCopy(const QString &schema, QList &, KConfig *cfg = nullptr); const QHash &getCharacterEncodings(int attrib) const; const KatePrefixStore &getCharacterEncodingsPrefixStore(int attrib) const; const QHash &getReverseCharacterEncodings(int attrib) const; int getEncodedCharactersInsertionPolicy(int attrib) const; /** * Returns a list of names of embedded modes. */ QStringList getEmbeddedHighlightingModes() const; private: /** * 'encoding' must not contain new line characters, i.e. '\n' or '\r'! **/ void addCharacterEncoding(const QString &key, const QString &encoding, const QChar &c); /** * create list of attributes from internal formats with properties as defined in syntax file * @return attributes list with attributes as defined in syntax file */ QList attributesForDefinition(); private: QStringList embeddedHighlightingModes; QStringList RegionList; QStringList ContextNameList; bool noHl = true; bool folding = false; QString deliminator; QString iName; - QString iNameTranslated; QString iSection; bool iHidden = false; QString identifier; QString iVersion; QString iStyle; QString iAuthor; QString iLicense; /** * Indentation mode, e.g. c-style, .... */ QString m_indentation; bool m_foldingIndentationSensitive = false; // map schema name to attributes... QHash< QString, QList > m_attributeArrays; /** * This class holds the additional properties for one highlight * definition, such as comment strings, deliminators etc. * * When a highlight is added, a instance of this class is appended to * m_additionalData, and the current position in the attrib and context * arrays are stored in the indexes for look up. You can then use * hlKeyForAttrib to find the relevant instance of this * class from m_additionalData. * * If you need to add a property to a highlight, add it here. */ class HighlightPropertyBag { public: KSyntaxHighlighting::Definition definition; QString singleLineCommentMarker; QString multiLineCommentStart; QString multiLineCommentEnd; KSyntaxHighlighting::CommentPosition singleLineCommentPosition; QVector emptyLines; QHash characterEncodings; KatePrefixStore characterEncodingsPrefixStore; QHash reverseCharacterEncodings; int encodedCharactersInsertionPolicy; }; /** * Highlight properties for each included highlight definition. * The key is the identifier */ QHash m_additionalData; /** * Fast lookup of hl properties, based on attribute index * The key is the starting index in the attribute array for each file. * @see hlKeyForAttrib */ QMap m_hlIndex; const HighlightPropertyBag &additionalData(const QString &name) const { auto it = m_additionalData.constFind(name); if (it == m_additionalData.constEnd()) it = m_additionalData.constFind(iName); Q_ASSERT(it != m_additionalData.constEnd()); return it.value(); } public: inline bool foldingIndentationSensitive() { return m_foldingIndentationSensitive; } inline bool allowsFolding() { return folding; } /** * all formats for the highlighting definition of this highlighting * includes included formats */ std::vector m_formats; /** * mapping of format id => index into m_formats */ std::unordered_map m_formatsIdToIndex; /** * textline to do updates on during doHighlight */ Kate::TextLineData *m_textLineToHighlight = nullptr; /** * check if the folding begin/ends are balanced! * constructed on demand! */ QHash *m_foldingStartToCount = nullptr; }; #endif