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
22namespace KTextEditor
23{
24class DocumentPrivate;
25class Cursor;
26}
27class KateIndentScript;
28class 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 */
35class KateAutoIndent : public QObject
36{
37 Q_OBJECT
38 /*
39 * Static methods to list indention modes
40 */
41public:
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 */
91public:
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 */
106private:
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
153public:
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 */
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(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, 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
213public Q_SLOTS:
214 void reloadScript();
215
216 /*
217 * needed data
218 */
219private:
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 */
233class KateViewIndentationAction : public KActionMenu
234{
235 Q_OBJECT
236
237public:
238 KateViewIndentationAction(KTextEditor::DocumentPrivate *_doc, const QString &text, QObject *parent);
239
240private:
241 KTextEditor::DocumentPrivate *doc;
242 QActionGroup *actionGroup;
243
244public Q_SLOTS:
245 void slotAboutToShow();
246
247private Q_SLOTS:
248 void setMode(QAction *);
249};
250
251#endif
252

source code of ktexteditor/src/utils/kateautoindent.h