File indexing completed on 2024-05-12 15:50:04

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003     SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
0004 
0005     SPDX-License-Identifier: MIT
0006 */
0007 
0008 #ifndef KSYNTAXHIGHLIGHTING_DEFINITION_H
0009 #define KSYNTAXHIGHLIGHTING_DEFINITION_H
0010 
0011 #include "ksyntaxhighlighting_export.h"
0012 
0013 #include <QPair>
0014 #include <QVector>
0015 #include <memory>
0016 #include <qobjectdefs.h>
0017 
0018 QT_BEGIN_NAMESPACE
0019 class QChar;
0020 class QString;
0021 QT_END_NAMESPACE
0022 
0023 namespace KSyntaxHighlighting
0024 {
0025 class Context;
0026 class Format;
0027 class KeywordList;
0028 
0029 class DefinitionData;
0030 
0031 /**
0032  * Defines the insert position when commenting code.
0033  * @since 5.50
0034  * @see Definition::singleLineCommentPosition()
0035  */
0036 enum class CommentPosition {
0037     //! The comment marker is inserted at the beginning of a line at column 0
0038     StartOfLine = 0,
0039     //! The comment marker is inserted after leading whitespaces right befire
0040     //! the first non-whitespace character.
0041     AfterWhitespace
0042 };
0043 
0044 /**
0045  * Represents a syntax definition.
0046  *
0047  * @section def_intro Introduction to Definitions
0048  *
0049  * A Definition is the short term for a syntax highlighting definition. It
0050  * typically is defined in terms of an XML syntax highlighting file, containing
0051  * all information about a particular syntax highlighting. This includes the
0052  * highlighting of keywords, information about code folding regions, and
0053  * indentation preferences.
0054  *
0055  * @section def_info General Header Data
0056  *
0057  * Each Definition contains a non-translated unique name() and a section().
0058  * In addition, for putting this information e.g. into menus, the functions
0059  * translatedName() and translatedSection() are provided. However, if isHidden()
0060  * returns @e true, the Definition should not be visible in the UI. The location
0061  * of the Definition can be obtained through filePath(), which either is the
0062  * location on disk or a path to a compiled-in Qt resource.
0063  *
0064  * The supported files of a Definition are defined by the list of extensions(),
0065  * and additionally by the list of mimeTypes(). Note, that extensions() returns
0066  * wildcards that need to be matched against the filename of the file that
0067  * requires highlighting. If multiple Definition%s match the file, then the one
0068  * with higher priority() wins.
0069  *
0070  * @section def_metadata Advanced Definition Data
0071  *
0072  * Advanced text editors such as Kate require additional information from a
0073  * Definition. For instance, foldingEnabled() defines whether a Definition has
0074  * code folding regions that can be shown in a code folding pane. Or
0075  * singleLineCommentMarker() and multiLineCommentMarker() provide comment
0076  * markers that can be used for commenting/uncommenting code. Similarly,
0077  * formats() returns a list of Format items defined by this Definition (which
0078  * equal the itemDatas of a highlighting definition file). includedDefinitions()
0079  * returns a list of all included Definition%s referenced by this Definition via
0080  * the rule IncludeRules, which is useful for displaying all Format items for
0081  * color configuration in the user interface.
0082  *
0083  * @see Repository
0084  * @since 5.28
0085  */
0086 class KSYNTAXHIGHLIGHTING_EXPORT Definition
0087 {
0088     Q_GADGET
0089     Q_PROPERTY(QString name READ name)
0090     Q_PROPERTY(QString translatedName READ translatedName)
0091     Q_PROPERTY(QString section READ section)
0092     Q_PROPERTY(QString translatedSection READ translatedSection)
0093     Q_PROPERTY(QString author READ author)
0094     Q_PROPERTY(QString license READ license)
0095 public:
0096     /**
0097      * Default constructor, creating an empty (invalid) Definition instance.
0098      * isValid() for this instance returns @e false.
0099      *
0100      * Use the Repository instead to obtain valid instances.
0101      */
0102     Definition();
0103 
0104     /**
0105      * Move constructor.
0106      * This definition takes the Definition data from @p other.
0107      * @note @p other may only be assigned to or destroyed afterwards.
0108      * @since 5.86
0109      */
0110     Definition(Definition &&other) noexcept;
0111 
0112     /**
0113      * Copy constructor.
0114      * Both this definition as well as @p other share the Definition data.
0115      */
0116     Definition(const Definition &other);
0117 
0118     /**
0119      * Destructor.
0120      */
0121     ~Definition();
0122 
0123     /**
0124      * Move assignment operator.
0125      * This definition takes the Definition data from @p other.
0126      * @note @p other may only be assigned to or destroyed afterwards.
0127      * @since 5.86
0128      */
0129     Definition &operator=(Definition &&other) noexcept;
0130 
0131     /**
0132      * Copy assignment operator.
0133      * Both this definition as well as @p rhs share the Definition data.
0134      */
0135     Definition &operator=(const Definition &rhs);
0136 
0137     /**
0138      * Checks two definitions for equality.
0139      */
0140     bool operator==(const Definition &other) const;
0141 
0142     /**
0143      * Checks two definitions for inequality.
0144      */
0145     bool operator!=(const Definition &other) const;
0146 
0147     /**
0148      * @name General Header Data
0149      *
0150      * @{
0151      */
0152 
0153     /**
0154      * Checks whether this object refers to a valid syntax definition.
0155      */
0156     bool isValid() const;
0157 
0158     /**
0159      * Returns the full path to the definition XML file containing
0160      * the syntax definition. Note that this can be a path to QRC content.
0161      */
0162     QString filePath() const;
0163 
0164     /** Name of the syntax.
0165      *  Used for internal references, prefer translatedName() for display.
0166      */
0167     QString name() const;
0168 
0169     /**
0170      * Translated name for display.
0171      */
0172     QString translatedName() const;
0173 
0174     /**
0175      * The group this syntax definition belongs to.
0176      * For display, consider translatedSection().
0177      */
0178     QString section() const;
0179 
0180     /**
0181      * Translated group name for display.
0182      */
0183     QString translatedSection() const;
0184 
0185     /**
0186      * Mime types associated with this syntax definition.
0187      */
0188     QVector<QString> mimeTypes() const;
0189 
0190     /**
0191      * File extensions associated with this syntax definition.
0192      * The returned list contains wildcards.
0193      */
0194     QVector<QString> extensions() const;
0195 
0196     /**
0197      * Returns the definition version.
0198      */
0199     int version() const;
0200 
0201     /**
0202      * Returns the definition priority.
0203      * A Definition with higher priority wins over Definitions with lower priorities.
0204      */
0205     int priority() const;
0206 
0207     /**
0208      * Returns @c true if this is an internal definition that should not be
0209      * displayed to the user.
0210      */
0211     bool isHidden() const;
0212 
0213     /**
0214      * Generalized language style, used for indentation.
0215      */
0216     QString style() const;
0217 
0218     /**
0219      * Indentation style to be used for this syntax.
0220      */
0221     QString indenter() const;
0222 
0223     /**
0224      * Name and email of the author of this syntax definition.
0225      */
0226     QString author() const;
0227 
0228     /**
0229      * License of this syntax definition.
0230      */
0231     QString license() const;
0232 
0233     /**
0234      * @}
0235      *
0236      * @name Advanced Definition Data
0237      */
0238 
0239     /**
0240      * Returns whether the character @p c is a word delimiter.
0241      * A delimiter defines whether a characters is a word boundary. Internally,
0242      * delimiters are used for matching keyword lists. As example, typically the
0243      * dot '.' is a word delimiter. However, if you have a keyword in a keyword
0244      * list that contains a dot, you have to add the dot to the
0245      * @e weakDeliminator attribute of the @e general section in your
0246      * highlighting definition. Similarly, sometimes additional delimiters are
0247      * required, which can be specified in @e additionalDeliminator.
0248      *
0249      * Checking whether a character is a delimiter is useful for instance if
0250      * text is selected with double click. Typically, the whole word should be
0251      * selected in this case. Similarly to the example above, the dot '.'
0252      * usually acts as word delimiter. However, using this function you can
0253      * implement text selection in such a way that keyword lists are correctly
0254      * selected.
0255      *
0256      * @note By default, the list of delimiters contains the following
0257      *       characters: \\t !%&()*+,-./:;<=>?[\\]^{|}~
0258      *
0259      * @since 5.50
0260      * @see isWordWrapDelimiter()
0261      */
0262     bool isWordDelimiter(QChar c) const;
0263 
0264     /**
0265      * Returns whether it is safe to break a line at before the character @c.
0266      * This is useful when wrapping a line e.g. by applying static word wrap.
0267      *
0268      * As example, consider the LaTeX code
0269      * @code
0270      * \command1\command2
0271      * @endcode
0272      * Applying static word wrap could lead to the following code:
0273      * @code
0274      * \command1\
0275      * command2
0276      * @endcode
0277      * command2 without a leading backslash is invalid in LaTeX. If '\\' is set
0278      * as word wrap delimiter, isWordWrapDelimiter('\\') then returns true,
0279      * meaning that it is safe to break the line before @c. The resulting code
0280      * then would be
0281      * @code
0282      * \command1
0283      * \command2
0284      * @endcode
0285      *
0286      * @note By default, the word wrap delimiters are equal to the word
0287      *       delimiters in isWordDelimiter().
0288      *
0289      * @since 5.50
0290      * @see isWordDelimiter()
0291      */
0292     bool isWordWrapDelimiter(QChar c) const;
0293 
0294     /**
0295      * Returns whether the highlighting supports code folding.
0296      * Code folding is supported either if the highlighting defines code folding
0297      * regions or if indentationBasedFoldingEnabled() returns @e true.
0298      * @since 5.50
0299      * @see indentationBasedFoldingEnabled()
0300      */
0301     bool foldingEnabled() const;
0302 
0303     /**
0304      * Returns whether indentation-based folding is enabled.
0305      * An example for indentation-based folding is Python.
0306      * When indentation-based folding is enabled, make sure to also check
0307      * foldingIgnoreList() for lines that should be treated as empty.
0308      *
0309      * @see foldingIgnoreList(), State::indentationBasedFoldingEnabled()
0310      */
0311     bool indentationBasedFoldingEnabled() const;
0312 
0313     /**
0314      * If indentationBasedFoldingEnabled() returns @c true, this function returns
0315      * a list of regular expressions that represent empty lines. That is, all
0316      * lines matching entirely one of the regular expressions should be treated
0317      * as empty lines when calculating the indentation-based folding ranges.
0318      *
0319      * @note This list is only of relevance, if indentationBasedFoldingEnabled()
0320      *       returns @c true.
0321      *
0322      * @see indentationBasedFoldingEnabled()
0323      */
0324     QStringList foldingIgnoreList() const;
0325 
0326     /**
0327      * Returns the section names of keywords.
0328      * @since 5.49
0329      * @see keywordList()
0330      */
0331     QStringList keywordLists() const;
0332 
0333     /**
0334      * Returns the list of keywords for the keyword list @p name.
0335      * @since 5.49
0336      * @see keywordLists(), setKeywordList()
0337      */
0338     QStringList keywordList(const QString &name) const;
0339 
0340     /**
0341      * Set the contents of the keyword list @p name to @p content.
0342      * Only existing keywordLists() can be changed. For non-existent keyword lists,
0343      * false is returned.
0344      *
0345      * Whenever you change a keyword list, make sure to trigger a rehighlight of
0346      * your documents. In case you are using QSyntaxHighlighter via SyntaxHighlighter,
0347      * this can be done by calling SyntaxHighlighter::rehighlight().
0348      *
0349      * @note In general, changing keyword lists via setKeywordList() is discouraged,
0350      *       since if a keyword list name in the syntax highlighting definition
0351      *       file changes, the call setKeywordList() may suddenly fail.
0352      *
0353      * @see keywordList(), keywordLists()
0354      * @since 5.62
0355      */
0356     bool setKeywordList(const QString &name, const QStringList &content);
0357 
0358     /**
0359      * Returns a list of all Format items used by this definition.
0360      * The order of the Format items equals the order of the itemDatas in the xml file.
0361      * @since 5.49
0362      */
0363     QVector<Format> formats() const;
0364 
0365     /**
0366      * Returns a list of Definitions that are referenced with the IncludeRules rule.
0367      * The returned list does not include this Definition. In case no other
0368      * Definitions are referenced via IncludeRules, the returned list is empty.
0369      *
0370      * @since 5.49
0371      */
0372     QVector<Definition> includedDefinitions() const;
0373 
0374     /**
0375      * Returns the marker that starts a single line comment.
0376      * For instance, in C++ the single line comment marker is "//".
0377      * @since 5.50
0378      * @see singleLineCommentPosition();
0379      */
0380     QString singleLineCommentMarker() const;
0381 
0382     /**
0383      * Returns the insert position of the comment marker for sinle line
0384      * comments.
0385      * @since 5.50
0386      * @see singleLineCommentMarker();
0387      */
0388     CommentPosition singleLineCommentPosition() const;
0389 
0390     /**
0391      * Returns the markers that start and end multiline comments.
0392      * For instance, in XML this is defined as "<!--" and "-->".
0393      * @since 5.50
0394      */
0395     QPair<QString, QString> multiLineCommentMarker() const;
0396 
0397     /**
0398      * Returns a list of character/string mapping that can be used for spell
0399      * checking. This is useful for instance when spell checking LaTeX, where
0400      * the string \"{A} represents the character Ä.
0401      * @since 5.50
0402      */
0403     QVector<QPair<QChar, QString>> characterEncodings() const;
0404 
0405     /**
0406      * @}
0407      */
0408 
0409 private:
0410     friend class DefinitionData;
0411     friend class DefinitionRef;
0412     KSYNTAXHIGHLIGHTING_NO_EXPORT explicit Definition(std::shared_ptr<DefinitionData> &&dd);
0413     std::shared_ptr<DefinitionData> d;
0414 };
0415 
0416 }
0417 
0418 QT_BEGIN_NAMESPACE
0419 Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_MOVABLE_TYPE);
0420 QT_END_NAMESPACE
0421 
0422 #endif