Skip to content

Commit 534ef89

Browse files
committed
Highlight matching braces
1 parent 86f6330 commit 534ef89

File tree

2 files changed

+71
-20
lines changed

2 files changed

+71
-20
lines changed

Dialogs/LuaConsole.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,8 @@ class LuaConsole final
6464
HWND m_hNotepad;
6565

6666
GUI::ScintillaWindow *m_sciInput;
67+
68+
void maintainIndentation();
69+
void braceMatch();
6770
};
6871

LuaConsole.cpp

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,34 @@
2121
#include "NppIFaceTable.h"
2222

2323

24+
#define INDIC_BRACEHIGHLIGHT INDIC_CONTAINER
25+
#define INDIC_BRACEBADLIGHT INDIC_CONTAINER + 1
26+
27+
static bool inline isBrace(int ch) {
28+
return strchr("[]{}()", ch) != NULL;
29+
}
30+
31+
static std::string getRange(GUI::ScintillaWindow *sw, int start, int end) {
32+
if (end <= start) return std::string();
33+
34+
std::vector<char> buffer(end - start + 1);
35+
TextRange tr;
36+
tr.chrg.cpMin = start;
37+
tr.chrg.cpMax = end;
38+
tr.lpstrText = buffer.data();
39+
40+
sw->CallPointer(SCI_GETTEXTRANGE, 0, &tr);
41+
42+
return std::string(buffer.begin(), buffer.end() - 1); // don't copy the null
43+
}
44+
45+
static std::string getWordAt(GUI::ScintillaWindow *sw, int pos) {
46+
int word_start = sw->Call(SCI_WORDSTARTPOSITION, pos, true);
47+
int word_end = sw->Call(SCI_WORDENDPOSITION, pos, true);
48+
return getRange(sw, word_start, word_end);
49+
}
50+
51+
2452
static void setStyles(GUI::ScintillaWindow &sci, bool is_input) {
2553
sci.Call(SCI_SETEOLMODE, SC_EOL_CRLF, 0);
2654

@@ -101,6 +129,10 @@ void LuaConsole::setupInput(GUI::ScintillaWindow &sci) {
101129
sci.Call(SCI_AUTOCSETMAXHEIGHT, 8);
102130
sci.Call(SCI_AUTOCSETCANCELATSTART, false);
103131

132+
sci.Call(SCI_INDICSETSTYLE, INDIC_BRACEHIGHLIGHT, INDIC_STRAIGHTBOX);
133+
sci.Call(SCI_INDICSETUNDER, INDIC_BRACEHIGHLIGHT, true);
134+
sci.Call(SCI_BRACEHIGHLIGHTINDICATOR, true, INDIC_BRACEHIGHLIGHT);
135+
104136
m_sciInput = &sci;
105137
}
106138

@@ -120,38 +152,54 @@ bool LuaConsole::processNotification(const SCNotification *scn) {
120152
showAutoCompletion();
121153
}
122154
else if (scn->ch == '\n') {
123-
int curPos = m_sciInput->Call(SCI_GETCURRENTPOS);
124-
int curLine = m_sciInput->Call(SCI_LINEFROMPOSITION, curPos);
125-
int prevIndent = m_sciInput->Call(SCI_GETLINEINDENTATION, curLine - 1);
126-
m_sciInput->Call(SCI_SETLINEINDENTATION, curLine, prevIndent);
127-
curPos = m_sciInput->Call(SCI_GETLINEINDENTPOSITION, curLine);
128-
m_sciInput->Call(SCI_SETEMPTYSELECTION, curPos);
155+
maintainIndentation();
129156
}
130157
break;
131158
}
159+
case SCN_UPDATEUI: {
160+
braceMatch();
161+
break;
162+
}
132163
}
133164
return true;
134165
}
135166

136-
static std::string getRange(GUI::ScintillaWindow *sw, int start, int end) {
137-
if (end <= start) return std::string();
167+
void LuaConsole::maintainIndentation() {
168+
int curPos = m_sciInput->Call(SCI_GETCURRENTPOS);
169+
int curLine = m_sciInput->Call(SCI_LINEFROMPOSITION, curPos);
170+
int prevIndent = m_sciInput->Call(SCI_GETLINEINDENTATION, curLine - 1);
171+
m_sciInput->Call(SCI_SETLINEINDENTATION, curLine, prevIndent);
172+
curPos = m_sciInput->Call(SCI_GETLINEINDENTPOSITION, curLine);
173+
m_sciInput->Call(SCI_SETEMPTYSELECTION, curPos);
174+
}
138175

139-
std::vector<char> buffer(end - start + 1);
140-
TextRange tr;
141-
tr.chrg.cpMin = start;
142-
tr.chrg.cpMax = end;
143-
tr.lpstrText = buffer.data();
176+
void LuaConsole::braceMatch() {
177+
int curPos = m_sciInput->Call(SCI_GETCURRENTPOS);
178+
int bracePos = INVALID_POSITION;
144179

145-
sw->CallPointer(SCI_GETTEXTRANGE, 0, &tr);
180+
// Check on both sides
181+
if (isBrace(m_sciInput->Call(SCI_GETCHARAT, curPos - 1))) {
182+
bracePos = curPos - 1;
183+
}
184+
else if (isBrace(m_sciInput->Call(SCI_GETCHARAT, curPos))) {
185+
bracePos = curPos;
186+
}
146187

147-
return std::string(buffer.begin(), buffer.end() - 1); // don't copy the null
188+
// See if we are next to a brace
189+
if (bracePos != INVALID_POSITION) {
190+
int otherPos = m_sciInput->Call(SCI_BRACEMATCH, bracePos, 0);
191+
if (otherPos != INVALID_POSITION) {
192+
m_sciInput->Call(SCI_BRACEHIGHLIGHT, bracePos, otherPos);
193+
}
194+
else {
195+
m_sciInput->Call(SCI_BRACEHIGHLIGHT, INVALID_POSITION, INVALID_POSITION);
196+
}
197+
}
198+
else {
199+
m_sciInput->Call(SCI_BRACEHIGHLIGHT, INVALID_POSITION, INVALID_POSITION);
200+
}
148201
}
149202

150-
static std::string getWordAt(GUI::ScintillaWindow *sw, int pos) {
151-
int word_start = sw->Call(SCI_WORDSTARTPOSITION, pos, true);
152-
int word_end = sw->Call(SCI_WORDENDPOSITION, pos, true);
153-
return getRange(sw, word_start, word_end);
154-
}
155203

156204
void LuaConsole::showAutoCompletion() {
157205
std::string partialWord;

0 commit comments

Comments
 (0)