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 "katetextbuffer.h"
12 
13 #include <ktexteditor_export.h>
14 
15 #include <QObject>
16 
17 class KateLineInfo;
18 namespace KTextEditor
19 {
20 class DocumentPrivate;
21 }
22 class KateHighlighting;
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 : 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      */
editChanged()68     inline bool editChanged() const
69     {
70         return editingChangedBuffer();
71     }
72 
73     /**
74      * dirty lines start
75      * @return start line
76      */
editTagStart()77     inline int editTagStart() const
78     {
79         return editingMinimalLineChanged();
80     }
81 
82     /**
83      * dirty lines end
84      * @return end line
85      */
editTagEnd()86     inline int editTagEnd() const
87     {
88         return editingMaximalLineChanged();
89     }
90 
91     /**
92      * line inserted/removed?
93      * @return line inserted/removed?
94      */
editTagFrom()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      */
brokenEncoding()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      */
tooLongLinesWrapped()127     bool tooLongLinesWrapped() const
128     {
129         return m_tooLongLinesWrapped;
130     }
131 
longestLineLoaded()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      */
plainLine(int lineno)158     inline Kate::TextLine plainLine(int lineno)
159     {
160         if (lineno < 0 || lineno >= lines()) {
161             return Kate::TextLine();
162         }
163 
164         return line(lineno);
165     }
166 
lineLength(int lineno)167     int lineLength(int lineno) const
168     {
169         if (lineno < 0 || lineno >= lines()) {
170             return -1;
171         }
172 
173         return Kate::TextBuffer::lineLength(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      * Return the total number of lines in the buffer.
187      */
count()188     inline int count() const
189     {
190         return lines();
191     }
192 
193     /**
194      * Unwrap given line.
195      * @param line line to unwrap
196      */
197     void unwrapLine(int line) override;
198 
199     /**
200      * Wrap line at given cursor position.
201      * @param position line/column as cursor where to wrap
202      */
203     void wrapLine(const KTextEditor::Cursor position) override;
204 
205 public:
tabWidth()206     inline int tabWidth() const
207     {
208         return m_tabWidth;
209     }
210 
211 public:
212     void setTabWidth(int w);
213 
214     /**
215      * Use @p highlight for highlighting
216      *
217      * @p highlight may be 0 in which case highlighting
218      * will be disabled.
219      */
220     void setHighlight(int hlMode);
221 
highlight()222     KateHighlighting *highlight()
223     {
224         return m_highlight;
225     }
226 
227     /**
228      * Invalidate highlighting of whole buffer.
229      */
230     void invalidateHighlighting();
231 
232     /**
233      * For a given line, compute the folding range that starts there
234      * to be used to fold e.g. from the icon border
235      * @param startLine start line
236      * @return folding range starting at the given line or invalid range when
237      *         there is no folding start or @p startLine is not valid
238      */
239     KTextEditor::Range computeFoldingRangeForStartLine(int startLine);
240 
241 private:
242     /**
243      * Highlight information needs to be updated.
244      *
245      * @param from first line in range
246      * @param to last line in range
247      * @param invalidate should the rehighlighted lines be tagged?
248      */
249     void doHighlight(int from, int to, bool invalidate);
250 
251 Q_SIGNALS:
252     /**
253      * Emitted when the highlighting of a certain range has
254      * changed.
255      */
256     void tagLines(KTextEditor::LineRange lineRange);
257     void respellCheckBlock(int start, int end);
258 
259 private:
260     /**
261      * document we belong to
262      */
263     KTextEditor::DocumentPrivate *const m_doc;
264 
265     /**
266      * file loaded with encoding problems?
267      */
268     bool m_brokenEncoding;
269 
270     /**
271      * too long lines wrapped on load?
272      */
273     bool m_tooLongLinesWrapped;
274 
275     /**
276      * length of the longest line loaded
277      */
278     int m_longestLineLoaded;
279 
280     /**
281      * current highlighting mode or 0
282      */
283     KateHighlighting *m_highlight;
284 
285     // for the scrapty indent sensitive langs
286     int m_tabWidth;
287 
288     /**
289      * last line with valid highlighting
290      */
291     int m_lineHighlighted;
292 
293     /**
294      * number of dynamic contexts causing a full invalidation
295      */
296     int m_maxDynamicContexts;
297 };
298 
299 #endif
300