forked from andreikop/qutepart-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
qutepart.h
514 lines (416 loc) · 16 KB
/
qutepart.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
/**
* \file qutepart.h
* \brief Main Qutepart header. Contains whole API.
*
* See also hl_factory.h if you need only syntax highlighter.
*/
#pragma once
#include <memory>
#include <QColor>
#include <QDebug>
#include <QPlainTextEdit>
#include <QSharedPointer>
#include <QSyntaxHighlighter>
namespace Qutepart {
/**
* \enum IndentAlg
* \brief Indentation algorithm.
* Returned by ::chooseLanguage().
*
* Passed to ::Qutepart::Qutepart::setIndentAlgorithm()
*/
enum IndentAlg {
/// Do not apply any algorithm. Default text editor behaviour.
INDENT_ALG_NONE = 0,
/// Insert to new lines indentation equal to previous line.
INDENT_ALG_NORMAL,
/// Algorithm for C-style languages where curly brackets are used to mark code blocks. C, C++,
/// PHP, Java, JS, ...
INDENT_ALG_CSTYLE,
/// Lisp indentation.
INDENT_ALG_LISP,
/// Scheme indentation.
INDENT_ALG_SCHEME,
/// XML indentation.
INDENT_ALG_XML,
/// Python indentation.
INDENT_ALG_PYTHON,
/// Ruby indentation.
INDENT_ALG_RUBY,
};
/**
* Programming language ID and related information.
*
* This structure is returned by ::chooseLanguage()
*/
struct LangInfo {
public:
LangInfo() = default;
inline LangInfo(const QString &id, const QStringList &names, IndentAlg indentAlg)
: id(id), names(names), indentAlg(indentAlg) {}
/// Check if the struct is valid (filled with meaningfull info)
inline bool isValid() const { return !id.isEmpty(); }
/// Internal unique language ID. Pass to ::Qutepart::Qutepart::setHighlighter()
QString id;
/// User readable language names
QStringList names;
/// Indenter algorithm for the language. Pass to ::Qutepart::Qutepart::setIndentAlgorithm()
IndentAlg indentAlg;
};
/**
* Choose language by available parameters.
* First parameters have higher priority.
* Returns `QString()` if can not detect the language.
*
* Fill as much parameters as you can. Set `QString()` for unknown parameters.
*
* \param mimeType The file MIME type. i.e. ``text/html``
* \param languageName The language name as written in the <a
* href="https://github.com/andreikop/qutepart-cpp/blob/master/src/hl/language_db_generated.cpp">language
* DB</a> \param sourceFilePath The path to the file which is edited. \param firstLine Contents of
* the first line of the file which is going to be edited.
*/
LangInfo chooseLanguage(const QString &mimeType = QString(),
const QString &languageName = QString(),
const QString &sourceFilePath = QString(),
const QString &firstLine = QString());
class Indenter;
class BracketHighlighter;
class LineNumberArea;
class MarkArea;
class Minimap;
class Completer;
class Theme;
/**
* Document line.
*
* A convenience class to programmatically edit the document
*/
class Line {
public:
Line(const QTextBlock &block);
/// Get line text
QString text() const;
/// Get line length not including EOL symbol
int length() const;
/// Remove the line from the document
void remove(int pos, int count);
private:
QTextBlock block_;
};
/** STL-compatible iterator implementation to work with document lines (blocks)
*
* Returns ::Qutepart::Line objects
*/
class LineIterator {
public:
LineIterator(const QTextBlock &block);
bool operator!=(const LineIterator &other);
bool operator==(const LineIterator &other);
LineIterator operator++();
Line operator*();
private:
QTextBlock block_;
};
/** A convenience class which provides high level interface to work with
* the document lines.
*
* Returned by ::Qutepart::Qutepart::lines()
*
* `Lines` is a performance-effective document representation.
* Getting whole text of document with `QPlainTextEdit::toPlainText()`` requires a lot of memory
* allocations and copying. This class accesses the text line by line without copying whole
* document.
*/
class Lines {
public:
Lines(QTextDocument *document);
/// Line count in the document
int count() const;
/// Get line by index.
Line at(int index) const;
/// `begin()` method for STL iteration support
LineIterator begin();
/// `end()` method for STL iteration support
LineIterator end();
/// First line of the document
Line first() const;
/// Last line of the document
Line last() const;
/// Append line to the end of the document.
void append(const QString &lineText);
// Remove and return line at number. Return the text wo \n
QString popAt(int lineNumber);
// Insert at given line number one or more lines.
// The text shoud be \n-separated. \n at end is interpreted as empty line.
void insertAt(int lineNumber, const QString &text);
private:
QTextDocument *document_;
};
/** Cursor position
*
* A convenience class, which is more friendly than low level QTextCursor API.
*
* Returned by ::Qutepart::Qutepart::textCursorPosition()
*/
struct TextCursorPosition {
TextCursorPosition(int line_, int column_) : line(line_), column(column_) {}
friend bool operator==(const TextCursorPosition &a, const TextCursorPosition &b) {
return a.line == b.line && a.column == b.column;
}
/// Current line. First line is 0.
int line;
/// Current column. First column is 0.
int column;
};
/**
Code editor widget
*/
class Qutepart : public QPlainTextEdit {
Q_OBJECT
public:
Qutepart(QWidget *parent = nullptr, const QString &text = QString());
// Not copyable or movable
Qutepart(const Qutepart &) = delete;
Qutepart &operator=(const Qutepart &) = delete;
Qutepart(Qutepart &&) = delete;
Qutepart &operator=(Qutepart &&) = delete;
virtual ~Qutepart();
/// High-performance access to document lines. See ::Qutepart::Lines
Lines lines() const;
/**
* Set highlighter. Use `Qutepart::chooseLanguage()` to choose the language
*
* \param languageId Language name. See Qutepart::LangInfo::id.
*/
void setHighlighter(const QString &languageId);
/**
* Removes the current syntax highlighter, all text will be drawen using default colors.
*/
void removeHighlighter();
/**
* Set indenter algorithm. Use `Qutepart::chooseLanguage()` to choose the algorithm.
*
* \param indentAlg Algorithm name. See Qutepart::LangInfo::indentAlg.
*/
void setIndentAlgorithm(IndentAlg indentAlg);
void setDefaultColors();
void setTheme(const Theme *newTheme);
const Theme *getTheme() const { return theme; }
/// Convenience method to get text cursor position.
TextCursorPosition textCursorPosition() const;
/// Go to specified line and column. First line and first column have index 0
void goTo(int line, int column = 0);
/// Go to text position specified by ::Qutepart::TextCursorPosition
void goTo(const TextCursorPosition &pos);
/// Indent current line using current smart indentation algorithm
void autoIndentCurrentLine();
/// Use Tabs instead of spaces for indentation
bool indentUseTabs() const;
/// Use Tabs instead of spaces for indentation
void setIndentUseTabs(bool);
/// Indentation width. Count of inserted spaces, Tab symbol display width
int indentWidth() const;
/// Indentation width. Count of inserted spaces, Tab symbol display width
void setIndentWidth(int);
/// Visual option. Draw indentation symbols.
bool drawIndentations() const;
/// Visual option. Draw indentation symbols.
void setDrawIndentations(bool);
/// Visual option. Draw any whitespace symbol.
bool drawAnyWhitespace() const;
/// Visual option. Draw any whitespace symbol.
void setDrawAnyWhitespace(bool);
/// Visual option. Draw incorrent indentation. i.e. at end of line or Tab after spaces.
bool drawIncorrectIndentation() const;
/// Visual option. Draw incorrent indentation. i.e. at end of line or Tab after spaces.
void setDrawIncorrectIndentation(bool);
/// Visual option. Draw solid line length marker (usually after column 80)
bool drawSolidEdge() const;
/// Visual option. Draw solid line length marker (usually after column 80)
void setDrawSolidEdge(bool);
/// Visual option. Column on which line lendth marker is drawn.
int lineLengthEdge() const;
/// Visual option. Column on which line lendth marker is drawn.
void setLineLengthEdge(int);
/// Visual option. Color of line lendth edge.
QColor lineLengthEdgeColor() const;
/// Visual option. Color of line lendth edge.
void setLineLengthEdgeColor(QColor);
/// Visual option. Color of current line highlighting. `QColor()` if disabled.
QColor currentLineColor() const;
/// Visual option. Color of current line highlighting. `QColor()` if disabled.
void setCurrentLineColor(QColor);
bool bracketHighlightingEnabled() const;
void setBracketHighlightingEnabled(bool value);
bool lineNumbersVisible() const;
void setLineNumbersVisible(bool value);
bool minimapVisible() const;
void setMinimapVisible(bool value);
/// To to logical, or phisical end/start of line.
bool getSmartHomeEnd() const;
/// To to logical, or phisical end/start of line.
void setSmartHomeEnd(bool value);
/// When cursor moves, select the current word under cursor in all the document
void setMarkCurrentWord(bool enable);
bool getMarkCurrentWord() const;
/// When pressinv '[' - should we enclose the selection with '[]'? Supports for quotes etc
void setBracketAutoEnclose(bool enable);
bool getBracketAutoEnclose() const;
// Autocompletion
void setCompletionEnabled(bool);
bool completionEnabled() const;
void setCompletionThreshold(int);
int completionThreshold() const;
// Actions
inline QAction *increaseIndentAction() const { return increaseIndentAction_; }
inline QAction *decreaseIndentAction() const { return decreaseIndentAction_; }
inline QAction *toggleBookmarkAction() const { return toggleBookmarkAction_; }
inline QAction *prevBookmarkAction() const { return prevBookmarkAction_; }
inline QAction *nextBookmarkAction() const { return nextBookmarkAction_; }
inline QAction *invokeCompletionAction() const { return invokeCompletionAction_; }
inline QAction *scrollDownAction() const { return scrollDownAction_; }
inline QAction *scrollUpAction() const { return scrollUpAction_; }
inline QAction *duplicateSelectionAction() const { return duplicateSelectionAction_; }
inline QAction *moveLineUpAction() const { return moveLineUpAction_; }
inline QAction *moveLineDownAction() const { return moveLineDownAction_; }
inline QAction *deleteLineAction() const { return deleteLineAction_; }
inline QAction *cutLineAction() const { return cutLineAction_; }
inline QAction *copyLineAction() const { return copyLineAction_; }
inline QAction *pasteLineAction() const { return pasteLineAction_; }
inline QAction *insertLineAboveAction() const { return insertLineAboveAction_; }
inline QAction *insertLineBelowAction() const { return insertLineBelowAction_; }
inline QAction *joinLinesAction() const { return joinLinesAction_; }
/// Zoom In the document by scaling fonts
inline QAction *zoomInAction() const { return zoomInAction_; }
/// Zoom Out the document by scaling fonts
inline QAction *zoomOutAction() const { return zoomOutAction_; }
/// Comment the current line, or selected text
inline QAction *toggleCommentAction() const { return toggleActionComment_; }
/// Find matching bracket for this position
inline QAction *findMatchingBracketAction() const { return findMatchingBracketAction_; }
// Convenience functions
void resetSelection();
protected:
void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void changeEvent(QEvent *event) override;
private:
void initActions();
QAction *createAction(const QString &text, QKeySequence shortcut, const QString &iconFileName,
std::function<void()> const &handler);
QList<QTextEdit::ExtraSelection> highlightText(const QString &word, bool fullWords);
// whitespace and edge drawing
void drawIndentMarkersAndEdge(const QRect &rect);
void drawIndentMarker(QPainter *painter, QTextBlock block, int column);
void drawEdgeLine(QPainter *painter, QTextBlock block, int edgePos);
void drawWhiteSpace(QPainter *painter, QTextBlock block, int column, QChar ch);
int effectiveEdgePos(const QString &text);
void chooseVisibleWhitespace(const QString &text, QVector<bool> *result);
QTextEdit::ExtraSelection currentLineExtraSelection() const;
void resizeEvent(QResizeEvent *event) override;
void updateTabStopWidth();
QRect cursorRect(QTextBlock block, int column, int offset) const;
void gotoBlock(const QTextBlock &block);
void indentBlock(const QTextBlock &block, bool withSpace) const;
void unIndentBlock(const QTextBlock &block, bool withSpace) const;
void changeSelectedBlocksIndent(bool increase, bool withSpace);
void scrollByOffset(int offset);
void duplicateSelection();
void moveSelectedLines(int offsetLines);
void deleteLine();
void cutLine();
void copyLine();
void pasteLine();
void insertLineAbove();
void insertLineBelow();
void toggleComment();
private slots:
void updateViewport();
void updateExtraSelections();
void onShortcutHome(QTextCursor::MoveMode moveMode);
void onShortcutEnd(QTextCursor::MoveMode moveMode);
void onShortcutToggleBookmark();
void onShortcutPrevBookmark();
void onShortcutNextBookmark();
void joinNextLine(QTextCursor &cursor);
void onShortcutJoinLines();
private:
const Theme *theme = nullptr;
QTimer *currentWordTimer;
QString lastWordUnderCursor;
QSharedPointer<QSyntaxHighlighter> highlighter_;
std::unique_ptr<Indenter> indenter_;
std::unique_ptr<BracketHighlighter> bracketHighlighter_;
std::unique_ptr<LineNumberArea> lineNumberArea_;
std::unique_ptr<MarkArea> markArea_;
Minimap* miniMap_ = nullptr;
std::unique_ptr<Completer> completer_;
bool drawIndentations_;
bool drawAnyWhitespace_;
bool drawIncorrectIndentation_;
bool drawSolidEdge_;
bool enableSmartHomeEnd_;
int lineLengthEdge_;
QColor lineNumberColor;
QColor currentLineNumberColor;
QColor lineLengthEdgeColor_;
QColor currentLineColor_;
QColor indentColor_;
QColor whitespaceColor_;
bool brakcetsQutoEnclose;
bool completionEnabled_;
int completionThreshold_;
int viewportMarginStart_;
int viewportMarginEnd_;
// private, not API
QAction *homeAction_;
QAction *homeSelectAction_;
QAction *endAction_;
QAction *endSelectAction_;
QAction *increaseIndentAction_;
QAction *decreaseIndentAction_;
QAction *toggleBookmarkAction_;
QAction *prevBookmarkAction_;
QAction *nextBookmarkAction_;
QAction *invokeCompletionAction_;
QAction *scrollDownAction_;
QAction *scrollUpAction_;
QAction *duplicateSelectionAction_;
QAction *moveLineUpAction_;
QAction *moveLineDownAction_;
QAction *deleteLineAction_;
QAction *cutLineAction_;
QAction *copyLineAction_;
QAction *pasteLineAction_;
QAction *insertLineAboveAction_;
QAction *insertLineBelowAction_;
QAction *joinLinesAction_;
QAction *zoomInAction_;
QAction *zoomOutAction_;
QAction *toggleActionComment_;
QAction *findMatchingBracketAction_;
friend class LineNumberArea;
friend class MarkArea;
public:
int MaxLinesForWordHighligher = 100000;
};
/**
A helper class which allows to group edit operations on Qutepart using RAII approach.
Operations are undo-redoble as a single change.
Example:
{
AtomicEditOperation op(qutepart);
qutepart.lines().insertAt(3, "line three");
qutepart.lines().insertAt(4, "line four");
}
*/
class AtomicEditOperation {
public:
AtomicEditOperation(Qutepart *qutepart);
~AtomicEditOperation();
private:
Qutepart *qutepart_;
};
} // namespace Qutepart