##// END OF EJS Templates
Calltips are now working.
Gael Varoquaux -
Show More
@@ -1,406 +1,405 b''
1 1 # encoding: utf-8
2 2 """
3 3 A Wx widget to act as a console and input commands.
4 4
5 5 This widget deals with prompts and provides an edit buffer
6 6 restricted to after the last prompt.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is
15 15 # in the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22 import wx
23 23 import wx.stc as stc
24 24
25 25 from wx.py import editwindow
26 26
27 27 import re
28 28
29 29 # FIXME: Need to provide an API for non user-generated display on the
30 30 # screen: this should not be editable by the user.
31 31
32 32 if wx.Platform == '__WXMSW__':
33 33 _DEFAULT_SIZE = 80
34 34 else:
35 35 _DEFAULT_SIZE = 10
36 36
37 37 _DEFAULT_STYLE = {
38 38 'stdout' : 'fore:#0000FF',
39 39 'stderr' : 'fore:#007f00',
40 40 'trace' : 'fore:#FF0000',
41 41
42 42 'default' : 'size:%d' % _DEFAULT_SIZE,
43 43 'bracegood' : 'fore:#FFFFFF,back:#0000FF,bold',
44 44 'bracebad' : 'fore:#000000,back:#FF0000,bold',
45 45
46 46 # properties for the various Python lexer styles
47 47 'comment' : 'fore:#007F00',
48 48 'number' : 'fore:#007F7F',
49 49 'string' : 'fore:#7F007F,italic',
50 50 'char' : 'fore:#7F007F,italic',
51 51 'keyword' : 'fore:#00007F,bold',
52 52 'triple' : 'fore:#7F0000',
53 53 'tripledouble' : 'fore:#7F0000',
54 54 'class' : 'fore:#0000FF,bold,underline',
55 55 'def' : 'fore:#007F7F,bold',
56 56 'operator' : 'bold'
57 57 }
58 58
59 59 # new style numbers
60 60 _STDOUT_STYLE = 15
61 61 _STDERR_STYLE = 16
62 62 _TRACE_STYLE = 17
63 63
64 64
65 65 # system colors
66 66 SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
67 67
68 68 #-------------------------------------------------------------------------------
69 69 # The console widget class
70 70 #-------------------------------------------------------------------------------
71 71 class ConsoleWidget(editwindow.EditWindow):
72 72 """ Specialized styled text control view for console-like workflow.
73 73
74 74 This widget is mainly interested in dealing with the prompt and
75 75 keeping the cursor inside the editing line.
76 76 """
77 77
78 78 title = 'Console'
79 79
80 80 style = _DEFAULT_STYLE.copy()
81 81
82 82 # Translation table from ANSI escape sequences to color. Override
83 83 # this to specify your colors.
84 84 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
85 85 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
86 86 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
87 87 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
88 88 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
89 89 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
90 90 '1;34': [12, 'LIGHT BLUE'], '1;35':
91 91 [13, 'MEDIUM VIOLET RED'],
92 92 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
93 93
94 94 # The color of the carret (call _apply_style() after setting)
95 95 carret_color = 'BLACK'
96 96
97 97
98 98 #--------------------------------------------------------------------------
99 99 # Public API
100 100 #--------------------------------------------------------------------------
101 101
102 102 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
103 103 size=wx.DefaultSize, style=0,
104 104 autocomplete_mode='popup'):
105 105 """ Autocomplete_mode: Can be 'popup' or 'text'
106 106 'text' show autocompletion in the text buffer
107 107 'popup' show it with a dropdown popup
108 108 """
109 109 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
110 110 self.configure_scintilla()
111 111
112 112 # FIXME: we need to retrieve this from the interpreter.
113 113 self.prompt = \
114 114 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02%i\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02'
115 115 self.new_prompt(self.prompt % 1)
116 116
117 117 self.autocomplete_mode = autocomplete_mode
118 118
119 119 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
120 120 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
121 121
122 122
123 123 def configure_scintilla(self):
124 124 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
125 125 # the widget
126 126 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
127 127 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
128 128 # Also allow Ctrl Shift "=" for poor non US keyboard users.
129 129 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
130 130 stc.STC_CMD_ZOOMIN)
131 131
132 132 #self.CmdKeyAssign(stc.STC_KEY_PRIOR, stc.STC_SCMOD_SHIFT,
133 133 # stc.STC_CMD_PAGEUP)
134 134
135 135 #self.CmdKeyAssign(stc.STC_KEY_NEXT, stc.STC_SCMOD_SHIFT,
136 136 # stc.STC_CMD_PAGEDOWN)
137 137
138 138 # Keys: we need to clear some of the keys the that don't play
139 139 # well with a console.
140 140 self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
141 141 self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
142 142 self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
143 143
144 144
145 145 self.SetEOLMode(stc.STC_EOL_CRLF)
146 146 self.SetWrapMode(stc.STC_WRAP_CHAR)
147 147 self.SetWrapMode(stc.STC_WRAP_WORD)
148 148 self.SetBufferedDraw(True)
149 149 self.SetUseAntiAliasing(True)
150 150 self.SetLayoutCache(stc.STC_CACHE_PAGE)
151 151 self.SetUndoCollection(False)
152 152 self.SetUseTabs(True)
153 153 self.SetIndent(4)
154 154 self.SetTabWidth(4)
155 155
156 156 self.EnsureCaretVisible()
157 157 # Tell autocompletion to choose automaticaly out of a single
158 158 # choice list
159 159 self.AutoCompSetChooseSingle(True)
160 160 self.AutoCompSetMaxHeight(10)
161 161
162 162 self.SetMargins(3, 3) #text is moved away from border with 3px
163 163 # Suppressing Scintilla margins
164 164 self.SetMarginWidth(0, 0)
165 165 self.SetMarginWidth(1, 0)
166 166 self.SetMarginWidth(2, 0)
167 167
168 168 self._apply_style()
169 169
170 170 # Xterm escape sequences
171 171 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
172 172 self.title_pat = re.compile('\x1b]0;(.*?)\x07')
173 173
174 174 #self.SetEdgeMode(stc.STC_EDGE_LINE)
175 175 #self.SetEdgeColumn(80)
176 176
177 177 # styles
178 178 p = self.style
179 179 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
180 180 self.StyleClearAll()
181 181 self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
182 182 self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
183 183 self.StyleSetSpec(_TRACE_STYLE, p['trace'])
184 184
185 185 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
186 186 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
187 187 self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
188 188 self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
189 189 self.StyleSetSpec(stc.STC_P_STRING, p['string'])
190 190 self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
191 191 self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
192 192 self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
193 193 self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
194 194 self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
195 195 self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
196 196 self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
197 197 self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
198 198 self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
199 199
200 200
201 201 def write(self, text):
202 202 """ Write given text to buffer, while translating the ansi escape
203 203 sequences.
204 204 """
205 205 title = self.title_pat.split(text)
206 206 if len(title)>0:
207 207 self.title = title[-1]
208 208
209 209 text = self.title_pat.sub('', text)
210 210 segments = self.color_pat.split(text)
211 211 segment = segments.pop(0)
212 212 self.StartStyling(self.GetLength(), 0xFF)
213 213 self.AppendText(segment)
214 214
215 215 if segments:
216 216 ansi_tags = self.color_pat.findall(text)
217 217
218 218 for tag in ansi_tags:
219 219 i = segments.index(tag)
220 220 self.StartStyling(self.GetLength(), 0xFF)
221 221 self.AppendText(segments[i+1])
222 222
223 223 if tag != '0':
224 224 self.SetStyling(len(segments[i+1]),
225 225 self.ANSI_STYLES[tag][0])
226 226
227 227 segments.pop(i)
228 228
229 229 self.GotoPos(self.GetLength())
230 230
231 231
232 232 def new_prompt(self, prompt):
233 233 """ Prints a prompt at start of line, and move the start of the
234 234 current block there.
235 235
236 236 The prompt can be give with ascii escape sequences.
237 237 """
238 238 self.write(prompt)
239 239 # now we update our cursor giving end of prompt
240 240 self.current_prompt_pos = self.GetLength()
241 241 self.current_prompt_line = self.GetCurrentLine()
242 242 wx.Yield()
243 243 self.EnsureCaretVisible()
244 244
245 245
246 246 def replace_current_edit_buffer(self, text):
247 247 """ Replace currently entered command line with given text.
248 248 """
249 249 self.SetSelection(self.current_prompt_pos, self.GetLength())
250 250 self.ReplaceSelection(text)
251 251 self.GotoPos(self.GetLength())
252 252
253 253
254 254 def get_current_edit_buffer(self):
255 255 """ Returns the text in current edit buffer.
256 256 """
257 257 return self.GetTextRange(self.current_prompt_pos,
258 258 self.GetLength())
259 259
260 260
261 261 #--------------------------------------------------------------------------
262 262 # Private API
263 263 #--------------------------------------------------------------------------
264 264
265 265 def _apply_style(self):
266 266 """ Applies the colors for the different text elements and the
267 267 carret.
268 268 """
269 269 self.SetCaretForeground(self.carret_color)
270 270
271 271 #self.StyleClearAll()
272 272 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
273 273 "fore:#FF0000,back:#0000FF,bold")
274 274 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
275 275 "fore:#000000,back:#FF0000,bold")
276 276
277 277 for style in self.ANSI_STYLES.values():
278 278 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
279 279
280 280
281 281 def write_completion(self, possibilities, mode=None):
282 282 if mode=='text' or self.autocomplete_mode == 'text':
283 283 max_len = len(max(possibilities, key=len))
284 284 current_buffer = self.get_current_edit_buffer()
285 285
286 286 self.write('\n')
287 287 for symbol in possibilities:
288 288 self.write(symbol.ljust(max_len))
289 289 self.new_prompt(self.prompt % (self.last_result['number'] + 1))
290 290 self.replace_current_edit_buffer(current_buffer)
291 291 else:
292 #possibilities.sort() # Python sorts are case sensitive
293 292 self.AutoCompSetIgnoreCase(False)
294 293 self.AutoCompSetAutoHide(False)
295 #let compute the length ot text)last word
296 splitter = [' ', '(', '[', '{']
297 last_word = self.get_current_edit_buffer()
298 for breaker in splitter:
299 last_word = last_word.split(breaker)[-1]
294 # compute the length ot the last word
295 separators = [' ', '(', '[', '{', '\n', '\t', '.']
296 symbol = self.get_current_edit_buffer()
297 for separator in separators:
298 symbol = symbol.split(separator)[-1]
300 299 self.AutoCompSetMaxHeight(len(possibilities))
301 self.AutoCompShow(len(last_word), " ".join(possibilities))
300 self.AutoCompShow(len(symbol), " ".join(possibilities))
302 301
303 302
304 303 def scroll_to_bottom(self):
305 304 maxrange = self.GetScrollRange(wx.VERTICAL)
306 305 self.ScrollLines(maxrange)
307 306
308 307
309 308 def _on_enter(self):
310 309 """ Called when the return key is hit.
311 310 """
312 311 pass
313 312
314 313
315 314 def _on_key_down(self, event, skip=True):
316 315 """ Key press callback used for correcting behavior for
317 316 console-like interfaces: the cursor is constraint to be after
318 317 the last prompt.
319 318
320 319 Return True if event as been catched.
321 320 """
322 321 catched = True
323 322 # Intercept some specific keys.
324 323 if event.KeyCode == ord('L') and event.ControlDown() :
325 324 self.scroll_to_bottom()
326 325 elif event.KeyCode == ord('K') and event.ControlDown() :
327 326 self.replace_current_edit_buffer('')
328 327 elif event.KeyCode == wx.WXK_PAGEUP and event.ShiftDown():
329 328 self.ScrollPages(-1)
330 329 elif event.KeyCode == wx.WXK_PAGEDOWN and event.ShiftDown():
331 330 self.ScrollPages(1)
332 331 else:
333 332 catched = False
334 333
335 334 if self.AutoCompActive():
336 335 event.Skip()
337 336 else:
338 337 if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
339 338 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
340 339 catched = True
341 340 self.write('\n')
342 341 self._on_enter()
343 342
344 343 elif event.KeyCode == wx.WXK_HOME:
345 344 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
346 345 self.GotoPos(self.current_prompt_pos)
347 346 catched = True
348 347
349 348 elif event.Modifiers in (wx.MOD_SHIFT, wx.MOD_WIN) :
350 349 # FIXME: This behavior is not ideal: if the selection
351 350 # is already started, it will jump.
352 351 self.SetSelectionStart(self.current_prompt_pos)
353 352 self.SetSelectionEnd(self.GetCurrentPos())
354 353 catched = True
355 354
356 355 elif event.KeyCode == wx.WXK_UP:
357 356 if self.GetCurrentLine() > self.current_prompt_line:
358 357 if self.GetCurrentLine() == self.current_prompt_line + 1 \
359 358 and self.GetColumn(self.GetCurrentPos()) < \
360 359 self.GetColumn(self.current_prompt_pos):
361 360 self.GotoPos(self.current_prompt_pos)
362 361 else:
363 362 event.Skip()
364 363 catched = True
365 364
366 365 elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
367 366 if self.GetCurrentPos() > self.current_prompt_pos:
368 367 event.Skip()
369 368 catched = True
370 369
371 370 if skip and not catched:
372 371 event.Skip()
373 372
374 373 return catched
375 374
376 375
377 376 def _on_key_up(self, event, skip=True):
378 377 """ If cursor is outside the editing region, put it back.
379 378 """
380 379 event.Skip()
381 380 if self.GetCurrentPos() < self.current_prompt_pos:
382 381 self.GotoPos(self.current_prompt_pos)
383 382
384 383
385 384
386 385
387 386 if __name__ == '__main__':
388 387 # Some simple code to test the console widget.
389 388 class MainWindow(wx.Frame):
390 389 def __init__(self, parent, id, title):
391 390 wx.Frame.__init__(self, parent, id, title, size=(300,250))
392 391 self._sizer = wx.BoxSizer(wx.VERTICAL)
393 392 self.console_widget = ConsoleWidget(self)
394 393 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
395 394 self.SetSizer(self._sizer)
396 395 self.SetAutoLayout(1)
397 396 self.Show(True)
398 397
399 398 app = wx.PySimpleApp()
400 399 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
401 400 w.SetSize((780, 460))
402 401 w.Show()
403 402
404 403 app.MainLoop()
405 404
406 405
@@ -1,178 +1,201 b''
1 1 # encoding: utf-8 -*- test-case-name:
2 2 # FIXME: Need to add tests.
3 3 # ipython1.frontend.cocoa.tests.test_cocoa_frontend -*-
4 4
5 5 """Classes to provide a Wx frontend to the
6 6 IPython.kernel.core.interpreter.
7 7
8 8 """
9 9
10 10 __docformat__ = "restructuredtext en"
11 11
12 12 #-------------------------------------------------------------------------------
13 13 # Copyright (C) 2008 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-------------------------------------------------------------------------------
18 18
19 19 #-------------------------------------------------------------------------------
20 20 # Imports
21 21 #-------------------------------------------------------------------------------
22 22
23 23
24 24 import wx
25 25 import re
26 26 from wx import stc
27 27 from console_widget import ConsoleWidget
28 import __builtin__
28 29
29 30 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
30 31
31 32 #_COMMAND_BG = '#FAFAF1' # Nice green
32 _RUNNING_BUFFER_BG = '#FDFFBE' # Nice yellow
33 _RUNNING_BUFFER_BG = '#FDFFD3' # Nice yellow
33 34
34 35 _RUNNING_BUFFER_MARKER = 31
35 36
36 37
37 38 #-------------------------------------------------------------------------------
38 39 # Classes to implement the Wx frontend
39 40 #-------------------------------------------------------------------------------
40 41 class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):
41 42
42 43 output_prompt = \
43 44 '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02'
44 45
45 46 #--------------------------------------------------------------------------
46 47 # Public API
47 48 #--------------------------------------------------------------------------
48 49
49 50 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
50 51 size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
51 52 *args, **kwds):
52 53 """ Create Shell instance.
53 54 """
54 55 ConsoleWidget.__init__(self, parent, id, pos, size, style)
55 56 PrefilterFrontEnd.__init__(self)
56 57
57 58 # Capture Character keys
58 59 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
59 60
60 61 # Marker for running buffer.
61 62 self.MarkerDefine(_RUNNING_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
62 63 background=_RUNNING_BUFFER_BG)
63 64
64 65
65 66
66 67 def do_completion(self, mode=None):
67 68 """ Do code completion.
68 69 mode can be 'text', 'popup' or 'none' to use default.
69 70 """
70 71 line = self.get_current_edit_buffer()
71 72 completions = self.complete(line)
72 73 if len(completions)>0:
73 74 self.write_completion(completions, mode=mode)
74 75
75 76
77 def do_calltip(self):
78 # compute the length ot the last word
79 separators = [' ', '(', '[', '{', '\n', '\t']
80 symbol = self.get_current_edit_buffer()
81 for separator in separators:
82 symbol_string = symbol.split(separator)[-1]
83 base_symbol_string = symbol_string.split('.')[0]
84 if base_symbol_string in self.shell.user_ns:
85 symbol = self.shell.user_ns[base_symbol_string]
86 elif base_symbol_string in self.shell.user_global_ns:
87 symbol = self.shell.user_global_ns[base_symbol_string]
88 elif base_symbol_string in __builtin__.__dict__:
89 symbol = __builtin__.__dict__[base_symbol_string]
90 else:
91 return False
92 for name in base_symbol_string.split('.')[1:] + ['__doc__']:
93 symbol = getattr(symbol, name)
94 self.CallTipShow(self.GetCurrentPos(), symbol)
95
76 96 def update_completion(self):
77 97 line = self.get_current_edit_buffer()
78 98 if self.AutoCompActive() and not line[-1] == '.':
79 99 line = line[:-1]
80 100 completions = self.complete(line)
81 101 choose_single = self.AutoCompGetChooseSingle()
82 102 self.AutoCompSetChooseSingle(False)
83 103 self.write_completion(completions, mode='popup')
84 104 self.AutoCompSetChooseSingle(choose_single)
85 105
86 106
87 107 def execute(self, python_string, raw_string=None):
88 108 self._cursor = wx.BusyCursor()
89 109 if raw_string is None:
90 110 raw_string = python_string
91 111 end_line = self.current_prompt_line \
92 112 + max(1, len(raw_string.split('\n'))-1)
93 113 for i in range(self.current_prompt_line, end_line):
94 114 self.MarkerAdd(i, 31)
95 115 PrefilterFrontEnd.execute(self, python_string, raw_string=raw_string)
96 116
97 117
98 118 def after_execute(self):
99 119 PrefilterFrontEnd.after_execute(self)
100 120 if hasattr(self, '_cursor'):
101 121 del self._cursor
102 122
103 123 #--------------------------------------------------------------------------
104 124 # Private API
105 125 #--------------------------------------------------------------------------
106 126
107 127
108 128 def _on_key_down(self, event, skip=True):
109 129 """ Capture the character events, let the parent
110 130 widget handle them, and put our logic afterward.
111 131 """
112 132 current_line_number = self.GetCurrentLine()
113 133 if self.AutoCompActive():
114 134 event.Skip()
115 135 if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE):
116 136 wx.CallAfter(self.do_completion)
117 137 elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
118 138 wx.WXK_RIGHT):
119 139 wx.CallAfter(self.update_completion)
120 140 else:
121 141 # Up history
122 142 if event.KeyCode == wx.WXK_UP and (
123 143 ( current_line_number == self.current_prompt_line and
124 144 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
125 145 or event.ControlDown() ):
126 146 new_buffer = self.get_history_previous(
127 147 self.get_current_edit_buffer())
128 148 if new_buffer is not None:
129 149 self.replace_current_edit_buffer(new_buffer)
130 150 if self.GetCurrentLine() > self.current_prompt_line:
131 151 # Go to first line, for seemless history up.
132 152 self.GotoPos(self.current_prompt_pos)
133 153 # Down history
134 154 elif event.KeyCode == wx.WXK_DOWN and (
135 155 ( current_line_number == self.LineCount -1 and
136 156 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
137 157 or event.ControlDown() ):
138 158 new_buffer = self.get_history_next()
139 159 if new_buffer is not None:
140 160 self.replace_current_edit_buffer(new_buffer)
141 161 elif event.KeyCode == ord('\t'):
142 162 last_line = self.get_current_edit_buffer().split('\n')[-1]
143 163 if not re.match(r'^\s*$', last_line):
144 164 self.do_completion(mode='text')
145 165 else:
146 166 event.Skip()
167 elif event.KeyCode == ord('('):
168 event.Skip()
169 self.do_calltip()
147 170 else:
148 171 ConsoleWidget._on_key_down(self, event, skip=skip)
149 172
150 173
151 174 def _on_key_up(self, event, skip=True):
152 175 if event.KeyCode == 59:
153 176 # Intercepting '.'
154 177 event.Skip()
155 178 #self.do_completion(mode='popup')
156 179 else:
157 180 ConsoleWidget._on_key_up(self, event, skip=skip)
158 181
159 182
160 183 if __name__ == '__main__':
161 184 class MainWindow(wx.Frame):
162 185 def __init__(self, parent, id, title):
163 186 wx.Frame.__init__(self, parent, id, title, size=(300,250))
164 187 self._sizer = wx.BoxSizer(wx.VERTICAL)
165 188 self.shell = IPythonWxController(self)
166 189 self._sizer.Add(self.shell, 1, wx.EXPAND)
167 190 self.SetSizer(self._sizer)
168 191 self.SetAutoLayout(1)
169 192 self.Show(True)
170 193
171 194 app = wx.PySimpleApp()
172 195 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
173 196 frame.shell.SetFocus()
174 197 frame.SetSize((660, 460))
175 198 self = frame.shell
176 199
177 200 app.MainLoop()
178 201
General Comments 0
You need to be logged in to leave comments. Login now