Skip to content

Commit 0b535ef

Browse files
authored
feat: settings for each parenthesis and tab jump out (#19)
* feat: add per parentheses setting and tab jump out 1. Now you can configure each parenthesis of whether to auto-complete, auto-remove and tab jump out, or even add or delete parentheses. 2. Now you can use tab to jump out of a close parenthesis, which is optional for each parenthesis. * chore: fix example * fix: add default constructor for QCodeEditor::Parentheses * refactor: use "Parenthesis" for the struct
1 parent a67aa01 commit 0b535ef

File tree

4 files changed

+68
-86
lines changed

4 files changed

+68
-86
lines changed

example/include/MainWindow.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ class MainWindow : public QMainWindow
5656

5757
QCheckBox* m_readOnlyCheckBox;
5858
QCheckBox* m_wordWrapCheckBox;
59-
QCheckBox* m_parenthesesEnabledCheckbox;
6059
QCheckBox* m_tabReplaceEnabledCheckbox;
6160
QSpinBox* m_tabReplaceNumberSpinbox;
6261
QCheckBox* m_autoIndentationCheckbox;

example/src/MainWindow.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ MainWindow::MainWindow(QWidget* parent) :
3434
m_styleCombobox(nullptr),
3535
m_readOnlyCheckBox(nullptr),
3636
m_wordWrapCheckBox(nullptr),
37-
m_parenthesesEnabledCheckbox(nullptr),
3837
m_tabReplaceEnabledCheckbox(nullptr),
3938
m_tabReplaceNumberSpinbox(nullptr),
4039
m_autoIndentationCheckbox(nullptr),
@@ -147,7 +146,6 @@ void MainWindow::createWidgets()
147146

148147
m_readOnlyCheckBox = new QCheckBox("Read Only", setupGroup);
149148
m_wordWrapCheckBox = new QCheckBox("Word Wrap", setupGroup);
150-
m_parenthesesEnabledCheckbox = new QCheckBox("Auto Parentheses", setupGroup);
151149
m_tabReplaceEnabledCheckbox = new QCheckBox("Tab Replace", setupGroup);
152150
m_tabReplaceNumberSpinbox = new QSpinBox(setupGroup);
153151
m_autoIndentationCheckbox = new QCheckBox("Auto Indentation", setupGroup);
@@ -177,7 +175,6 @@ void MainWindow::createWidgets()
177175
m_setupLayout->addWidget(m_styleCombobox);
178176
m_setupLayout->addWidget(m_readOnlyCheckBox);
179177
m_setupLayout->addWidget(m_wordWrapCheckBox);
180-
m_setupLayout->addWidget(m_parenthesesEnabledCheckbox);
181178
m_setupLayout->addWidget(m_tabReplaceEnabledCheckbox);
182179
m_setupLayout->addWidget(m_tabReplaceNumberSpinbox);
183180
m_setupLayout->addWidget(m_autoIndentationCheckbox);
@@ -237,7 +234,6 @@ void MainWindow::setupWidgets()
237234
m_styleCombobox->addItems(list);
238235
list.clear();
239236

240-
m_parenthesesEnabledCheckbox->setChecked(m_codeEditor->autoParentheses());
241237
m_tabReplaceEnabledCheckbox->setChecked(m_codeEditor->tabReplace());
242238
m_tabReplaceNumberSpinbox->setValue(m_codeEditor->tabReplaceSize());
243239
m_tabReplaceNumberSpinbox->setSuffix(tr(" spaces"));
@@ -300,13 +296,6 @@ void MainWindow::performConnections()
300296
}
301297
);
302298

303-
connect(
304-
m_parenthesesEnabledCheckbox,
305-
&QCheckBox::stateChanged,
306-
[this](int state)
307-
{ m_codeEditor->setAutoParentheses(state != 0); }
308-
);
309-
310299
connect(
311300
m_tabReplaceEnabledCheckbox,
312301
&QCheckBox::stateChanged,

include/internal/QCodeEditor.hpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ class QCodeEditor : public QTextEdit
2929
Error
3030
};
3131

32+
struct Parenthesis
33+
{
34+
QChar left, right;
35+
bool autoComplete, autoRemove, tabJumpOut;
36+
37+
Parenthesis(const QChar &l = '(', const QChar &r = ')', bool complete = true, bool remove = true,
38+
bool jumpout = true)
39+
: left(l), right(r), autoComplete(complete), autoRemove(remove), tabJumpOut(jumpout)
40+
{
41+
}
42+
};
43+
3244
/**
3345
* @brief Constructor.
3446
* @param widget Pointer to parent widget.
@@ -58,17 +70,6 @@ class QCodeEditor : public QTextEdit
5870
*/
5971
void setSyntaxStyle(QSyntaxStyle *style);
6072

61-
/**
62-
* @brief Method setting auto parentheses enabled.
63-
*/
64-
void setAutoParentheses(bool enabled);
65-
66-
/**
67-
* @brief Method for getting is auto parentheses enabled.
68-
* Default value: true
69-
*/
70-
bool autoParentheses() const;
71-
7273
/**
7374
* @brief Method for setting tab replacing
7475
* enabled.
@@ -101,9 +102,9 @@ class QCodeEditor : public QTextEdit
101102
void setAutoIndentation(bool enabled);
102103

103104
/**
104-
* @brief Method for setting auto remove parenthesis enabled.
105+
* @brief Method for setting the parentheses.
105106
*/
106-
void setAutoRemoveParentheses(bool enabled);
107+
void setParentheses(const QVector<Parenthesis> &parentheses);
107108

108109
/**
109110
* @brief Method for setting extra bottom margin enabled.
@@ -370,13 +371,13 @@ class QCodeEditor : public QTextEdit
370371
QCompleter *m_completer;
371372

372373
bool m_autoIndentation;
373-
bool m_autoParentheses;
374374
bool m_replaceTab;
375-
bool m_autoRemoveParentheses;
376375
bool m_extraBottomMargin;
377376
QString m_tabReplace;
378377

379378
QList<QTextEdit::ExtraSelection> extra1, extra2, extra_squiggles;
380379

381380
QVector<SquiggleInformation> m_squiggler;
381+
382+
QVector<Parenthesis> m_parentheses;
382383
};

src/internal/QCodeEditor.cpp

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@
2424
#include <QTextStream>
2525
#include <QToolTip>
2626

27-
static QVector<QPair<QString, QString>> parentheses = {{"(", ")"}, {"{", "}"}, {"[", "]"}, {"\"", "\""}, {"'", "'"}};
28-
2927
QCodeEditor::QCodeEditor(QWidget *widget)
3028
: QTextEdit(widget), m_highlighter(nullptr), m_syntaxStyle(nullptr), m_lineNumberArea(new QLineNumberArea(this)),
31-
m_completer(nullptr), m_autoIndentation(true), m_autoParentheses(true), m_replaceTab(true),
32-
m_autoRemoveParentheses(true), m_extraBottomMargin(true), m_tabReplace(QString(4, ' ')), extra1(), extra2(),
33-
extra_squiggles(), m_squiggler()
29+
m_completer(nullptr), m_autoIndentation(true), m_replaceTab(true), m_extraBottomMargin(true),
30+
m_tabReplace(QString(4, ' ')), extra1(), extra2(), extra_squiggles(), m_squiggler(),
31+
m_parentheses({{'(', ')'}, {'{', '}'}, {'[', ']'}, {'\"', '\"'}, {'\'', '\''}})
3432
{
3533
initFont();
3634
performConnections();
@@ -400,24 +398,24 @@ void QCodeEditor::highlightParenthesis()
400398
auto currentSymbol = charUnderCursor();
401399
auto prevSymbol = charUnderCursor(-1);
402400

403-
for (auto &pair : parentheses)
401+
for (auto &p : m_parentheses)
404402
{
405403
int direction;
406404

407405
QChar counterSymbol;
408406
QChar activeSymbol;
409407
auto position = textCursor().position();
410408

411-
if (pair.first == currentSymbol)
409+
if (p.left == currentSymbol)
412410
{
413411
direction = 1;
414-
counterSymbol = pair.second[0];
412+
counterSymbol = p.right;
415413
activeSymbol = currentSymbol;
416414
}
417-
else if (pair.second == prevSymbol)
415+
else if (p.right == prevSymbol)
418416
{
419417
direction = -1;
420-
counterSymbol = pair.first[0];
418+
counterSymbol = p.left;
421419
activeSymbol = prevSymbol;
422420
position--;
423421
}
@@ -661,7 +659,18 @@ void QCodeEditor::keyPressEvent(QKeyEvent *e)
661659
indent();
662660
return;
663661
}
664-
else if (m_replaceTab)
662+
663+
auto c = charUnderCursor();
664+
for (auto p : m_parentheses)
665+
{
666+
if (p.tabJumpOut && c == p.right)
667+
{
668+
moveCursor(QTextCursor::NextCharacter);
669+
return;
670+
}
671+
}
672+
673+
if (m_replaceTab)
665674
{
666675
insertPlainText(m_tabReplace);
667676
return;
@@ -708,14 +717,13 @@ void QCodeEditor::keyPressEvent(QKeyEvent *e)
708717
return;
709718
}
710719

711-
if (m_autoRemoveParentheses && e->key() == Qt::Key_Backspace && e->modifiers() == Qt::NoModifier &&
712-
!textCursor().hasSelection())
720+
if (e->key() == Qt::Key_Backspace && e->modifiers() == Qt::NoModifier && !textCursor().hasSelection())
713721
{
714722
auto pre = charUnderCursor(-1);
715723
auto nxt = charUnderCursor();
716-
for (auto p : parentheses)
724+
for (auto p : m_parentheses)
717725
{
718-
if (p.first == pre && p.second == nxt)
726+
if (p.autoRemove && p.left == pre && p.right == nxt)
719727
{
720728
auto cursor = textCursor();
721729
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor);
@@ -753,20 +761,20 @@ void QCodeEditor::keyPressEvent(QKeyEvent *e)
753761
}
754762
}
755763

756-
if (m_autoParentheses)
764+
for (auto p : m_parentheses)
757765
{
758-
for (auto &&el : parentheses)
766+
if (p.autoComplete)
759767
{
760-
// Add parentheses for selection
761-
if (el.first == e->text())
768+
auto cursor = textCursor();
769+
if (cursor.hasSelection())
762770
{
763-
auto cursor = textCursor();
764-
if (cursor.hasSelection())
771+
if (p.left == e->text())
765772
{
773+
// Add parentheses for selection
766774
int startPos = cursor.selectionStart();
767775
int endPos = cursor.selectionEnd();
768776
bool cursorAtEnd = cursor.position() == endPos;
769-
auto text = el.first + cursor.selectedText() + el.second;
777+
auto text = p.left + cursor.selectedText() + p.right;
770778
insertPlainText(text);
771779
if (cursorAtEnd)
772780
{
@@ -782,6 +790,26 @@ void QCodeEditor::keyPressEvent(QKeyEvent *e)
782790
return;
783791
}
784792
}
793+
else
794+
{
795+
if (p.right == e->text())
796+
{
797+
auto symbol = charUnderCursor();
798+
799+
if (symbol == p.right)
800+
{
801+
moveCursor(QTextCursor::NextCharacter);
802+
return;
803+
}
804+
}
805+
806+
if (p.left == e->text())
807+
{
808+
insertPlainText(QString(p.left) + p.right);
809+
moveCursor(QTextCursor::PreviousCharacter);
810+
return;
811+
}
812+
}
785813
}
786814
}
787815

@@ -792,31 +820,6 @@ void QCodeEditor::keyPressEvent(QKeyEvent *e)
792820
return;
793821
}
794822

795-
if (m_autoParentheses)
796-
{
797-
for (auto &&el : parentheses)
798-
{
799-
// If it's close brace - check parentheses
800-
if (el.second == e->text())
801-
{
802-
auto symbol = charUnderCursor();
803-
804-
if (symbol == el.second)
805-
{
806-
moveCursor(QTextCursor::MoveOperation::Right);
807-
return;
808-
}
809-
}
810-
// Inserting closed brace
811-
if (el.first == e->text())
812-
{
813-
insertPlainText(el.first + el.second);
814-
moveCursor(QTextCursor::MoveOperation::Left);
815-
return;
816-
}
817-
}
818-
}
819-
820823
QTextEdit::keyPressEvent(e);
821824
}
822825

@@ -828,9 +831,9 @@ void QCodeEditor::setAutoIndentation(bool enabled)
828831
m_autoIndentation = enabled;
829832
}
830833

831-
void QCodeEditor::setAutoRemoveParentheses(bool enabled)
834+
void QCodeEditor::setParentheses(const QVector<Parenthesis> &parentheses)
832835
{
833-
m_autoRemoveParentheses = enabled;
836+
m_parentheses = parentheses;
834837
}
835838

836839
void QCodeEditor::setExtraBottomMargin(bool enabled)
@@ -844,16 +847,6 @@ bool QCodeEditor::autoIndentation() const
844847
return m_autoIndentation;
845848
}
846849

847-
void QCodeEditor::setAutoParentheses(bool enabled)
848-
{
849-
m_autoParentheses = enabled;
850-
}
851-
852-
bool QCodeEditor::autoParentheses() const
853-
{
854-
return m_autoParentheses;
855-
}
856-
857850
void QCodeEditor::setTabReplace(bool enabled)
858851
{
859852
m_replaceTab = enabled;

0 commit comments

Comments
 (0)