##// END OF EJS Templates
Docstrings tweaks.
gvaroquaux -
Show More
@@ -1,367 +1,370 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A Wx widget that deals with prompts and provides an edit buffer
3 A Wx widget to act as a console and input commands.
4
5 This widget deals with prompts and provides an edit buffer
4 restricted to after the last prompt.
6 restricted to after the last prompt.
5 """
7 """
6
8
7 __docformat__ = "restructuredtext en"
9 __docformat__ = "restructuredtext en"
8
10
9 #-------------------------------------------------------------------------------
11 #-------------------------------------------------------------------------------
10 # Copyright (C) 2008 The IPython Development Team
12 # Copyright (C) 2008 The IPython Development Team
11 #
13 #
12 # Distributed under the terms of the BSD License. The full license is
14 # Distributed under the terms of the BSD License. The full license is
13 # in the file COPYING, distributed as part of this software.
15 # in the file COPYING, distributed as part of this software.
14 #-------------------------------------------------------------------------------
16 #-------------------------------------------------------------------------------
15
17
16 #-------------------------------------------------------------------------------
18 #-------------------------------------------------------------------------------
17 # Imports
19 # Imports
18 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
19
21
20 import wx
22 import wx
21 import wx.stc as stc
23 import wx.stc as stc
22
24
23 import re
25 import re
24
26
25 # FIXME: Need to provide an API for non user-generated display on the
27 # FIXME: Need to provide an API for non user-generated display on the
26 # screen: this should not be editable by the user.
28 # screen: this should not be editable by the user.
27
29
28 #-------------------------------------------------------------------------------
30 #-------------------------------------------------------------------------------
29 # The console widget class
31 # The console widget class
30 #-------------------------------------------------------------------------------
32 #-------------------------------------------------------------------------------
31 class ConsoleWidget(stc.StyledTextCtrl):
33 class ConsoleWidget(stc.StyledTextCtrl):
32 """ Specialized styled text control view for console-like workflow.
34 """ Specialized styled text control view for console-like workflow.
35
33 This widget is mainly interested in dealing with the prompt and
36 This widget is mainly interested in dealing with the prompt and
34 keeping the cursor inside the editing line.
37 keeping the cursor inside the editing line.
35 """
38 """
36
39
37 # Translation table from ANSI escape sequences to color. Override
40 # Translation table from ANSI escape sequences to color. Override
38 # this to specify your colors.
41 # this to specify your colors.
39 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
42 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
40 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
43 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
41 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
44 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
42 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
45 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
43 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
46 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
44 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
47 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
45 '1;34': [12, 'LIGHT BLUE'], '1;35':
48 '1;34': [12, 'LIGHT BLUE'], '1;35':
46 [13, 'MEDIUM VIOLET RED'],
49 [13, 'MEDIUM VIOLET RED'],
47 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
50 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
48
51
49 # The color of the carret (call _apply_style() after setting)
52 # The color of the carret (call _apply_style() after setting)
50 carret_color = 'BLACK'
53 carret_color = 'BLACK'
51
54
52
55
53 #--------------------------------------------------------------------------
56 #--------------------------------------------------------------------------
54 # Public API
57 # Public API
55 #--------------------------------------------------------------------------
58 #--------------------------------------------------------------------------
56
59
57 def write(self, text):
60 def write(self, text):
58 """ Write given text to buffer, while translating the ansi escape
61 """ Write given text to buffer, while translating the ansi escape
59 sequences.
62 sequences.
60 """
63 """
61 segments = self.color_pat.split(text)
64 segments = self.color_pat.split(text)
62 segment = segments.pop(0)
65 segment = segments.pop(0)
63 self.StartStyling(self.GetLength(), 0xFF)
66 self.StartStyling(self.GetLength(), 0xFF)
64 self.AppendText(segment)
67 self.AppendText(segment)
65
68
66 if segments:
69 if segments:
67 ansi_tags = self.color_pat.findall(text)
70 ansi_tags = self.color_pat.findall(text)
68
71
69 for tag in ansi_tags:
72 for tag in ansi_tags:
70 i = segments.index(tag)
73 i = segments.index(tag)
71 self.StartStyling(self.GetLength(), 0xFF)
74 self.StartStyling(self.GetLength(), 0xFF)
72 self.AppendText(segments[i+1])
75 self.AppendText(segments[i+1])
73
76
74 if tag != '0':
77 if tag != '0':
75 self.SetStyling(len(segments[i+1]),
78 self.SetStyling(len(segments[i+1]),
76 self.ANSI_STYLES[tag][0])
79 self.ANSI_STYLES[tag][0])
77
80
78 segments.pop(i)
81 segments.pop(i)
79
82
80 self.GotoPos(self.GetLength())
83 self.GotoPos(self.GetLength())
81
84
82
85
83 def new_prompt(self, prompt):
86 def new_prompt(self, prompt):
84 """ Prints a prompt at start of line, and move the start of the
87 """ Prints a prompt at start of line, and move the start of the
85 current block there.
88 current block there.
86
89
87 The prompt can be give with ascii escape sequences.
90 The prompt can be give with ascii escape sequences.
88 """
91 """
89 self.write(prompt)
92 self.write(prompt)
90 # now we update our cursor giving end of prompt
93 # now we update our cursor giving end of prompt
91 self.current_prompt_pos = self.GetLength()
94 self.current_prompt_pos = self.GetLength()
92 self.current_prompt_line = self.GetCurrentLine()
95 self.current_prompt_line = self.GetCurrentLine()
93
96
94 autoindent = self.indent * ' '
97 autoindent = self.indent * ' '
95 autoindent = autoindent.replace(' ','\t')
98 autoindent = autoindent.replace(' ','\t')
96 self.write(autoindent)
99 self.write(autoindent)
97
100
98
101
99 def replace_current_edit_buffer(self, text):
102 def replace_current_edit_buffer(self, text):
100 """ Replace currently entered command line with given text.
103 """ Replace currently entered command line with given text.
101 """
104 """
102 self.SetSelection(self.current_prompt_pos, self.GetLength())
105 self.SetSelection(self.current_prompt_pos, self.GetLength())
103 self.ReplaceSelection(text)
106 self.ReplaceSelection(text)
104 self.GotoPos(self.GetLength())
107 self.GotoPos(self.GetLength())
105
108
106
109
107 def get_current_edit_buffer(self):
110 def get_current_edit_buffer(self):
108 """ Returns the text in current edit buffer.
111 """ Returns the text in current edit buffer.
109 """
112 """
110 return self.GetTextRange(self.current_prompt_pos,
113 return self.GetTextRange(self.current_prompt_pos,
111 self.GetLength())
114 self.GetLength())
112
115
113
116
114 #--------------------------------------------------------------------------
117 #--------------------------------------------------------------------------
115 # Private API
118 # Private API
116 #--------------------------------------------------------------------------
119 #--------------------------------------------------------------------------
117
120
118 def __init__(self, parent, pos=wx.DefaultPosition, ID=-1,
121 def __init__(self, parent, pos=wx.DefaultPosition, ID=-1,
119 size=wx.DefaultSize, style=0,
122 size=wx.DefaultSize, style=0,
120 autocomplete_mode='IPYTHON'):
123 autocomplete_mode='IPYTHON'):
121 """ Autocomplete_mode: Can be 'IPYTHON' or 'STC'
124 """ Autocomplete_mode: Can be 'IPYTHON' or 'STC'
122 'IPYTHON' show autocompletion the ipython way
125 'IPYTHON' show autocompletion the ipython way
123 'STC" show it scintilla text control way
126 'STC" show it scintilla text control way
124 """
127 """
125 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
128 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
126
129
127 #------ Scintilla configuration -----------------------------------
130 #------ Scintilla configuration -----------------------------------
128
131
129 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
132 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
130 # the widget
133 # the widget
131 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
134 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
132 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
135 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
133 # Also allow Ctrl Shift "=" for poor non US keyboard users.
136 # Also allow Ctrl Shift "=" for poor non US keyboard users.
134 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
137 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
135 stc.STC_CMD_ZOOMIN)
138 stc.STC_CMD_ZOOMIN)
136
139
137 self.SetEOLMode(stc.STC_EOL_CRLF)
140 self.SetEOLMode(stc.STC_EOL_CRLF)
138 self.SetWrapMode(stc.STC_WRAP_CHAR)
141 self.SetWrapMode(stc.STC_WRAP_CHAR)
139 self.SetWrapMode(stc.STC_WRAP_WORD)
142 self.SetWrapMode(stc.STC_WRAP_WORD)
140 self.SetBufferedDraw(True)
143 self.SetBufferedDraw(True)
141 self.SetUseAntiAliasing(True)
144 self.SetUseAntiAliasing(True)
142 self.SetLayoutCache(stc.STC_CACHE_PAGE)
145 self.SetLayoutCache(stc.STC_CACHE_PAGE)
143 self.SetUndoCollection(False)
146 self.SetUndoCollection(False)
144 self.SetUseTabs(True)
147 self.SetUseTabs(True)
145 self.SetIndent(4)
148 self.SetIndent(4)
146 self.SetTabWidth(4)
149 self.SetTabWidth(4)
147
150
148 self.EnsureCaretVisible()
151 self.EnsureCaretVisible()
149
152
150 self.SetMargins(3, 3) #text is moved away from border with 3px
153 self.SetMargins(3, 3) #text is moved away from border with 3px
151 # Suppressing Scintilla margins
154 # Suppressing Scintilla margins
152 self.SetMarginWidth(0, 0)
155 self.SetMarginWidth(0, 0)
153 self.SetMarginWidth(1, 0)
156 self.SetMarginWidth(1, 0)
154 self.SetMarginWidth(2, 0)
157 self.SetMarginWidth(2, 0)
155
158
156 self._apply_style()
159 self._apply_style()
157
160
158 self.indent = 0
161 self.indent = 0
159 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
162 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
160
163
161 # FIXME: we need to retrieve this from the interpreter.
164 # FIXME: we need to retrieve this from the interpreter.
162 self.prompt = \
165 self.prompt = \
163 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x026\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02'
166 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x026\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02'
164 self.new_prompt(self.prompt)
167 self.new_prompt(self.prompt)
165
168
166 self.autocomplete_mode = autocomplete_mode
169 self.autocomplete_mode = autocomplete_mode
167
170
168 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
171 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
169
172
170
173
171 def _apply_style(self):
174 def _apply_style(self):
172 """ Applies the colors for the different text elements and the
175 """ Applies the colors for the different text elements and the
173 carret.
176 carret.
174 """
177 """
175 # FIXME: We need to do something for the fonts, but this is
178 # FIXME: We need to do something for the fonts, but this is
176 # clearly not the right option.
179 # clearly not the right option.
177 #we define platform specific fonts
180 #we define platform specific fonts
178 # if wx.Platform == '__WXMSW__':
181 # if wx.Platform == '__WXMSW__':
179 # faces = { 'times': 'Times New Roman',
182 # faces = { 'times': 'Times New Roman',
180 # 'mono' : 'Courier New',
183 # 'mono' : 'Courier New',
181 # 'helv' : 'Arial',
184 # 'helv' : 'Arial',
182 # 'other': 'Comic Sans MS',
185 # 'other': 'Comic Sans MS',
183 # 'size' : 10,
186 # 'size' : 10,
184 # 'size2': 8,
187 # 'size2': 8,
185 # }
188 # }
186 # elif wx.Platform == '__WXMAC__':
189 # elif wx.Platform == '__WXMAC__':
187 # faces = { 'times': 'Times New Roman',
190 # faces = { 'times': 'Times New Roman',
188 # 'mono' : 'Monaco',
191 # 'mono' : 'Monaco',
189 # 'helv' : 'Arial',
192 # 'helv' : 'Arial',
190 # 'other': 'Comic Sans MS',
193 # 'other': 'Comic Sans MS',
191 # 'size' : 10,
194 # 'size' : 10,
192 # 'size2': 8,
195 # 'size2': 8,
193 # }
196 # }
194 # else:
197 # else:
195 # faces = { 'times': 'Times',
198 # faces = { 'times': 'Times',
196 # 'mono' : 'Courier',
199 # 'mono' : 'Courier',
197 # 'helv' : 'Helvetica',
200 # 'helv' : 'Helvetica',
198 # 'other': 'new century schoolbook',
201 # 'other': 'new century schoolbook',
199 # 'size' : 10,
202 # 'size' : 10,
200 # 'size2': 8,
203 # 'size2': 8,
201 # }
204 # }
202 # self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
205 # self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
203 # "fore:%s,back:%s,size:%d,face:%s"
206 # "fore:%s,back:%s,size:%d,face:%s"
204 # % (self.ANSI_STYLES['0;30'][1],
207 # % (self.ANSI_STYLES['0;30'][1],
205 # self.background_color,
208 # self.background_color,
206 # faces['size'], faces['mono']))
209 # faces['size'], faces['mono']))
207
210
208 self.SetCaretForeground(self.carret_color)
211 self.SetCaretForeground(self.carret_color)
209
212
210 self.StyleClearAll()
213 self.StyleClearAll()
211 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
214 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
212 "fore:#FF0000,back:#0000FF,bold")
215 "fore:#FF0000,back:#0000FF,bold")
213 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
216 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
214 "fore:#000000,back:#FF0000,bold")
217 "fore:#000000,back:#FF0000,bold")
215
218
216 for style in self.ANSI_STYLES.values():
219 for style in self.ANSI_STYLES.values():
217 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
220 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
218
221
219
222
220 def removeFromTo(self, from_pos, to_pos):
223 def removeFromTo(self, from_pos, to_pos):
221 if from_pos < to_pos:
224 if from_pos < to_pos:
222 self.SetSelection(from_pos, to_pos)
225 self.SetSelection(from_pos, to_pos)
223 self.DeleteBack()
226 self.DeleteBack()
224
227
225
228
226 def selectFromTo(self, from_pos, to_pos):
229 def selectFromTo(self, from_pos, to_pos):
227 self.SetSelectionStart(from_pos)
230 self.SetSelectionStart(from_pos)
228 self.SetSelectionEnd(to_pos)
231 self.SetSelectionEnd(to_pos)
229
232
230
233
231 def writeCompletion(self, possibilities):
234 def writeCompletion(self, possibilities):
232 if self.autocomplete_mode == 'IPYTHON':
235 if self.autocomplete_mode == 'IPYTHON':
233 max_len = len(max(possibilities, key=len))
236 max_len = len(max(possibilities, key=len))
234 max_symbol = ' '*max_len
237 max_symbol = ' '*max_len
235
238
236 #now we check how much symbol we can put on a line...
239 #now we check how much symbol we can put on a line...
237 test_buffer = max_symbol + ' '*4
240 test_buffer = max_symbol + ' '*4
238
241
239 allowed_symbols = 80/len(test_buffer)
242 allowed_symbols = 80/len(test_buffer)
240 if allowed_symbols == 0:
243 if allowed_symbols == 0:
241 allowed_symbols = 1
244 allowed_symbols = 1
242
245
243 pos = 1
246 pos = 1
244 buf = ''
247 buf = ''
245 for symbol in possibilities:
248 for symbol in possibilities:
246 #buf += symbol+'\n'#*spaces)
249 #buf += symbol+'\n'#*spaces)
247 if pos < allowed_symbols:
250 if pos < allowed_symbols:
248 spaces = max_len - len(symbol) + 4
251 spaces = max_len - len(symbol) + 4
249 buf += symbol+' '*spaces
252 buf += symbol+' '*spaces
250 pos += 1
253 pos += 1
251 else:
254 else:
252 buf += symbol+'\n'
255 buf += symbol+'\n'
253 pos = 1
256 pos = 1
254 self.write(buf)
257 self.write(buf)
255 else:
258 else:
256 possibilities.sort() # Python sorts are case sensitive
259 possibilities.sort() # Python sorts are case sensitive
257 self.AutoCompSetIgnoreCase(False)
260 self.AutoCompSetIgnoreCase(False)
258 self.AutoCompSetAutoHide(False)
261 self.AutoCompSetAutoHide(False)
259 #let compute the length ot last word
262 #let compute the length ot last word
260 splitter = [' ', '(', '[', '{']
263 splitter = [' ', '(', '[', '{']
261 last_word = self.get_current_edit_buffer()
264 last_word = self.get_current_edit_buffer()
262 for breaker in splitter:
265 for breaker in splitter:
263 last_word = last_word.split(breaker)[-1]
266 last_word = last_word.split(breaker)[-1]
264 self.AutoCompShow(len(last_word), " ".join(possibilities))
267 self.AutoCompShow(len(last_word), " ".join(possibilities))
265
268
266
269
267 def _onKeypress(self, event, skip=True):
270 def _onKeypress(self, event, skip=True):
268 """ Key press callback used for correcting behavior for
271 """ Key press callback used for correcting behavior for
269 console-like interfaces: the cursor is constraint to be after
272 console-like interfaces: the cursor is constraint to be after
270 the last prompt.
273 the last prompt.
271
274
272 Return True if event as been catched.
275 Return True if event as been catched.
273 """
276 """
274 catched = False
277 catched = False
275 if self.AutoCompActive():
278 if self.AutoCompActive():
276 event.Skip()
279 event.Skip()
277 else:
280 else:
278 if event.GetKeyCode() == wx.WXK_HOME:
281 if event.GetKeyCode() == wx.WXK_HOME:
279 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
282 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
280 self.GotoPos(self.current_prompt_pos)
283 self.GotoPos(self.current_prompt_pos)
281 catched = True
284 catched = True
282
285
283 elif event.Modifiers == wx.MOD_SHIFT:
286 elif event.Modifiers == wx.MOD_SHIFT:
284 self.selectFromTo(self.current_prompt_pos,
287 self.selectFromTo(self.current_prompt_pos,
285 self.GetCurrentPos())
288 self.GetCurrentPos())
286 catched = True
289 catched = True
287
290
288 elif event.GetKeyCode() == wx.WXK_UP:
291 elif event.GetKeyCode() == wx.WXK_UP:
289 if self.GetCurrentLine() > self.current_prompt_line:
292 if self.GetCurrentLine() > self.current_prompt_line:
290 if self.GetCurrentLine() == self.current_prompt_line + 1 \
293 if self.GetCurrentLine() == self.current_prompt_line + 1 \
291 and self.GetColumn(self.GetCurrentPos()) < \
294 and self.GetColumn(self.GetCurrentPos()) < \
292 self.GetColumn(self.current_prompt_pos):
295 self.GetColumn(self.current_prompt_pos):
293 self.GotoPos(self.current_prompt_pos)
296 self.GotoPos(self.current_prompt_pos)
294 else:
297 else:
295 event.Skip()
298 event.Skip()
296 catched = True
299 catched = True
297
300
298 elif event.GetKeyCode() in (wx.WXK_LEFT, wx.WXK_BACK):
301 elif event.GetKeyCode() in (wx.WXK_LEFT, wx.WXK_BACK):
299 if self.GetCurrentPos() > self.current_prompt_pos:
302 if self.GetCurrentPos() > self.current_prompt_pos:
300 event.Skip()
303 event.Skip()
301 catched = True
304 catched = True
302
305
303 if skip and not catched:
306 if skip and not catched:
304 event.Skip()
307 event.Skip()
305
308
306 if event.GetKeyCode() not in (wx.WXK_PAGEUP, wx.WXK_PAGEDOWN)\
309 if event.GetKeyCode() not in (wx.WXK_PAGEUP, wx.WXK_PAGEDOWN)\
307 and event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
310 and event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
308 wx.MOD_SHIFT):
311 wx.MOD_SHIFT):
309 # If cursor is outside the editing region, put it back.
312 # If cursor is outside the editing region, put it back.
310 if self.GetCurrentPos() < self.current_prompt_pos:
313 if self.GetCurrentPos() < self.current_prompt_pos:
311 self.GotoPos(self.current_prompt_pos)
314 self.GotoPos(self.current_prompt_pos)
312
315
313 return catched
316 return catched
314
317
315
318
316 def OnUpdateUI(self, evt):
319 def OnUpdateUI(self, evt):
317 # check for matching braces
320 # check for matching braces
318 braceAtCaret = -1
321 braceAtCaret = -1
319 braceOpposite = -1
322 braceOpposite = -1
320 charBefore = None
323 charBefore = None
321 caretPos = self.GetCurrentPos()
324 caretPos = self.GetCurrentPos()
322
325
323 if caretPos > 0:
326 if caretPos > 0:
324 charBefore = self.GetCharAt(caretPos - 1)
327 charBefore = self.GetCharAt(caretPos - 1)
325 styleBefore = self.GetStyleAt(caretPos - 1)
328 styleBefore = self.GetStyleAt(caretPos - 1)
326
329
327 # check before
330 # check before
328 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
331 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
329 braceAtCaret = caretPos - 1
332 braceAtCaret = caretPos - 1
330
333
331 # check after
334 # check after
332 if braceAtCaret < 0:
335 if braceAtCaret < 0:
333 charAfter = self.GetCharAt(caretPos)
336 charAfter = self.GetCharAt(caretPos)
334 styleAfter = self.GetStyleAt(caretPos)
337 styleAfter = self.GetStyleAt(caretPos)
335
338
336 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
339 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
337 braceAtCaret = caretPos
340 braceAtCaret = caretPos
338
341
339 if braceAtCaret >= 0:
342 if braceAtCaret >= 0:
340 braceOpposite = self.BraceMatch(braceAtCaret)
343 braceOpposite = self.BraceMatch(braceAtCaret)
341
344
342 if braceAtCaret != -1 and braceOpposite == -1:
345 if braceAtCaret != -1 and braceOpposite == -1:
343 self.BraceBadLight(braceAtCaret)
346 self.BraceBadLight(braceAtCaret)
344 else:
347 else:
345 self.BraceHighlight(braceAtCaret, braceOpposite)
348 self.BraceHighlight(braceAtCaret, braceOpposite)
346
349
347
350
348 if __name__ == '__main__':
351 if __name__ == '__main__':
349 # Some simple code to test the console widget.
352 # Some simple code to test the console widget.
350 class MainWindow(wx.Frame):
353 class MainWindow(wx.Frame):
351 def __init__(self, parent, id, title):
354 def __init__(self, parent, id, title):
352 wx.Frame.__init__(self, parent, id, title, size=(300,250))
355 wx.Frame.__init__(self, parent, id, title, size=(300,250))
353 self._sizer = wx.BoxSizer(wx.VERTICAL)
356 self._sizer = wx.BoxSizer(wx.VERTICAL)
354 self.console_widget = ConsoleWidget(self)
357 self.console_widget = ConsoleWidget(self)
355 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
358 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
356 self.SetSizer(self._sizer)
359 self.SetSizer(self._sizer)
357 self.SetAutoLayout(1)
360 self.SetAutoLayout(1)
358 self.Show(True)
361 self.Show(True)
359
362
360 app = wx.PySimpleApp()
363 app = wx.PySimpleApp()
361 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
364 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
362 w.SetSize((780, 460))
365 w.SetSize((780, 460))
363 w.Show()
366 w.Show()
364
367
365 app.MainLoop()
368 app.MainLoop()
366
369
367
370
General Comments 0
You need to be logged in to leave comments. Login now