1 | /* |
2 | SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> |
3 | SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com> |
4 | |
5 | SPDX-License-Identifier: MIT |
6 | */ |
7 | |
8 | #ifndef KSYNTAXHIGHLIGHTING_DEFINITION_H |
9 | #define KSYNTAXHIGHLIGHTING_DEFINITION_H |
10 | |
11 | #include "ksyntaxhighlighting_export.h" |
12 | |
13 | #include <QList> |
14 | #include <QPair> |
15 | #include <QString> |
16 | #include <memory> |
17 | #include <qobjectdefs.h> |
18 | |
19 | namespace KSyntaxHighlighting |
20 | { |
21 | class Context; |
22 | class Format; |
23 | class KeywordList; |
24 | |
25 | class DefinitionData; |
26 | |
27 | /** |
28 | * Defines the insert position when commenting code. |
29 | * @since 5.50 |
30 | * @see Definition::singleLineCommentPosition() |
31 | */ |
32 | enum class { |
33 | //! The comment marker is inserted at the beginning of a line at column 0 |
34 | = 0, |
35 | //! The comment marker is inserted after leading whitespaces right befire |
36 | //! the first non-whitespace character. |
37 | |
38 | }; |
39 | |
40 | /** |
41 | * Represents a syntax definition. |
42 | * |
43 | * @section def_intro Introduction to Definitions |
44 | * |
45 | * A Definition is the short term for a syntax highlighting definition. It |
46 | * typically is defined in terms of an XML syntax highlighting file, containing |
47 | * all information about a particular syntax highlighting. This includes the |
48 | * highlighting of keywords, information about code folding regions, and |
49 | * indentation preferences. |
50 | * |
51 | * @section def_info General Header Data |
52 | * |
53 | * Each Definition contains a non-translated unique name() and a section(). |
54 | * In addition, for putting this information e.g. into menus, the functions |
55 | * translatedName() and translatedSection() are provided. However, if isHidden() |
56 | * returns @e true, the Definition should not be visible in the UI. The location |
57 | * of the Definition can be obtained through filePath(), which either is the |
58 | * location on disk or a path to a compiled-in Qt resource. |
59 | * |
60 | * The supported files of a Definition are defined by the list of extensions(), |
61 | * and additionally by the list of mimeTypes(). Note, that extensions() returns |
62 | * wildcards that need to be matched against the filename of the file that |
63 | * requires highlighting. If multiple Definition%s match the file, then the one |
64 | * with higher priority() wins. |
65 | * |
66 | * @section def_metadata Advanced Definition Data |
67 | * |
68 | * Advanced text editors such as Kate require additional information from a |
69 | * Definition. For instance, foldingEnabled() defines whether a Definition has |
70 | * code folding regions that can be shown in a code folding pane. Or |
71 | * singleLineCommentMarker() and multiLineCommentMarker() provide comment |
72 | * markers that can be used for commenting/uncommenting code. Similarly, |
73 | * formats() returns a list of Format items defined by this Definition (which |
74 | * equal the itemDatas of a highlighting definition file). includedDefinitions() |
75 | * returns a list of all included Definition%s referenced by this Definition via |
76 | * the rule IncludeRules, which is useful for displaying all Format items for |
77 | * color configuration in the user interface. |
78 | * |
79 | * @see Repository |
80 | * @since 5.28 |
81 | */ |
82 | class KSYNTAXHIGHLIGHTING_EXPORT Definition |
83 | { |
84 | Q_GADGET |
85 | Q_PROPERTY(QString name READ name) |
86 | Q_PROPERTY(QString translatedName READ translatedName) |
87 | Q_PROPERTY(QString section READ section) |
88 | Q_PROPERTY(QString translatedSection READ translatedSection) |
89 | Q_PROPERTY(QString author READ author) |
90 | Q_PROPERTY(QString license READ license) |
91 | public: |
92 | /** |
93 | * Default constructor, creating an empty (invalid) Definition instance. |
94 | * isValid() for this instance returns @e false. |
95 | * |
96 | * Use the Repository instead to obtain valid instances. |
97 | */ |
98 | Definition(); |
99 | |
100 | /** |
101 | * Move constructor. |
102 | * This definition takes the Definition data from @p other. |
103 | * @note @p other may only be assigned to or destroyed afterwards. |
104 | * @since 5.86 |
105 | */ |
106 | Definition(Definition &&other) noexcept; |
107 | |
108 | /** |
109 | * Copy constructor. |
110 | * Both this definition as well as @p other share the Definition data. |
111 | */ |
112 | Definition(const Definition &other); |
113 | |
114 | /** |
115 | * Destructor. |
116 | */ |
117 | ~Definition(); |
118 | |
119 | /** |
120 | * Move assignment operator. |
121 | * This definition takes the Definition data from @p other. |
122 | * @note @p other may only be assigned to or destroyed afterwards. |
123 | * @since 5.86 |
124 | */ |
125 | Definition &operator=(Definition &&other) noexcept; |
126 | |
127 | /** |
128 | * Copy assignment operator. |
129 | * Both this definition as well as @p rhs share the Definition data. |
130 | */ |
131 | Definition &operator=(const Definition &rhs); |
132 | |
133 | /** |
134 | * Checks two definitions for equality. |
135 | */ |
136 | bool operator==(const Definition &other) const; |
137 | |
138 | /** |
139 | * Checks two definitions for inequality. |
140 | */ |
141 | bool operator!=(const Definition &other) const; |
142 | |
143 | /** |
144 | * @name General Header Data |
145 | * |
146 | * @{ |
147 | */ |
148 | |
149 | /** |
150 | * Checks whether this object refers to a valid syntax definition. |
151 | */ |
152 | bool isValid() const; |
153 | |
154 | /** |
155 | * Returns the full path to the definition XML file containing |
156 | * the syntax definition. Note that this can be a path to QRC content. |
157 | */ |
158 | QString filePath() const; |
159 | |
160 | /** Name of the syntax. |
161 | * Used for internal references, prefer translatedName() for display. |
162 | */ |
163 | QString name() const; |
164 | |
165 | /** |
166 | * Alternate names the syntax can be referred to by. |
167 | * |
168 | * @since 6.1 |
169 | */ |
170 | QStringList alternativeNames() const; |
171 | |
172 | /** |
173 | * Translated name for display. |
174 | */ |
175 | QString translatedName() const; |
176 | |
177 | /** |
178 | * The group this syntax definition belongs to. |
179 | * For display, consider translatedSection(). |
180 | */ |
181 | QString section() const; |
182 | |
183 | /** |
184 | * Translated group name for display. |
185 | */ |
186 | QString translatedSection() const; |
187 | |
188 | /** |
189 | * Mime types associated with this syntax definition. |
190 | */ |
191 | QList<QString> mimeTypes() const; |
192 | |
193 | /** |
194 | * File extensions associated with this syntax definition. |
195 | * The returned list contains wildcards. |
196 | */ |
197 | QList<QString> extensions() const; |
198 | |
199 | /** |
200 | * Returns the definition version. |
201 | */ |
202 | int version() const; |
203 | |
204 | /** |
205 | * Returns the definition priority. |
206 | * A Definition with higher priority wins over Definitions with lower priorities. |
207 | */ |
208 | int priority() const; |
209 | |
210 | /** |
211 | * Returns @c true if this is an internal definition that should not be |
212 | * displayed to the user. |
213 | */ |
214 | bool isHidden() const; |
215 | |
216 | /** |
217 | * Generalized language style, used for indentation. |
218 | */ |
219 | QString style() const; |
220 | |
221 | /** |
222 | * Indentation style to be used for this syntax. |
223 | */ |
224 | QString indenter() const; |
225 | |
226 | /** |
227 | * Name and email of the author of this syntax definition. |
228 | */ |
229 | QString author() const; |
230 | |
231 | /** |
232 | * License of this syntax definition. |
233 | */ |
234 | QString license() const; |
235 | |
236 | /** |
237 | * @} |
238 | * |
239 | * @name Advanced Definition Data |
240 | */ |
241 | |
242 | /** |
243 | * Returns whether the character @p c is a word delimiter. |
244 | * A delimiter defines whether a characters is a word boundary. Internally, |
245 | * delimiters are used for matching keyword lists. As example, typically the |
246 | * dot '.' is a word delimiter. However, if you have a keyword in a keyword |
247 | * list that contains a dot, you have to add the dot to the |
248 | * @e weakDeliminator attribute of the @e general section in your |
249 | * highlighting definition. Similarly, sometimes additional delimiters are |
250 | * required, which can be specified in @e additionalDeliminator. |
251 | * |
252 | * Checking whether a character is a delimiter is useful for instance if |
253 | * text is selected with double click. Typically, the whole word should be |
254 | * selected in this case. Similarly to the example above, the dot '.' |
255 | * usually acts as word delimiter. However, using this function you can |
256 | * implement text selection in such a way that keyword lists are correctly |
257 | * selected. |
258 | * |
259 | * @note By default, the list of delimiters contains the following |
260 | * characters: \\t !%&()*+,-./:;<=>?[\\]^{|}~ |
261 | * |
262 | * @since 5.50 |
263 | * @see isWordWrapDelimiter() |
264 | */ |
265 | bool isWordDelimiter(QChar c) const; |
266 | |
267 | /** |
268 | * Returns whether it is safe to break a line at before the character @c. |
269 | * This is useful when wrapping a line e.g. by applying static word wrap. |
270 | * |
271 | * As example, consider the LaTeX code |
272 | * @code |
273 | * \command1\command2 |
274 | * @endcode |
275 | * Applying static word wrap could lead to the following code: |
276 | * @code |
277 | * \command1\ |
278 | * command2 |
279 | * @endcode |
280 | * command2 without a leading backslash is invalid in LaTeX. If '\\' is set |
281 | * as word wrap delimiter, isWordWrapDelimiter('\\') then returns true, |
282 | * meaning that it is safe to break the line before @c. The resulting code |
283 | * then would be |
284 | * @code |
285 | * \command1 |
286 | * \command2 |
287 | * @endcode |
288 | * |
289 | * @note By default, the word wrap delimiters are equal to the word |
290 | * delimiters in isWordDelimiter(). |
291 | * |
292 | * @since 5.50 |
293 | * @see isWordDelimiter() |
294 | */ |
295 | bool isWordWrapDelimiter(QChar c) const; |
296 | |
297 | /** |
298 | * Returns whether the highlighting supports code folding. |
299 | * Code folding is supported either if the highlighting defines code folding |
300 | * regions or if indentationBasedFoldingEnabled() returns @e true. |
301 | * @since 5.50 |
302 | * @see indentationBasedFoldingEnabled() |
303 | */ |
304 | bool foldingEnabled() const; |
305 | |
306 | /** |
307 | * Returns whether indentation-based folding is enabled. |
308 | * An example for indentation-based folding is Python. |
309 | * When indentation-based folding is enabled, make sure to also check |
310 | * foldingIgnoreList() for lines that should be treated as empty. |
311 | * |
312 | * @see foldingIgnoreList(), State::indentationBasedFoldingEnabled() |
313 | */ |
314 | bool indentationBasedFoldingEnabled() const; |
315 | |
316 | /** |
317 | * If indentationBasedFoldingEnabled() returns @c true, this function returns |
318 | * a list of regular expressions that represent empty lines. That is, all |
319 | * lines matching entirely one of the regular expressions should be treated |
320 | * as empty lines when calculating the indentation-based folding ranges. |
321 | * |
322 | * @note This list is only of relevance, if indentationBasedFoldingEnabled() |
323 | * returns @c true. |
324 | * |
325 | * @see indentationBasedFoldingEnabled() |
326 | */ |
327 | QStringList foldingIgnoreList() const; |
328 | |
329 | /** |
330 | * Returns the section names of keywords. |
331 | * @since 5.49 |
332 | * @see keywordList() |
333 | */ |
334 | QStringList keywordLists() const; |
335 | |
336 | /** |
337 | * Returns the list of keywords for the keyword list @p name. |
338 | * @since 5.49 |
339 | * @see keywordLists(), setKeywordList() |
340 | */ |
341 | QStringList keywordList(const QString &name) const; |
342 | |
343 | /** |
344 | * Set the contents of the keyword list @p name to @p content. |
345 | * Only existing keywordLists() can be changed. For non-existent keyword lists, |
346 | * false is returned. |
347 | * |
348 | * Whenever you change a keyword list, make sure to trigger a rehighlight of |
349 | * your documents. In case you are using QSyntaxHighlighter via SyntaxHighlighter, |
350 | * this can be done by calling SyntaxHighlighter::rehighlight(). |
351 | * |
352 | * @note In general, changing keyword lists via setKeywordList() is discouraged, |
353 | * since if a keyword list name in the syntax highlighting definition |
354 | * file changes, the call setKeywordList() may suddenly fail. |
355 | * |
356 | * @see keywordList(), keywordLists() |
357 | * @since 5.62 |
358 | */ |
359 | bool setKeywordList(const QString &name, const QStringList &content); |
360 | |
361 | /** |
362 | * Returns a list of all Format items used by this definition. |
363 | * The order of the Format items equals the order of the itemDatas in the xml file. |
364 | * @since 5.49 |
365 | */ |
366 | QList<Format> formats() const; |
367 | |
368 | /** |
369 | * Returns a list of Definitions that are referenced with the IncludeRules rule. |
370 | * The returned list does not include this Definition. In case no other |
371 | * Definitions are referenced via IncludeRules, the returned list is empty. |
372 | * |
373 | * @since 5.49 |
374 | */ |
375 | QList<Definition> includedDefinitions() const; |
376 | |
377 | /** |
378 | * Returns the marker that starts a single line comment. |
379 | * For instance, in C++ the single line comment marker is "//". |
380 | * @since 5.50 |
381 | * @see singleLineCommentPosition(); |
382 | */ |
383 | QString () const; |
384 | |
385 | /** |
386 | * Returns the insert position of the comment marker for sinle line |
387 | * comments. |
388 | * @since 5.50 |
389 | * @see singleLineCommentMarker(); |
390 | */ |
391 | CommentPosition () const; |
392 | |
393 | /** |
394 | * Returns the markers that start and end multiline comments. |
395 | * For instance, in XML this is defined as "<!--" and "-->". |
396 | * @since 5.50 |
397 | */ |
398 | QPair<QString, QString> () const; |
399 | |
400 | /** |
401 | * Returns a list of character/string mapping that can be used for spell |
402 | * checking. This is useful for instance when spell checking LaTeX, where |
403 | * the string \"{A} represents the character Ä. |
404 | * @since 5.50 |
405 | */ |
406 | QList<QPair<QChar, QString>> characterEncodings() const; |
407 | |
408 | /** |
409 | * @} |
410 | */ |
411 | |
412 | private: |
413 | friend class DefinitionData; |
414 | friend class DefinitionRef; |
415 | KSYNTAXHIGHLIGHTING_NO_EXPORT explicit Definition(std::shared_ptr<DefinitionData> &&dd); |
416 | std::shared_ptr<DefinitionData> d; |
417 | }; |
418 | |
419 | } |
420 | |
421 | QT_BEGIN_NAMESPACE |
422 | Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_RELOCATABLE_TYPE); |
423 | QT_END_NAMESPACE |
424 | |
425 | #endif |
426 | |