File indexing completed on 2023-09-24 04:11:28
0001 /* 0002 SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KATE_TEXTLINE_H 0008 #define KATE_TEXTLINE_H 0009 0010 #include <QSharedPointer> 0011 #include <QString> 0012 #include <QVector> 0013 0014 #include <ktexteditor_export.h> 0015 0016 #include <KSyntaxHighlighting/State> 0017 0018 namespace Kate 0019 { 0020 /** 0021 * Class representing a single text line. 0022 * For efficiency reasons, not only pure text is stored here, but also additional data. 0023 * Will be only accessed over shared pointers. 0024 */ 0025 class KTEXTEDITOR_EXPORT TextLineData 0026 { 0027 /** 0028 * TexBlock is a friend class, only one allowed to touch the text content. 0029 */ 0030 friend class TextBlock; 0031 0032 public: 0033 /** 0034 * Attribute storage 0035 */ 0036 class Attribute 0037 { 0038 public: 0039 /** 0040 * Attribute constructor 0041 * @param _offset offset 0042 * @param _length length 0043 * @param _attributeValue attribute value 0044 */ 0045 explicit Attribute(int _offset = 0, int _length = 0, short _attributeValue = 0) 0046 : offset(_offset) 0047 , length(_length) 0048 , attributeValue(_attributeValue) 0049 { 0050 } 0051 0052 /** 0053 * offset 0054 */ 0055 int offset; 0056 0057 /** 0058 * length 0059 */ 0060 int length; 0061 0062 /** 0063 * attribute value (to encode type of this range) 0064 */ 0065 short attributeValue; 0066 }; 0067 0068 /** 0069 * Folding storage 0070 */ 0071 class Folding 0072 { 0073 public: 0074 /** 0075 * Construct folding. 0076 * @param _offset offset of the folding start 0077 * @param _length length of the folding 0078 * @param _foldingValue positive ones start foldings, negative ones end them 0079 */ 0080 Folding(int _offset, int _length, int _foldingValue) 0081 : offset(_offset) 0082 , length(_length) 0083 , foldingValue(_foldingValue) 0084 { 0085 } 0086 0087 /** 0088 * offset 0089 */ 0090 int offset = 0; 0091 0092 /** 0093 * length 0094 */ 0095 int length = 0; 0096 0097 /** 0098 * positive ones start foldings, negative ones end them 0099 */ 0100 int foldingValue = 0; 0101 }; 0102 0103 /** 0104 * Flags of TextLineData 0105 */ 0106 enum Flags { flagAutoWrapped = 1, flagFoldingStartAttribute = 2, flagLineModified = 4, flagLineSavedOnDisk = 8 }; 0107 0108 /** 0109 * Construct an empty text line. 0110 */ 0111 TextLineData() = default; 0112 0113 /** 0114 * Construct an text line with given text. 0115 * @param text text to use for this line 0116 */ 0117 explicit TextLineData(const QString &text) 0118 : m_text(text) 0119 , m_flags(0) 0120 { 0121 } 0122 0123 /** 0124 * Accessor to the text contained in this line. 0125 * @return text of this line as constant reference 0126 */ 0127 const QString &text() const 0128 { 0129 return m_text; 0130 } 0131 0132 /** 0133 * Returns the position of the first non-whitespace character 0134 * @return position of first non-whitespace char or -1 if there is none 0135 */ 0136 int firstChar() const; 0137 0138 /** 0139 * Returns the position of the last non-whitespace character 0140 * @return position of last non-whitespace char or -1 if there is none 0141 */ 0142 int lastChar() const; 0143 0144 /** 0145 * Find the position of the next char that is not a space. 0146 * @param pos Column of the character which is examined first. 0147 * @return True if the specified or a following character is not a space 0148 * Otherwise false. 0149 */ 0150 int nextNonSpaceChar(int pos) const; 0151 0152 /** 0153 * Find the position of the previous char that is not a space. 0154 * @param pos Column of the character which is examined first. 0155 * @return The position of the first non-whitespace character preceding pos, 0156 * or -1 if none is found. 0157 */ 0158 int previousNonSpaceChar(int pos) const; 0159 0160 /** 0161 * Returns the character at the given \e column. If \e column is out of 0162 * range, the return value is QChar(). 0163 * @param column column you want char for 0164 * @return char at given column or QChar() 0165 */ 0166 inline QChar at(int column) const 0167 { 0168 if (column >= 0 && column < m_text.length()) { 0169 return m_text.at(column); 0170 } 0171 0172 return QChar(); 0173 } 0174 0175 inline void markAsModified(bool modified) 0176 { 0177 if (modified) { 0178 m_flags |= flagLineModified; 0179 m_flags &= (~flagLineSavedOnDisk); 0180 } else { 0181 m_flags &= (~flagLineModified); 0182 } 0183 } 0184 0185 inline bool markedAsModified() const 0186 { 0187 return m_flags & flagLineModified; 0188 } 0189 0190 inline void markAsSavedOnDisk(bool savedOnDisk) 0191 { 0192 if (savedOnDisk) { 0193 m_flags |= flagLineSavedOnDisk; 0194 m_flags &= (~flagLineModified); 0195 } else { 0196 m_flags &= (~flagLineSavedOnDisk); 0197 } 0198 } 0199 0200 inline bool markedAsSavedOnDisk() const 0201 { 0202 return m_flags & flagLineSavedOnDisk; 0203 } 0204 0205 /** 0206 * Clear folding start status. 0207 */ 0208 void clearMarkedAsFoldingStart() 0209 { 0210 m_flags &= ~flagFoldingStartAttribute; 0211 } 0212 0213 /** 0214 * Is on this line a folding start per attribute? 0215 * @return folding start line per attribute? or not? 0216 */ 0217 bool markedAsFoldingStartAttribute() const 0218 { 0219 return m_flags & flagFoldingStartAttribute; 0220 } 0221 0222 /** 0223 * Mark as folding start line of an attribute based folding. 0224 */ 0225 void markAsFoldingStartAttribute() 0226 { 0227 m_flags |= flagFoldingStartAttribute; 0228 } 0229 0230 /** 0231 * Returns the line's length. 0232 */ 0233 int length() const 0234 { 0235 return m_text.length(); 0236 } 0237 0238 /** 0239 * Returns \e true, if the line was automagically wrapped, otherwise returns 0240 * \e false. 0241 * @return was this line auto-wrapped? 0242 */ 0243 bool isAutoWrapped() const 0244 { 0245 return m_flags & flagAutoWrapped; 0246 } 0247 0248 /** 0249 * Returns the substring with \e length beginning at the given \e column. 0250 * @param column start column of text to return 0251 * @param length length of text to return 0252 * @return wanted part of text 0253 */ 0254 QString string(int column, int length) const 0255 { 0256 return m_text.mid(column, length); 0257 } 0258 0259 /** 0260 * Leading whitespace of this line 0261 * @return leading whitespace of this line 0262 */ 0263 QString leadingWhitespace() const; 0264 0265 /** 0266 * Returns the indentation depth with each tab expanded into \e tabWidth characters. 0267 */ 0268 int indentDepth(int tabWidth) const; 0269 0270 /** 0271 * Returns the \e column with each tab expanded into \e tabWidth characters. 0272 */ 0273 int toVirtualColumn(int column, int tabWidth) const; 0274 0275 /** 0276 * Returns the "real" column where each tab only counts one character. 0277 * The conversion calculates with \e tabWidth characters for each tab. 0278 */ 0279 int fromVirtualColumn(int column, int tabWidth) const; 0280 0281 /** 0282 * Returns the text length with each tab expanded into \e tabWidth characters. 0283 */ 0284 int virtualLength(int tabWidth) const; 0285 0286 /** 0287 * Returns \e true, if \e match equals to the text at position \e column, 0288 * otherwise returns \e false. 0289 */ 0290 bool matchesAt(int column, const QString &match) const; 0291 0292 /** 0293 * Returns \e true, if the line starts with \e match, otherwise returns \e false. 0294 */ 0295 bool startsWith(const QString &match) const 0296 { 0297 return m_text.startsWith(match); 0298 } 0299 0300 /** 0301 * Returns \e true, if the line ends with \e match, otherwise returns \e false. 0302 */ 0303 bool endsWith(const QString &match) const 0304 { 0305 return m_text.endsWith(match); 0306 } 0307 0308 /** 0309 * context stack 0310 * @return context stack 0311 */ 0312 const KSyntaxHighlighting::State &highlightingState() const 0313 { 0314 return m_highlightingState; 0315 } 0316 0317 /** 0318 * Sets the syntax highlight context number 0319 * @param val new context array 0320 */ 0321 void setHighlightingState(const KSyntaxHighlighting::State &val) 0322 { 0323 m_highlightingState = val; 0324 } 0325 0326 /** 0327 * Add attribute to this line. 0328 * @param attribute new attribute to append 0329 */ 0330 void addAttribute(const Attribute &attribute); 0331 0332 /** 0333 * Clear attributes and foldings of this line 0334 */ 0335 void clearAttributesAndFoldings() 0336 { 0337 m_attributesList.clear(); 0338 m_foldings.clear(); 0339 } 0340 0341 /** 0342 * Accessor to attributes 0343 * @return attributes of this line 0344 */ 0345 const QVector<Attribute> &attributesList() const 0346 { 0347 return m_attributesList; 0348 } 0349 0350 /** 0351 * Accessor to foldings 0352 * @return foldings of this line 0353 */ 0354 const std::vector<Folding> &foldings() const 0355 { 0356 return m_foldings; 0357 } 0358 0359 /** 0360 * Add new folding at end of foldings stored in this line 0361 * @param offset offset of folding start 0362 * @param length length of the string that represents the folding 0363 * @param folding folding to add, positive to open, negative to close 0364 */ 0365 void addFolding(int offset, int length, int folding) 0366 { 0367 m_foldings.emplace_back(offset, length, folding); 0368 } 0369 0370 /** 0371 * Gets the attribute at the given position 0372 * use KRenderer::attributes to get the KTextAttribute for this. 0373 * 0374 * @param pos position of attribute requested 0375 * @return value of attribute 0376 */ 0377 short attribute(int pos) const; 0378 0379 /** 0380 * set auto-wrapped property 0381 * @param wrapped line was wrapped? 0382 */ 0383 void setAutoWrapped(bool wrapped) 0384 { 0385 if (wrapped) { 0386 m_flags = m_flags | flagAutoWrapped; 0387 } else { 0388 m_flags = m_flags & ~flagAutoWrapped; 0389 } 0390 } 0391 0392 private: 0393 /** 0394 * Accessor to the text contained in this line. 0395 * This accessor is private, only the friend class text buffer/block is allowed to access the text read/write. 0396 * @return text of this line 0397 */ 0398 QString &textReadWrite() 0399 { 0400 return m_text; 0401 } 0402 0403 private: 0404 /** 0405 * text of this line 0406 */ 0407 QString m_text; 0408 0409 /** 0410 * attributes of this line 0411 */ 0412 QVector<Attribute> m_attributesList; 0413 0414 /** 0415 * foldings of this line 0416 */ 0417 std::vector<Folding> m_foldings; 0418 0419 /** 0420 * current highlighting state 0421 */ 0422 KSyntaxHighlighting::State m_highlightingState; 0423 0424 /** 0425 * flags of this line 0426 */ 0427 unsigned int m_flags = 0; 0428 }; 0429 0430 /** 0431 * The normal world only accesses the text lines with shared pointers. 0432 */ 0433 typedef std::shared_ptr<TextLineData> TextLine; 0434 } 0435 0436 #endif