File indexing completed on 2024-05-12 04:02:18

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