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

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #ifndef KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H
0008 #define KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H
0009 
0010 #include "ksyntaxhighlighting_export.h"
0011 
0012 #include <QObject>
0013 
0014 #include <memory>
0015 
0016 QT_BEGIN_NAMESPACE
0017 class QString;
0018 QT_END_NAMESPACE
0019 
0020 namespace KSyntaxHighlighting
0021 {
0022 class AbstractHighlighterPrivate;
0023 class Definition;
0024 class FoldingRegion;
0025 class Format;
0026 class State;
0027 class Theme;
0028 
0029 /**
0030  * Abstract base class for highlighters.
0031  *
0032  * @section abshl_intro Introduction
0033  *
0034  * The AbstractHighlighter provides an interface to highlight text.
0035  *
0036  * The SyntaxHighlighting framework already ships with one implementation,
0037  * namely the SyntaxHighlighter, which also derives from QSyntaxHighlighter,
0038  * meaning that it can be used to highlight a QTextDocument or a QML TextEdit.
0039  * In order to use the SyntaxHighlighter, just call setDefinition() and
0040  * setTheme(), and the associated documents will automatically be highlighted.
0041  *
0042  * However, if you want to use the SyntaxHighlighting framework to implement
0043  * your own syntax highlighter, you need to sublcass from AbstractHighlighter.
0044  *
0045  * @section abshl_impl Implementing your own Syntax Highlighter
0046  *
0047  * In order to implement your own syntax highlighter, you need to inherit from
0048  * AbstractHighlighter. Then, pass each text line that needs to be highlighted
0049  * in order to highlightLine(). Internally, highlightLine() uses the Definition
0050  * initially set through setDefinition() and the State of the previous text line
0051  * to parse and highlight the given text line. For each visual highlighting
0052  * change, highlightLine() will call applyFormat(). Therefore, reimplement
0053  * applyFormat() to get notified of the Format that is valid in the range
0054  * starting at the given offset with the specified length. Similarly, for each
0055  * text part that starts or ends a code folding region, highlightLine() will
0056  * call applyFolding(). Therefore, if you are interested in code folding,
0057  * reimplement applyFolding() to get notified of the starting and ending code
0058  * folding regions, again specified in the range starting at the given offset
0059  * with the given length.
0060  *
0061  * The Format class itself depends on the current Theme. A theme must be
0062  * initially set once such that the Format%s instances can be queried for
0063  * concrete colors.
0064  *
0065  * Optionally, you can also reimplement setTheme() and setDefinition() to get
0066  * notified whenever the Definition or the Theme changes.
0067  *
0068  * @see SyntaxHighlighter
0069  * @since 5.28
0070  */
0071 class KSYNTAXHIGHLIGHTING_EXPORT AbstractHighlighter
0072 {
0073 public:
0074     virtual ~AbstractHighlighter();
0075 
0076     /**
0077      * Returns the syntax definition used for highlighting.
0078      *
0079      * @see setDefinition()
0080      */
0081     Definition definition() const;
0082 
0083     /**
0084      * Sets the syntax definition used for highlighting.
0085      *
0086      * Subclasses can re-implement this method to e.g. trigger
0087      * re-highlighting or clear internal data structures if needed.
0088      */
0089     virtual void setDefinition(const Definition &def);
0090 
0091     /**
0092      * Returns the currently selected theme for highlighting.
0093      *
0094      * @note If no Theme was set through setTheme(), the returned Theme will be
0095      *       invalid, see Theme::isValid().
0096      */
0097     Theme theme() const;
0098 
0099     /**
0100      * Sets the theme used for highlighting.
0101      *
0102      * Subclasses can re-implement this method to e.g. trigger
0103      * re-highlighing or to do general palette color setup.
0104      */
0105     virtual void setTheme(const Theme &theme);
0106 
0107 protected:
0108     AbstractHighlighter();
0109     KSYNTAXHIGHLIGHTING_NO_EXPORT explicit AbstractHighlighter(AbstractHighlighterPrivate *dd);
0110 
0111 #if KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(5, 87)
0112     /**
0113      * @copydoc highlightLine(QStringView,const State&)
0114      * @deprecated since 5.87, use highlightLine(QStringView, const State&) instead.
0115      */
0116     // no deprecation warning, as removal of this will automatically "port" the using code
0117     State highlightLine(const QString &text, const State &state);
0118 #endif
0119 
0120     // TODO KF6: add an optional void* context argument that is passed through
0121     // to the applyX() calls, so highlighters dealing with some form of line object
0122     // (such as QSyntaxHighlighter or KTextEditor) can avoid some ugly hacks to have
0123     // this context available in their applyX methods
0124     /**
0125      * Highlight the given line. Call this from your derived class
0126      * where appropriate. This will result in any number of applyFormat()
0127      * and applyFolding() calls as a result.
0128      * @param text A string containing the text of the line to highlight.
0129      * @param state The highlighting state handle returned by the call
0130      *        to highlightLine() for the previous line. For the very first line,
0131      *        just pass a default constructed State().
0132      * @returns The state of the highlighting engine after processing the
0133      *        given line. This needs to passed into highlightLine() for the
0134      *        next line. You can store the state for efficient partial
0135      *        re-highlighting for example during editing.
0136      *
0137      * @see applyFormat(), applyFolding()
0138      */
0139     State highlightLine(QStringView text, const State &state);
0140 
0141     /**
0142      * Reimplement this to apply formats to your output. The provided @p format
0143      * is valid for the interval [@p offset, @p offset + @p length).
0144      *
0145      * @param offset The start column of the interval for which @p format matches
0146      * @param length The length of the matching text
0147      * @param format The Format that applies to the range [offset, offset + length)
0148      *
0149      * @note Make sure to set a valid Definition, otherwise the parameter
0150      *       @p format is invalid for the entire line passed to highlightLine()
0151      *       (cf. Format::isValid()).
0152      *
0153      * @see applyFolding(), highlightLine()
0154      */
0155     virtual void applyFormat(int offset, int length, const Format &format) = 0;
0156 
0157     /**
0158      * Reimplement this to apply folding to your output. The provided
0159      * FoldingRegion @p region either stars or ends a code folding region in the
0160      * interval [@p offset, @p offset + @p length).
0161      *
0162      * @param offset The start column of the FoldingRegion
0163      * @param length The length of the matching text that starts / ends a
0164      *       folding region
0165      * @param region The FoldingRegion that applies to the range [offset, offset + length)
0166      *
0167      * @note The FoldingRegion @p region is @e always either of type
0168      *       FoldingRegion::Type::Begin or FoldingRegion::Type::End.
0169      *
0170      * @see applyFormat(), highlightLine(), FoldingRegion
0171      */
0172     virtual void applyFolding(int offset, int length, FoldingRegion region);
0173 
0174 protected:
0175     AbstractHighlighterPrivate *d_ptr;
0176 
0177 private:
0178     Q_DECLARE_PRIVATE(AbstractHighlighter)
0179     Q_DISABLE_COPY(AbstractHighlighter)
0180 };
0181 }
0182 
0183 QT_BEGIN_NAMESPACE
0184 Q_DECLARE_INTERFACE(KSyntaxHighlighting::AbstractHighlighter, "org.kde.SyntaxHighlighting.AbstractHighlighter")
0185 QT_END_NAMESPACE
0186 
0187 #endif // KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H