File indexing completed on 2024-04-28 07:46:40
0001 /* 0002 SPDX-FileCopyrightText: 2001, 2002 Joseph Wenninger <jowenn@kde.org> 0003 SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org> 0004 SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KATE_HIGHLIGHT_H 0010 #define KATE_HIGHLIGHT_H 0011 0012 #include <KSyntaxHighlighting/AbstractHighlighter> 0013 #include <KSyntaxHighlighting/Definition> 0014 #include <KSyntaxHighlighting/FoldingRegion> 0015 #include <KSyntaxHighlighting/Format> 0016 #include <KSyntaxHighlighting/Theme> 0017 0018 #include <KTextEditor/Attribute> 0019 #include <KTextEditor/Range> 0020 0021 #include "spellcheck/prefixstore.h" 0022 0023 #include <QHash> 0024 #include <QList> 0025 0026 #include <QRegularExpression> 0027 #include <QStringList> 0028 0029 #include <unordered_map> 0030 #include <vector> 0031 0032 namespace KTextEditor 0033 { 0034 class DocumentPrivate; 0035 } 0036 namespace Kate 0037 { 0038 class TextLine; 0039 } 0040 0041 class KateHighlighting : private KSyntaxHighlighting::AbstractHighlighter 0042 { 0043 public: 0044 explicit KateHighlighting(const KSyntaxHighlighting::Definition &def); 0045 0046 /** 0047 * Folding storage 0048 */ 0049 class Folding 0050 { 0051 public: 0052 /** 0053 * Construct folding. 0054 * @param _offset offset of the folding start 0055 * @param _length length of the folding 0056 * @param _foldingRegion folding region, includes if we start or end a region and the id 0057 */ 0058 Folding(int _offset, int _length, KSyntaxHighlighting::FoldingRegion _foldingRegion) 0059 : offset(_offset) 0060 , length(_length) 0061 , foldingRegion(_foldingRegion) 0062 { 0063 } 0064 0065 /** 0066 * offset 0067 */ 0068 int offset = 0; 0069 0070 /** 0071 * length 0072 */ 0073 int length = 0; 0074 0075 /** 0076 * folding region, includes if we start or end a region and the id 0077 */ 0078 KSyntaxHighlighting::FoldingRegion foldingRegion; 0079 }; 0080 0081 /** 0082 * Folding vector used to pass out folding knowledge 0083 */ 0084 typedef std::vector<Folding> Foldings; 0085 0086 protected: 0087 /** 0088 * Reimplement this to apply formats to your output. The provided @p format 0089 * is valid for the interval [@p offset, @p offset + @p length). 0090 * 0091 * @param offset The start column of the interval for which @p format matches 0092 * @param length The length of the matching text 0093 * @param format The Format that applies to the range [offset, offset + length) 0094 * 0095 * @note Make sure to set a valid Definition, otherwise the parameter 0096 * @p format is invalid for the entire line passed to highlightLine() 0097 * (cf. Format::isValid()). 0098 * 0099 * @see applyFolding(), highlightLine() 0100 */ 0101 void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; 0102 0103 /** 0104 * Reimplement this to apply folding to your output. The provided 0105 * FoldingRegion @p region either stars or ends a code folding region in the 0106 * interval [@p offset, @p offset + @p length). 0107 * 0108 * @param offset The start column of the FoldingRegion 0109 * @param length The length of the matching text that starts / ends a 0110 * folding region 0111 * @param region The FoldingRegion that applies to the range [offset, offset + length) 0112 * 0113 * @note The FoldingRegion @p region is @e always either of type 0114 * FoldingRegion::Type::Begin or FoldingRegion::Type::End. 0115 * 0116 * @see applyFormat(), highlightLine(), FoldingRegion 0117 */ 0118 void applyFolding(int offset, int length, KSyntaxHighlighting::FoldingRegion region) override; 0119 0120 public: 0121 /** 0122 * Parse the text and fill in the context array and folding list array 0123 * 0124 * @param prevLine The previous line, the context array is picked up from that if present. 0125 * @param textLine The text line to parse 0126 * @param ctxChanged will be set to reflect if the context changed 0127 * @param foldings foldings vector to fill, if that is wanted 0128 */ 0129 void doHighlight(const Kate::TextLine *prevLine, Kate::TextLine *textLine, bool &ctxChanged, Foldings *foldings = nullptr); 0130 0131 const QString &name() const 0132 { 0133 return iName; 0134 } 0135 const QString §ion() const 0136 { 0137 return iSection; 0138 } 0139 bool hidden() const 0140 { 0141 return iHidden; 0142 } 0143 const QString &style() const 0144 { 0145 return iStyle; 0146 } 0147 const QString &getIdentifier() const 0148 { 0149 return identifier; 0150 } 0151 0152 /** 0153 * @return true if the character @p c is not a deliminator character 0154 * for the corresponding highlight. 0155 */ 0156 bool isInWord(QChar c, int attrib = 0) const; 0157 0158 /** 0159 * @return true if the character @p c is a wordwrap deliminator as specified 0160 * in the general keyword section of the xml file. 0161 */ 0162 bool canBreakAt(QChar c, int attrib = 0) const; 0163 /** 0164 * 0165 */ 0166 const QList<QRegularExpression> &emptyLines(int attribute = 0) const; 0167 0168 bool isEmptyLine(const Kate::TextLine *textline) const; 0169 0170 /** 0171 * @return true if @p beginAttr and @p endAttr are members of the same 0172 * highlight, and there are comment markers of either type in that. 0173 */ 0174 bool canComment(int startAttr, int endAttr) const; 0175 0176 /** 0177 * @return the mulitiline comment start marker for the highlight 0178 * corresponding to @p attrib. 0179 */ 0180 QString getCommentStart(int attrib = 0) const; 0181 0182 /** 0183 * @return the muiltiline comment end marker for the highlight corresponding 0184 * to @p attrib. 0185 */ 0186 QString getCommentEnd(int attrib = 0) const; 0187 0188 /** 0189 * @return the single comment marker for the highlight corresponding 0190 * to @p attrib. 0191 */ 0192 QString getCommentSingleLineStart(int attrib = 0) const; 0193 0194 const QHash<QString, QChar> &characterEncodings(int attrib = 0) const; 0195 0196 /** 0197 * @return the single comment marker position for the highlight corresponding 0198 * to @p attrib. 0199 */ 0200 KSyntaxHighlighting::CommentPosition getCommentSingleLinePosition(int attrib = 0) const; 0201 0202 bool attributeRequiresSpellchecking(int attr); 0203 0204 /** 0205 * map attribute to its name 0206 * @return name of the attribute 0207 */ 0208 QString nameForAttrib(int attrib) const; 0209 0210 /** 0211 * Get attribute for the given cursor position. 0212 * @param doc document to use 0213 * @param cursor cursor position in the given document 0214 * @return attribute valid at that location, default is 0 0215 */ 0216 int attributeForLocation(KTextEditor::DocumentPrivate *doc, const KTextEditor::Cursor cursor); 0217 0218 /** 0219 * Get all keywords valid for the given cursor position. 0220 * @param doc document to use 0221 * @param cursor cursor position in the given document 0222 * @return all keywords valid at that location 0223 */ 0224 QStringList keywordsForLocation(KTextEditor::DocumentPrivate *doc, const KTextEditor::Cursor cursor); 0225 0226 /** 0227 * Is spellchecking required for the tiven cursor position? 0228 * @param doc document to use 0229 * @param cursor cursor position in the given document 0230 * @return spell checking required? 0231 */ 0232 bool spellCheckingRequiredForLocation(KTextEditor::DocumentPrivate *doc, const KTextEditor::Cursor cursor); 0233 0234 /** 0235 * Get highlighting mode for the given cursor position. 0236 * @param doc document to use 0237 * @param cursor cursor position in the given document 0238 * @return mode valid at that location 0239 */ 0240 QString higlightingModeForLocation(KTextEditor::DocumentPrivate *doc, const KTextEditor::Cursor cursor); 0241 0242 KSyntaxHighlighting::Theme::TextStyle defaultStyleForAttribute(int attr) const; 0243 0244 void clearAttributeArrays(); 0245 0246 QList<KTextEditor::Attribute::Ptr> attributes(const QString &schema); 0247 0248 inline bool noHighlighting() const 0249 { 0250 return noHl; 0251 } 0252 0253 /** 0254 * Indentation mode, e.g. c-style, .... 0255 * @return indentation mode 0256 */ 0257 const QString &indentation() const 0258 { 0259 return m_indentation; 0260 } 0261 0262 const QHash<QString, QChar> &getCharacterEncodings(int attrib) const; 0263 const KatePrefixStore &getCharacterEncodingsPrefixStore(int attrib) const; 0264 const QHash<QChar, QString> &getReverseCharacterEncodings(int attrib) const; 0265 0266 /** 0267 * Returns a list of names of embedded modes. 0268 */ 0269 QStringList getEmbeddedHighlightingModes() const; 0270 0271 /** 0272 * create list of attributes from internal formats with properties as defined in syntax file 0273 * @param schema The id of the chosen schema 0274 * @return attributes list with attributes as defined in syntax file 0275 */ 0276 QList<KTextEditor::Attribute::Ptr> attributesForDefinition(const QString &schema) const; 0277 0278 /** 0279 * Retrieve all formats for this highlighting. 0280 * @return all formats for the highlighting definition of this highlighting includes included formats 0281 */ 0282 const std::vector<KSyntaxHighlighting::Format> &formats() const 0283 { 0284 return m_formats; 0285 } 0286 0287 private: 0288 int sanitizeFormatIndex(int attrib) const; 0289 0290 private: 0291 QStringList embeddedHighlightingModes; 0292 0293 bool noHl = true; 0294 bool folding = false; 0295 0296 QString iName; 0297 QString iSection; 0298 bool iHidden = false; 0299 QString identifier; 0300 QString iStyle; 0301 0302 /** 0303 * Indentation mode, e.g. c-style, .... 0304 */ 0305 QString m_indentation; 0306 0307 bool m_foldingIndentationSensitive = false; 0308 0309 // map schema name to attributes... 0310 QHash<QString, QList<KTextEditor::Attribute::Ptr>> m_attributeArrays; 0311 0312 /** 0313 * This class holds the additional properties for one highlight 0314 * definition, such as comment strings, deliminators etc. 0315 */ 0316 class HighlightPropertyBag 0317 { 0318 public: 0319 KSyntaxHighlighting::Definition definition; 0320 QString singleLineCommentMarker; 0321 QString multiLineCommentStart; 0322 QString multiLineCommentEnd; 0323 KSyntaxHighlighting::CommentPosition singleLineCommentPosition; 0324 QList<QRegularExpression> emptyLines; 0325 QHash<QString, QChar> characterEncodings; 0326 KatePrefixStore characterEncodingsPrefixStore; 0327 QHash<QChar, QString> reverseCharacterEncodings; 0328 }; 0329 0330 public: 0331 inline bool foldingIndentationSensitive() 0332 { 0333 return m_foldingIndentationSensitive; 0334 } 0335 inline bool allowsFolding() 0336 { 0337 return folding; 0338 } 0339 0340 /** 0341 * Highlight properties for this definition and each included highlight definition. 0342 */ 0343 std::vector<HighlightPropertyBag> m_properties; 0344 0345 /** 0346 * all formats for the highlighting definition of this highlighting 0347 * includes included formats 0348 */ 0349 std::vector<KSyntaxHighlighting::Format> m_formats; 0350 0351 /** 0352 * for each format, pointer to the matching HighlightPropertyBag in m_properties 0353 */ 0354 std::vector<const HighlightPropertyBag *> m_propertiesForFormat; 0355 0356 /** 0357 * mapping of format id => index into m_formats 0358 */ 0359 std::unordered_map<int, int> m_formatsIdToIndex; 0360 0361 /** 0362 * textline to do updates on during doHighlight 0363 */ 0364 Kate::TextLine *m_textLineToHighlight = nullptr; 0365 0366 /** 0367 * foldings vector to do updates on during doHighlight 0368 * might not be set, then we ignor that 0369 */ 0370 Foldings *m_foldings = nullptr; 0371 0372 /** 0373 * check if the folding begin/ends are balanced! 0374 * updated during doHighlight 0375 */ 0376 QHash<int, int> m_foldingStartToCount; 0377 }; 0378 0379 #endif