1 | /* |
2 | SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> |
3 | |
4 | SPDX-License-Identifier: MIT |
5 | */ |
6 | |
7 | #ifndef KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H |
8 | #define KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H |
9 | |
10 | #include "ksyntaxhighlighting_export.h" |
11 | |
12 | #include <QObject> |
13 | |
14 | #include <memory> |
15 | |
16 | QT_BEGIN_NAMESPACE |
17 | class QString; |
18 | QT_END_NAMESPACE |
19 | |
20 | namespace KSyntaxHighlighting |
21 | { |
22 | class AbstractHighlighterPrivate; |
23 | class Definition; |
24 | class FoldingRegion; |
25 | class Format; |
26 | class State; |
27 | class Theme; |
28 | |
29 | /** |
30 | * Abstract base class for highlighters. |
31 | * |
32 | * @section abshl_intro Introduction |
33 | * |
34 | * The AbstractHighlighter provides an interface to highlight text. |
35 | * |
36 | * The SyntaxHighlighting framework already ships with one implementation, |
37 | * namely the SyntaxHighlighter, which also derives from QSyntaxHighlighter, |
38 | * meaning that it can be used to highlight a QTextDocument or a QML TextEdit. |
39 | * In order to use the SyntaxHighlighter, just call setDefinition() and |
40 | * setTheme(), and the associated documents will automatically be highlighted. |
41 | * |
42 | * However, if you want to use the SyntaxHighlighting framework to implement |
43 | * your own syntax highlighter, you need to sublcass from AbstractHighlighter. |
44 | * |
45 | * @section abshl_impl Implementing your own Syntax Highlighter |
46 | * |
47 | * In order to implement your own syntax highlighter, you need to inherit from |
48 | * AbstractHighlighter. Then, pass each text line that needs to be highlighted |
49 | * in order to highlightLine(). Internally, highlightLine() uses the Definition |
50 | * initially set through setDefinition() and the State of the previous text line |
51 | * to parse and highlight the given text line. For each visual highlighting |
52 | * change, highlightLine() will call applyFormat(). Therefore, reimplement |
53 | * applyFormat() to get notified of the Format that is valid in the range |
54 | * starting at the given offset with the specified length. Similarly, for each |
55 | * text part that starts or ends a code folding region, highlightLine() will |
56 | * call applyFolding(). Therefore, if you are interested in code folding, |
57 | * reimplement applyFolding() to get notified of the starting and ending code |
58 | * folding regions, again specified in the range starting at the given offset |
59 | * with the given length. |
60 | * |
61 | * The Format class itself depends on the current Theme. A theme must be |
62 | * initially set once such that the Format%s instances can be queried for |
63 | * concrete colors. |
64 | * |
65 | * Optionally, you can also reimplement setTheme() and setDefinition() to get |
66 | * notified whenever the Definition or the Theme changes. |
67 | * |
68 | * @see SyntaxHighlighter |
69 | * @since 5.28 |
70 | */ |
71 | class KSYNTAXHIGHLIGHTING_EXPORT AbstractHighlighter |
72 | { |
73 | public: |
74 | virtual ~AbstractHighlighter(); |
75 | |
76 | /** |
77 | * Returns the syntax definition used for highlighting. |
78 | * |
79 | * @see setDefinition() |
80 | */ |
81 | Definition definition() const; |
82 | |
83 | /** |
84 | * Sets the syntax definition used for highlighting. |
85 | * |
86 | * Subclasses can re-implement this method to e.g. trigger |
87 | * re-highlighting or clear internal data structures if needed. |
88 | */ |
89 | virtual void setDefinition(const Definition &def); |
90 | |
91 | /** |
92 | * Returns the currently selected theme for highlighting. |
93 | * |
94 | * @note If no Theme was set through setTheme(), the returned Theme will be |
95 | * invalid, see Theme::isValid(). |
96 | */ |
97 | Theme theme() const; |
98 | |
99 | /** |
100 | * Sets the theme used for highlighting. |
101 | * |
102 | * Subclasses can re-implement this method to e.g. trigger |
103 | * re-highlighing or to do general palette color setup. |
104 | */ |
105 | virtual void setTheme(const Theme &theme); |
106 | |
107 | protected: |
108 | AbstractHighlighter(); |
109 | KSYNTAXHIGHLIGHTING_NO_EXPORT explicit AbstractHighlighter(AbstractHighlighterPrivate *dd); |
110 | |
111 | // TODO KF6: add an optional void* context argument that is passed through |
112 | // to the applyX() calls, so highlighters dealing with some form of line object |
113 | // (such as QSyntaxHighlighter or KTextEditor) can avoid some ugly hacks to have |
114 | // this context available in their applyX methods |
115 | /** |
116 | * Highlight the given line. Call this from your derived class |
117 | * where appropriate. This will result in any number of applyFormat() |
118 | * and applyFolding() calls as a result. |
119 | * @param text A string containing the text of the line to highlight. |
120 | * @param state The highlighting state handle returned by the call |
121 | * to highlightLine() for the previous line. For the very first line, |
122 | * just pass a default constructed State(). |
123 | * @returns The state of the highlighting engine after processing the |
124 | * given line. This needs to passed into highlightLine() for the |
125 | * next line. You can store the state for efficient partial |
126 | * re-highlighting for example during editing. |
127 | * |
128 | * @see applyFormat(), applyFolding() |
129 | */ |
130 | State highlightLine(QStringView text, const State &state); |
131 | |
132 | /** |
133 | * Reimplement this to apply formats to your output. The provided @p format |
134 | * is valid for the interval [@p offset, @p offset + @p length). |
135 | * |
136 | * @param offset The start column of the interval for which @p format matches |
137 | * @param length The length of the matching text |
138 | * @param format The Format that applies to the range [offset, offset + length) |
139 | * |
140 | * @note Make sure to set a valid Definition, otherwise the parameter |
141 | * @p format is invalid for the entire line passed to highlightLine() |
142 | * (cf. Format::isValid()). |
143 | * |
144 | * @see applyFolding(), highlightLine() |
145 | */ |
146 | virtual void applyFormat(int offset, int length, const Format &format) = 0; |
147 | |
148 | /** |
149 | * Reimplement this to apply folding to your output. The provided |
150 | * FoldingRegion @p region either stars or ends a code folding region in the |
151 | * interval [@p offset, @p offset + @p length). |
152 | * |
153 | * @param offset The start column of the FoldingRegion |
154 | * @param length The length of the matching text that starts / ends a |
155 | * folding region |
156 | * @param region The FoldingRegion that applies to the range [offset, offset + length) |
157 | * |
158 | * @note The FoldingRegion @p region is @e always either of type |
159 | * FoldingRegion::Type::Begin or FoldingRegion::Type::End. |
160 | * |
161 | * @see applyFormat(), highlightLine(), FoldingRegion |
162 | */ |
163 | virtual void applyFolding(int offset, int length, FoldingRegion region); |
164 | |
165 | protected: |
166 | AbstractHighlighterPrivate *d_ptr; |
167 | |
168 | private: |
169 | Q_DECLARE_PRIVATE(AbstractHighlighter) |
170 | Q_DISABLE_COPY(AbstractHighlighter) |
171 | }; |
172 | } |
173 | |
174 | QT_BEGIN_NAMESPACE |
175 | Q_DECLARE_INTERFACE(KSyntaxHighlighting::AbstractHighlighter, "org.kde.SyntaxHighlighting.AbstractHighlighter" ) |
176 | QT_END_NAMESPACE |
177 | |
178 | #endif // KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H |
179 | |