1 | /* |
2 | SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org> |
3 | SPDX-FileCopyrightText: 2002-2004 Christoph Cullmann <cullmann@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KATE_BUFFER_H |
9 | #define KATE_BUFFER_H |
10 | |
11 | #include "katehighlight.h" |
12 | #include "katetextbuffer.h" |
13 | |
14 | #include <ktexteditor_export.h> |
15 | |
16 | #include <QObject> |
17 | |
18 | class KateLineInfo; |
19 | namespace KTextEditor |
20 | { |
21 | class DocumentPrivate; |
22 | } |
23 | |
24 | /** |
25 | * The KateBuffer class maintains a collections of lines. |
26 | * |
27 | * @author Waldo Bastian <bastian@kde.org> |
28 | * @author Christoph Cullmann <cullmann@kde.org> |
29 | */ |
30 | class KTEXTEDITOR_EXPORT KateBuffer final : public Kate::TextBuffer |
31 | { |
32 | Q_OBJECT |
33 | |
34 | public: |
35 | /** |
36 | * Create an empty buffer. |
37 | * @param doc parent document |
38 | */ |
39 | explicit KateBuffer(KTextEditor::DocumentPrivate *doc); |
40 | |
41 | /** |
42 | * Goodbye buffer |
43 | */ |
44 | ~KateBuffer() override; |
45 | |
46 | public: |
47 | /** |
48 | * start some editing action |
49 | */ |
50 | void editStart(); |
51 | |
52 | /** |
53 | * finish some editing action |
54 | */ |
55 | void editEnd(); |
56 | |
57 | /** |
58 | * Update highlighting of the lines in |
59 | * last edit transaction |
60 | */ |
61 | void updateHighlighting(); |
62 | |
63 | /** |
64 | * were there changes in the current running |
65 | * editing session? |
66 | * @return changes done? |
67 | */ |
68 | inline bool editChanged() const |
69 | { |
70 | return editingChangedBuffer(); |
71 | } |
72 | |
73 | /** |
74 | * dirty lines start |
75 | * @return start line |
76 | */ |
77 | inline int editTagStart() const |
78 | { |
79 | return editingMinimalLineChanged(); |
80 | } |
81 | |
82 | /** |
83 | * dirty lines end |
84 | * @return end line |
85 | */ |
86 | inline int editTagEnd() const |
87 | { |
88 | return editingMaximalLineChanged(); |
89 | } |
90 | |
91 | /** |
92 | * line inserted/removed? |
93 | * @return line inserted/removed? |
94 | */ |
95 | inline bool editTagFrom() const |
96 | { |
97 | return editingChangedNumberOfLines() != 0; |
98 | } |
99 | |
100 | public: |
101 | /** |
102 | * Clear the buffer. |
103 | */ |
104 | void clear() override; |
105 | |
106 | /** |
107 | * Open a file, use the given filename |
108 | * @param m_file filename to open |
109 | * @param enforceTextCodec enforce to use only the set text codec |
110 | * @return success |
111 | */ |
112 | bool openFile(const QString &m_file, bool enforceTextCodec); |
113 | |
114 | /** |
115 | * Did encoding errors occur on load? |
116 | * @return encoding errors occurred on load? |
117 | */ |
118 | bool brokenEncoding() const |
119 | { |
120 | return m_brokenEncoding; |
121 | } |
122 | |
123 | /** |
124 | * Too long lines wrapped on load? |
125 | * @return too long lines wrapped on load? |
126 | */ |
127 | bool tooLongLinesWrapped() const |
128 | { |
129 | return m_tooLongLinesWrapped; |
130 | } |
131 | |
132 | int longestLineLoaded() const |
133 | { |
134 | return m_longestLineLoaded; |
135 | } |
136 | |
137 | /** |
138 | * Can the current codec handle all chars |
139 | * @return chars can be encoded |
140 | */ |
141 | bool canEncode(); |
142 | |
143 | /** |
144 | * Save the buffer to a file, use the given filename + codec + end of line chars (internal use of qtextstream) |
145 | * @param m_file filename to save to |
146 | * @return success |
147 | */ |
148 | bool saveFile(const QString &m_file); |
149 | |
150 | public: |
151 | /** |
152 | * Return line @p lineno. |
153 | * Highlighting of returned line might be out-dated, which may be sufficient |
154 | * for pure text manipulation functions, like search/replace. |
155 | * If you require highlighting to be up to date, call @ref ensureHighlighted |
156 | * prior to this method. |
157 | */ |
158 | inline Kate::TextLine plainLine(int lineno) |
159 | { |
160 | if (lineno < 0 || lineno >= lines()) { |
161 | return Kate::TextLine(); |
162 | } |
163 | |
164 | return line(line: lineno); |
165 | } |
166 | |
167 | int lineLength(int lineno) const |
168 | { |
169 | if (lineno < 0 || lineno >= lines()) { |
170 | return -1; |
171 | } |
172 | |
173 | return Kate::TextBuffer::lineLength(line: lineno); |
174 | } |
175 | |
176 | /** |
177 | * Update highlighting of given line @p line, if needed. |
178 | * If @p line is already highlighted, this function does nothing. |
179 | * If @p line is not highlighted, all lines up to line + lookAhead |
180 | * are highlighted. |
181 | * @param lookAhead also highlight these following lines |
182 | */ |
183 | void ensureHighlighted(int line, int lookAhead = 64); |
184 | |
185 | /** |
186 | * Unwrap given line. |
187 | * @param line line to unwrap |
188 | */ |
189 | void unwrapLine(int line) override; |
190 | |
191 | /** |
192 | * Wrap line at given cursor position. |
193 | * @param position line/column as cursor where to wrap |
194 | */ |
195 | void wrapLine(const KTextEditor::Cursor position) override; |
196 | |
197 | public: |
198 | inline int tabWidth() const |
199 | { |
200 | return m_tabWidth; |
201 | } |
202 | |
203 | public: |
204 | void setTabWidth(int w); |
205 | |
206 | /** |
207 | * Use @p highlight for highlighting |
208 | * |
209 | * @p highlight may be 0 in which case highlighting |
210 | * will be disabled. |
211 | */ |
212 | void setHighlight(int hlMode); |
213 | |
214 | KateHighlighting *highlight() |
215 | { |
216 | return m_highlight; |
217 | } |
218 | |
219 | /** |
220 | * Invalidate highlighting of whole buffer. |
221 | */ |
222 | void invalidateHighlighting(); |
223 | |
224 | /** |
225 | * Compute folding vector for the given line, will internally do a re-highlighting. |
226 | * @param line line to get folding vector for |
227 | */ |
228 | KateHighlighting::Foldings computeFoldings(int line); |
229 | |
230 | /** |
231 | * For a given line, compute if folding starts here. |
232 | * @param startLine start line |
233 | * @return does folding start here and is it indentation based? |
234 | */ |
235 | std::pair<bool, bool> isFoldingStartingOnLine(int startLine); |
236 | |
237 | /** |
238 | * For a given line, compute the folding range that starts there |
239 | * to be used to fold e.g. from the icon border |
240 | * @param startLine start line |
241 | * @return folding range starting at the given line or invalid range when |
242 | * there is no folding start or @p startLine is not valid |
243 | */ |
244 | KTextEditor::Range computeFoldingRangeForStartLine(int startLine); |
245 | |
246 | private: |
247 | /** |
248 | * Highlight information needs to be updated. |
249 | * |
250 | * @param from first line in range |
251 | * @param to last line in range |
252 | * @param invalidate should the rehighlighted lines be tagged? |
253 | */ |
254 | KTEXTEDITOR_NO_EXPORT |
255 | void doHighlight(int from, int to, bool invalidate); |
256 | |
257 | Q_SIGNALS: |
258 | /** |
259 | * Emitted when the highlighting of a certain range has |
260 | * changed. |
261 | */ |
262 | void tagLines(KTextEditor::LineRange lineRange); |
263 | void respellCheckBlock(int start, int end); |
264 | |
265 | private: |
266 | /** |
267 | * document we belong to |
268 | */ |
269 | KTextEditor::DocumentPrivate *const m_doc; |
270 | |
271 | /** |
272 | * file loaded with encoding problems? |
273 | */ |
274 | bool m_brokenEncoding; |
275 | |
276 | /** |
277 | * too long lines wrapped on load? |
278 | */ |
279 | bool m_tooLongLinesWrapped; |
280 | |
281 | /** |
282 | * length of the longest line loaded |
283 | */ |
284 | int m_longestLineLoaded; |
285 | |
286 | /** |
287 | * current highlighting mode or 0 |
288 | */ |
289 | KateHighlighting *m_highlight; |
290 | |
291 | // for the scrapty indent sensitive langs |
292 | int m_tabWidth; |
293 | |
294 | /** |
295 | * last line with valid highlighting |
296 | */ |
297 | int m_lineHighlighted; |
298 | }; |
299 | |
300 | #endif |
301 | |