File indexing completed on 2024-04-21 03:57:46

0001 /*
0002     SPDX-FileCopyrightText: 2003 Jesse Yurkovich <yurkjes@iit.edu>
0003 
0004     KateVarIndent class:
0005     SPDX-FileCopyrightText: 2004 Anders Lund <anders@alweb.dk>
0006 
0007     Basic support for config page:
0008     SPDX-FileCopyrightText: 2005 Dominik Haumann <dhdev@gmx.de>
0009 
0010     SPDX-License-Identifier: LGPL-2.0-or-later
0011 */
0012 
0013 #ifndef KATE_AUTO_INDENT_H
0014 #define KATE_AUTO_INDENT_H
0015 
0016 #include "kateconfig.h"
0017 
0018 #include <QObject>
0019 
0020 #include <KActionMenu>
0021 
0022 namespace KTextEditor
0023 {
0024 class DocumentPrivate;
0025 class Cursor;
0026 }
0027 class KateIndentScript;
0028 class KateHighlighting;
0029 
0030 /**
0031  * Provides Auto-Indent functionality for katepart.
0032  * This baseclass is a real dummy, does nothing beside remembering the document it belongs too,
0033  * only to have the object around
0034  */
0035 class KateAutoIndent : public QObject
0036 {
0037     Q_OBJECT
0038     /*
0039      * Static methods to list indention modes
0040      */
0041 public:
0042     /**
0043      * List all possible modes by name, i.e. "C Style", "XML Style", ...
0044      * @return list of modes
0045      */
0046     static QStringList listModes();
0047 
0048     /**
0049      * List all possible names, i.e. "cstyle", "xml", ...
0050      * @return list of indenter identifiers
0051      */
0052     static QStringList listIdentifiers();
0053 
0054     /**
0055      * Return the mode name given the mode
0056      * @param mode mode index
0057      * @return name for this mode index
0058      */
0059     static QString modeName(int mode);
0060 
0061     /**
0062      * Return the mode description
0063      * @param mode mode index
0064      * @return mode index
0065      */
0066     static QString modeDescription(int mode);
0067 
0068     /**
0069      * Return the syntax highlighting style required to use this mode
0070      * @param mode mode index
0071      * @return required style, or empty if the mode doesn't require any style
0072      */
0073     static QString modeRequiredStyle(int mode);
0074 
0075     /**
0076      * Maps name -> index
0077      * @param name mode name
0078      * @return mode index
0079      */
0080     static uint modeNumber(const QString &name);
0081 
0082     /**
0083      * count of modes
0084      * @return number of existing modes
0085      */
0086     static int modeCount();
0087 
0088     /*
0089      * Construction + Destruction
0090      */
0091 public:
0092     /**
0093      * Constructor, creates dummy indenter "None"
0094      * \param doc parent document
0095      */
0096     explicit KateAutoIndent(KTextEditor::DocumentPrivate *doc);
0097 
0098     /**
0099      * Destructor
0100      */
0101     ~KateAutoIndent() override;
0102 
0103     /*
0104      * Internal helper for the subclasses and itself
0105      */
0106 private:
0107     /**
0108      * Produces a string with the proper indentation characters for its length.
0109      *
0110      * @param length The length of the indention in characters.
0111      * @param align Length of alignment, ignored if less of equal to length
0112      * @return A QString representing @p length characters (factoring in tabs and spaces)
0113      */
0114     QString tabString(int length, int align) const;
0115 
0116     /**
0117      * Set the indent level of the line.
0118      * \param line line to change indent for
0119      * \param indentDepth set indentation to given number of spaces
0120      * \param align if align is higher than indentDepth, the difference
0121      * represents a number of spaces to be added after the indent
0122      */
0123     bool doIndent(int line, int indentDepth, int align = 0);
0124 
0125     /**
0126      * Change the indent of the specified line by the number of levels
0127      * specified by change. Positive values will indent more, negative values
0128      * will indent less.
0129      * \param line line to change indent for
0130      * \param change change the indentation by given number of spaces
0131      */
0132     bool doIndentRelative(int line, int change);
0133 
0134     /**
0135      * Reuse the indent of the previous line
0136      * \param line line to change indent for
0137      */
0138     void keepIndent(int line);
0139 
0140     /**
0141      * Call the indentation script, this is a helper to be used in userTypedChar and indent
0142      * \param view the view the user work at
0143      * \param position current cursor position, after the inserted char...
0144      * \param typedChar the inserted char, indent will just give the script '\n'
0145      */
0146     void scriptIndent(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor position, QChar typedChar);
0147 
0148     /**
0149      * Return true if the required style for the script is provided by the highlighter.
0150      */
0151     static bool isStyleProvided(const KateIndentScript *script, const KateHighlighting *highlight);
0152 
0153 public:
0154     /**
0155      * Switch indenter
0156      * Nop if already set to given mode
0157      * Otherwise switch to given indenter or to "None" if no suitable found...
0158      * @param name indention mode wanted
0159      */
0160     void setMode(const QString &name);
0161 
0162     /**
0163      * Check if the current highlighting mode provides the style required by the
0164      * current indenter. If not, deactivate the indenter by changing to "normal"
0165      * mode.
0166      */
0167     void checkRequiredStyle();
0168 
0169     /**
0170      * mode name
0171      */
0172     const QString &modeName() const
0173     {
0174         return m_mode;
0175     }
0176 
0177     /**
0178      * Update indenter's configuration (indention width, etc.)
0179      * Is called in the updateConfig() of the document and after creation of the indenter...
0180      */
0181     void updateConfig();
0182 
0183     /**
0184      * Function to provide the common indent/unindent/clean indent functionality to the document
0185      * This should be generic for all indenters, internally it uses the doIndent function.
0186      * This works equal for all indenters, even for "none" or the scripts
0187      * \param range range of text to change indent for
0188      * \param change level of indents to add or remove, zero will still trigger cleaning of indentation
0189      * and removal of extra spaces, if option set
0190      * \return \e true on success, otherwise \e false
0191      */
0192     bool changeIndent(KTextEditor::Range range, int change);
0193 
0194     /**
0195      * The document requests the indenter to indent the given range of existing text.
0196      * This may happen to indent text pasted or to reindent existing text.
0197      * For "none" and "normal" this is a nop, for the scripts, the expression
0198      * will be asked for indent level for each line
0199      * \param view the view the user work at
0200      * \param range the range of text to indent...
0201      */
0202     void indent(KTextEditor::ViewPrivate *view, KTextEditor::Range range);
0203 
0204     /**
0205      * The user typed some char, the indenter can react on this
0206      * '\n' will be send as char if the user wraps a line
0207      * \param view the view the user work at
0208      * \param position current cursor position, after the inserted char...
0209      * \param typedChar the inserted char
0210      */
0211     void userTypedChar(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor position, QChar typedChar);
0212 
0213 public Q_SLOTS:
0214     void reloadScript();
0215 
0216     /*
0217      * needed data
0218      */
0219 private:
0220     KTextEditor::DocumentPrivate *doc; //!< the document the indenter works on
0221     int tabWidth; //!< The number of characters simulated for a tab
0222     int indentWidth; //!< The number of characters used when tabs are replaced by spaces
0223     bool useSpaces; //!< Should we use spaces or tabs to indent
0224     bool keepExtra; //!< Keep indentation that is not on indentation boundaries
0225     QString m_mode;
0226     KateIndentScript *m_script;
0227 };
0228 
0229 /**
0230  * This action provides a list of available indenters and gets plugged
0231  * into the KTextEditor::ViewPrivate's KActionCollection.
0232  */
0233 class KateViewIndentationAction : public KActionMenu
0234 {
0235     Q_OBJECT
0236 
0237 public:
0238     KateViewIndentationAction(KTextEditor::DocumentPrivate *_doc, const QString &text, QObject *parent);
0239 
0240 private:
0241     KTextEditor::DocumentPrivate *doc;
0242     QActionGroup *actionGroup;
0243 
0244 public Q_SLOTS:
0245     void slotAboutToShow();
0246 
0247 private Q_SLOTS:
0248     void setMode(QAction *);
0249 };
0250 
0251 #endif