1 /* 2 SPDX-FileCopyrightText: 2003 Jesse Yurkovich <yurkjes@iit.edu> 3 4 KateVarIndent class: 5 SPDX-FileCopyrightText: 2004 Anders Lund <anders@alweb.dk> 6 7 Basic support for config page: 8 SPDX-FileCopyrightText: 2005 Dominik Haumann <dhdev@gmx.de> 9 10 SPDX-License-Identifier: LGPL-2.0-or-later 11 */ 12 13 #ifndef KATE_AUTO_INDENT_H 14 #define KATE_AUTO_INDENT_H 15 16 #include "kateconfig.h" 17 18 #include <QObject> 19 20 #include <KActionMenu> 21 22 namespace KTextEditor 23 { 24 class DocumentPrivate; 25 class Cursor; 26 } 27 class KateIndentScript; 28 class KateHighlighting; 29 30 /** 31 * Provides Auto-Indent functionality for katepart. 32 * This baseclass is a real dummy, does nothing beside remembering the document it belongs too, 33 * only to have the object around 34 */ 35 class KateAutoIndent : public QObject 36 { 37 Q_OBJECT 38 /* 39 * Static methods to list indention modes 40 */ 41 public: 42 /** 43 * List all possible modes by name, i.e. "C Style", "XML Style", ... 44 * @return list of modes 45 */ 46 static QStringList listModes(); 47 48 /** 49 * List all possible names, i.e. "cstyle", "xml", ... 50 * @return list of indenter identifiers 51 */ 52 static QStringList listIdentifiers(); 53 54 /** 55 * Return the mode name given the mode 56 * @param mode mode index 57 * @return name for this mode index 58 */ 59 static QString modeName(int mode); 60 61 /** 62 * Return the mode description 63 * @param mode mode index 64 * @return mode index 65 */ 66 static QString modeDescription(int mode); 67 68 /** 69 * Return the syntax highlighting style required to use this mode 70 * @param mode mode index 71 * @return required style, or empty if the mode doesn't require any style 72 */ 73 static QString modeRequiredStyle(int mode); 74 75 /** 76 * Maps name -> index 77 * @param name mode name 78 * @return mode index 79 */ 80 static uint modeNumber(const QString &name); 81 82 /** 83 * count of modes 84 * @return number of existing modes 85 */ 86 static int modeCount(); 87 88 /* 89 * Construction + Destruction 90 */ 91 public: 92 /** 93 * Constructor, creates dummy indenter "None" 94 * \param doc parent document 95 */ 96 explicit KateAutoIndent(KTextEditor::DocumentPrivate *doc); 97 98 /** 99 * Destructor 100 */ 101 ~KateAutoIndent() override; 102 103 /* 104 * Internal helper for the subclasses and itself 105 */ 106 private: 107 /** 108 * Produces a string with the proper indentation characters for its length. 109 * 110 * @param length The length of the indention in characters. 111 * @param align Length of alignment, ignored if less of equal to length 112 * @return A QString representing @p length characters (factoring in tabs and spaces) 113 */ 114 QString tabString(int length, int align) const; 115 116 /** 117 * Set the indent level of the line. 118 * \param line line to change indent for 119 * \param indentDepth set indentation to given number of spaces 120 * \param align if align is higher than indentDepth, the difference 121 * represents a number of spaces to be added after the indent 122 */ 123 bool doIndent(int line, int indentDepth, int align = 0); 124 125 /** 126 * Change the indent of the specified line by the number of levels 127 * specified by change. Positive values will indent more, negative values 128 * will indent less. 129 * \param line line to change indent for 130 * \param change change the indentation by given number of spaces 131 */ 132 bool doIndentRelative(int line, int change); 133 134 /** 135 * Reuse the indent of the previous line 136 * \param line line to change indent for 137 */ 138 void keepIndent(int line); 139 140 /** 141 * Call the indentation script, this is a helper to be used in userTypedChar and indent 142 * \param view the view the user work at 143 * \param position current cursor position, after the inserted char... 144 * \param typedChar the inserted char, indent will just give the script '\n' 145 */ 146 void scriptIndent(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor position, QChar typedChar); 147 148 /** 149 * Return true if the required style for the script is provided by the highlighter. 150 */ 151 static bool isStyleProvided(const KateIndentScript *script, const KateHighlighting *highlight); 152 153 public: 154 /** 155 * Switch indenter 156 * Nop if already set to given mode 157 * Otherwise switch to given indenter or to "None" if no suitable found... 158 * @param name indention mode wanted 159 */ 160 void setMode(const QString &name); 161 162 /** 163 * Check if the current highlighting mode provides the style required by the 164 * current indenter. If not, deactivate the indenter by changing to "normal" 165 * mode. 166 */ 167 void checkRequiredStyle(); 168 169 /** 170 * mode name 171 */ modeName()172 const QString &modeName() const 173 { 174 return m_mode; 175 } 176 177 /** 178 * Update indenter's configuration (indention width, etc.) 179 * Is called in the updateConfig() of the document and after creation of the indenter... 180 */ 181 void updateConfig(); 182 183 /** 184 * Function to provide the common indent/unindent/clean indent functionality to the document 185 * This should be generic for all indenters, internally it uses the doIndent function. 186 * This works equal for all indenters, even for "none" or the scripts 187 * \param range range of text to change indent for 188 * \param change level of indents to add or remove, zero will still trigger cleaning of indentation 189 * and removal of extra spaces, if option set 190 * \return \e true on success, otherwise \e false 191 */ 192 bool changeIndent(const KTextEditor::Range &range, int change); 193 194 /** 195 * The document requests the indenter to indent the given range of existing text. 196 * This may happen to indent text pasted or to reindent existing text. 197 * For "none" and "normal" this is a nop, for the scripts, the expression 198 * will be asked for indent level for each line 199 * \param view the view the user work at 200 * \param range the range of text to indent... 201 */ 202 void indent(KTextEditor::ViewPrivate *view, const KTextEditor::Range &range); 203 204 /** 205 * The user typed some char, the indenter can react on this 206 * '\n' will be send as char if the user wraps a line 207 * \param view the view the user work at 208 * \param position current cursor position, after the inserted char... 209 * \param typedChar the inserted char 210 */ 211 void userTypedChar(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor position, QChar typedChar); 212 213 public Q_SLOTS: 214 void reloadScript(); 215 216 /* 217 * needed data 218 */ 219 private: 220 KTextEditor::DocumentPrivate *doc; //!< the document the indenter works on 221 int tabWidth; //!< The number of characters simulated for a tab 222 int indentWidth; //!< The number of characters used when tabs are replaced by spaces 223 bool useSpaces; //!< Should we use spaces or tabs to indent 224 bool keepExtra; //!< Keep indentation that is not on indentation boundaries 225 QString m_mode; 226 KateIndentScript *m_script; 227 }; 228 229 /** 230 * This action provides a list of available indenters and gets plugged 231 * into the KTextEditor::ViewPrivate's KActionCollection. 232 */ 233 class KateViewIndentationAction : public KActionMenu 234 { 235 Q_OBJECT 236 237 public: 238 KateViewIndentationAction(KTextEditor::DocumentPrivate *_doc, const QString &text, QObject *parent); 239 240 private: 241 KTextEditor::DocumentPrivate *doc; 242 QActionGroup *actionGroup; 243 244 public Q_SLOTS: 245 void slotAboutToShow(); 246 247 private Q_SLOTS: 248 void setMode(QAction *); 249 }; 250 251 #endif 252