1/*
2 SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#ifndef KATE_TEXTLINE_H
8#define KATE_TEXTLINE_H
9
10#include <KSyntaxHighlighting/State>
11
12#include <QList>
13#include <QString>
14
15namespace Kate
16{
17/**
18 * Class representing a single text line.
19 * For efficiency reasons, not only pure text is stored here, but also additional data.
20 */
21class TextLine
22{
23public:
24 /**
25 * Attribute storage
26 */
27 class Attribute
28 {
29 public:
30 /**
31 * Attribute constructor
32 * @param _offset offset
33 * @param _length length
34 * @param _attributeValue attribute value
35 */
36 explicit Attribute(int _offset = 0, int _length = 0, int _attributeValue = 0)
37 : offset(_offset)
38 , length(_length)
39 , attributeValue(_attributeValue)
40 {
41 }
42
43 /**
44 * offset
45 */
46 int offset;
47
48 /**
49 * length
50 */
51 int length;
52
53 /**
54 * attribute value (to encode type of this range)
55 */
56 int attributeValue;
57 };
58
59 /**
60 * Flags of TextLine
61 */
62 enum Flags { flagAutoWrapped = 1, flagFoldingStartAttribute = 2, flagFoldingEndAttribute = 4, flagLineModified = 8, flagLineSavedOnDisk = 16 };
63
64 /**
65 * Construct an empty text line.
66 */
67 TextLine() = default;
68
69 /**
70 * Construct an text line with given text.
71 * @param text text to use for this line
72 */
73 explicit TextLine(const QString &text)
74 : m_text(text)
75 , m_flags(0)
76 {
77 }
78
79 /**
80 * Accessor to the text contained in this line.
81 * @return text of this line as constant reference
82 */
83 const QString &text() const
84 {
85 return m_text;
86 }
87
88 /**
89 * Accessor to the text contained in this line.
90 * @return text of this line as reference
91 */
92 QString &text()
93 {
94 return m_text;
95 }
96
97 /**
98 * Returns the position of the first non-whitespace character
99 * @return position of first non-whitespace char or -1 if there is none
100 */
101 int firstChar() const;
102
103 /**
104 * Returns the position of the last non-whitespace character
105 * @return position of last non-whitespace char or -1 if there is none
106 */
107 int lastChar() const;
108
109 /**
110 * Find the position of the next char that is not a space.
111 * @param pos Column of the character which is examined first.
112 * @return True if the specified or a following character is not a space
113 * Otherwise false.
114 */
115 int nextNonSpaceChar(int pos) const;
116
117 /**
118 * Find the position of the previous char that is not a space.
119 * @param pos Column of the character which is examined first.
120 * @return The position of the first non-whitespace character preceding pos,
121 * or -1 if none is found.
122 */
123 int previousNonSpaceChar(int pos) const;
124
125 /**
126 * Returns the character at the given \e column. If \e column is out of
127 * range, the return value is QChar().
128 * @param column column you want char for
129 * @return char at given column or QChar()
130 */
131 inline QChar at(int column) const
132 {
133 if (column >= 0 && column < m_text.length()) {
134 return m_text.at(i: column);
135 }
136
137 return QChar();
138 }
139
140 inline void markAsModified(bool modified)
141 {
142 if (modified) {
143 m_flags |= flagLineModified;
144 m_flags &= (~flagLineSavedOnDisk);
145 } else {
146 m_flags &= (~flagLineModified);
147 }
148 }
149
150 inline bool markedAsModified() const
151 {
152 return m_flags & flagLineModified;
153 }
154
155 inline void markAsSavedOnDisk(bool savedOnDisk)
156 {
157 if (savedOnDisk) {
158 m_flags |= flagLineSavedOnDisk;
159 m_flags &= (~flagLineModified);
160 } else {
161 m_flags &= (~flagLineSavedOnDisk);
162 }
163 }
164
165 inline bool markedAsSavedOnDisk() const
166 {
167 return m_flags & flagLineSavedOnDisk;
168 }
169
170 /**
171 * Clear folding start and end status.
172 */
173 void clearMarkedAsFoldingStartAndEnd()
174 {
175 m_flags &= ~flagFoldingStartAttribute;
176 m_flags &= ~flagFoldingEndAttribute;
177 }
178
179 /**
180 * Is on this line a folding start per attribute?
181 * @return folding start line per attribute? or not?
182 */
183 bool markedAsFoldingStartAttribute() const
184 {
185 return m_flags & flagFoldingStartAttribute;
186 }
187
188 /**
189 * Mark as folding start line of an attribute based folding.
190 */
191 void markAsFoldingStartAttribute()
192 {
193 m_flags |= flagFoldingStartAttribute;
194 }
195
196 /**
197 * Is on this line a folding end per attribute?
198 * @return folding end line per attribute? or not?
199 */
200 bool markedAsFoldingEndAttribute() const
201 {
202 return m_flags & flagFoldingEndAttribute;
203 }
204
205 /**
206 * Mark as folding end line of an attribute based folding.
207 */
208 void markAsFoldingEndAttribute()
209 {
210 m_flags |= flagFoldingEndAttribute;
211 }
212
213 /**
214 * Returns the line's length.
215 */
216 int length() const
217 {
218 return m_text.length();
219 }
220
221 /**
222 * Returns \e true, if the line was automagically wrapped, otherwise returns
223 * \e false.
224 * @return was this line auto-wrapped?
225 */
226 bool isAutoWrapped() const
227 {
228 return m_flags & flagAutoWrapped;
229 }
230
231 /**
232 * Returns the substring with \e length beginning at the given \e column.
233 * @param column start column of text to return
234 * @param length length of text to return
235 * @return wanted part of text
236 */
237 QString string(int column, int length) const
238 {
239 return m_text.mid(position: column, n: length);
240 }
241
242 /**
243 * Leading whitespace of this line
244 * @return leading whitespace of this line
245 */
246 QString leadingWhitespace() const;
247
248 /**
249 * Returns the indentation depth with each tab expanded into \e tabWidth characters.
250 */
251 int indentDepth(int tabWidth) const;
252
253 /**
254 * Returns the \e column with each tab expanded into \e tabWidth characters.
255 */
256 int toVirtualColumn(int column, int tabWidth) const;
257
258 /**
259 * Returns the "real" column where each tab only counts one character.
260 * The conversion calculates with \e tabWidth characters for each tab.
261 */
262 int fromVirtualColumn(int column, int tabWidth) const;
263
264 /**
265 * Returns the text length with each tab expanded into \e tabWidth characters.
266 */
267 int virtualLength(int tabWidth) const;
268
269 /**
270 * Returns \e true, if \e match equals to the text at position \e column,
271 * otherwise returns \e false.
272 */
273 bool matchesAt(int column, const QString &match) const;
274
275 /**
276 * Returns \e true, if the line starts with \e match, otherwise returns \e false.
277 */
278 bool startsWith(const QString &match) const
279 {
280 return m_text.startsWith(s: match);
281 }
282
283 /**
284 * Returns \e true, if the line ends with \e match, otherwise returns \e false.
285 */
286 bool endsWith(const QString &match) const
287 {
288 return m_text.endsWith(s: match);
289 }
290
291 /**
292 * context stack
293 * @return context stack
294 */
295 const KSyntaxHighlighting::State &highlightingState() const
296 {
297 return m_highlightingState;
298 }
299
300 /**
301 * Sets the syntax highlight context number
302 * @param val new context array
303 */
304 void setHighlightingState(const KSyntaxHighlighting::State &val)
305 {
306 m_highlightingState = val;
307 }
308
309 /**
310 * Add attribute to this line.
311 * @param attribute new attribute to append
312 */
313 void addAttribute(const Attribute &attribute);
314
315 /**
316 * Clear attributes and foldings of this line
317 */
318 void clearAttributes()
319 {
320 m_attributesList.clear();
321 }
322
323 /**
324 * Accessor to attributes
325 * @return attributes of this line
326 */
327 const QList<Attribute> &attributesList() const
328 {
329 return m_attributesList;
330 }
331
332 /**
333 * Gets the attribute at the given position
334 * use KRenderer::attributes to get the KTextAttribute for this.
335 *
336 * @param pos position of attribute requested
337 * @return value of attribute
338 */
339 int attribute(int pos) const;
340
341 /**
342 * set auto-wrapped property
343 * @param wrapped line was wrapped?
344 */
345 void setAutoWrapped(bool wrapped)
346 {
347 if (wrapped) {
348 m_flags = m_flags | flagAutoWrapped;
349 } else {
350 m_flags = m_flags & ~flagAutoWrapped;
351 }
352 }
353
354private:
355 /**
356 * text of this line
357 */
358 QString m_text;
359
360 /**
361 * attributes of this line
362 */
363 QList<Attribute> m_attributesList;
364
365 /**
366 * current highlighting state
367 */
368 KSyntaxHighlighting::State m_highlightingState;
369
370 /**
371 * flags of this line
372 */
373 unsigned int m_flags = 0;
374};
375}
376
377#endif
378

source code of ktexteditor/src/buffer/katetextline.h