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

source code of syntax-highlighting/src/lib/definition.h