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+
2452static 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
156204void LuaConsole::showAutoCompletion () {
157205 std::string partialWord;
0 commit comments