Show More
@@ -63,7 +63,7 b' _TRACE_STYLE = 17' | |||||
63 |
|
63 | |||
64 |
|
64 | |||
65 | # system colors |
|
65 | # system colors | |
66 | SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND) |
|
66 | #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND) | |
67 |
|
67 | |||
68 | #------------------------------------------------------------------------------- |
|
68 | #------------------------------------------------------------------------------- | |
69 | # The console widget class |
|
69 | # The console widget class | |
@@ -100,12 +100,7 b' class ConsoleWidget(editwindow.EditWindow):' | |||||
100 | #-------------------------------------------------------------------------- |
|
100 | #-------------------------------------------------------------------------- | |
101 |
|
101 | |||
102 | def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, |
|
102 | def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, | |
103 | size=wx.DefaultSize, style=0, |
|
103 | size=wx.DefaultSize, style=0, ): | |
104 | autocomplete_mode='popup'): |
|
|||
105 | """ Autocomplete_mode: Can be 'popup' or 'text' |
|
|||
106 | 'text' show autocompletion in the text buffer |
|
|||
107 | 'popup' show it with a dropdown popup |
|
|||
108 | """ |
|
|||
109 | editwindow.EditWindow.__init__(self, parent, id, pos, size, style) |
|
104 | editwindow.EditWindow.__init__(self, parent, id, pos, size, style) | |
110 | self.configure_scintilla() |
|
105 | self.configure_scintilla() | |
111 |
|
106 | |||
@@ -114,8 +109,6 b' class ConsoleWidget(editwindow.EditWindow):' | |||||
114 | '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02%i\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02' |
|
109 | '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02%i\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02' | |
115 | self.new_prompt(self.prompt % 1) |
|
110 | self.new_prompt(self.prompt % 1) | |
116 |
|
111 | |||
117 | self.autocomplete_mode = autocomplete_mode |
|
|||
118 |
|
||||
119 | self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) |
|
112 | self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) | |
120 | self.Bind(wx.EVT_KEY_UP, self._on_key_up) |
|
113 | self.Bind(wx.EVT_KEY_UP, self._on_key_up) | |
121 |
|
114 | |||
@@ -154,9 +147,10 b' class ConsoleWidget(editwindow.EditWindow):' | |||||
154 | self.SetTabWidth(4) |
|
147 | self.SetTabWidth(4) | |
155 |
|
148 | |||
156 | self.EnsureCaretVisible() |
|
149 | self.EnsureCaretVisible() | |
157 |
# |
|
150 | # we don't want scintilla's autocompletion to choose | |
158 | # choice list |
|
151 | # automaticaly out of a single choice list, as we pop it up | |
159 | self.AutoCompSetChooseSingle(True) |
|
152 | # automaticaly | |
|
153 | self.AutoCompSetChooseSingle(False) | |||
160 | self.AutoCompSetMaxHeight(10) |
|
154 | self.AutoCompSetMaxHeight(10) | |
161 |
|
155 | |||
162 | self.SetMargins(3, 3) #text is moved away from border with 3px |
|
156 | self.SetMargins(3, 3) #text is moved away from border with 3px | |
@@ -278,42 +272,41 b' class ConsoleWidget(editwindow.EditWindow):' | |||||
278 | self.StyleSetSpec(style[0], "bold,fore:%s" % style[1]) |
|
272 | self.StyleSetSpec(style[0], "bold,fore:%s" % style[1]) | |
279 |
|
273 | |||
280 |
|
274 | |||
281 |
def write_completion(self, possibilities |
|
275 | def write_completion(self, possibilities): | |
282 | if mode=='text' or self.autocomplete_mode == 'text': |
|
276 | # FIXME: This is non Wx specific and needs to be moved into | |
283 | # FIXME: This is non Wx specific and needs to be moved into |
|
277 | # the base class. | |
284 | # the base class. |
|
278 | current_buffer = self.get_current_edit_buffer() | |
285 | current_buffer = self.get_current_edit_buffer() |
|
279 | ||
286 |
|
280 | self.write('\n') | ||
287 | self.write('\n') |
|
281 | max_len = len(max(possibilities, key=len)) + 1 | |
288 | max_len = len(max(possibilities, key=len)) |
|
282 | ||
289 |
|
283 | #now we check how much symbol we can put on a line... | ||
290 | #now we check how much symbol we can put on a line... |
|
284 | chars_per_line = self.GetSize()[0]/self.GetCharWidth() | |
291 | chars_per_line = self.GetSize()[0]/self.GetCharWidth() |
|
285 | symbols_per_line = max(1, chars_per_line/max_len) | |
292 | symbols_per_line = max(1, chars_per_line/max_len) |
|
286 | ||
293 |
|
287 | pos = 1 | ||
294 |
|
|
288 | buf = [] | |
295 | buf = [] |
|
289 | for symbol in possibilities: | |
296 |
f |
|
290 | if pos < symbols_per_line: | |
297 |
|
|
291 | buf.append(symbol.ljust(max_len)) | |
298 | buf.append(symbol.ljust(max_len)) |
|
292 | pos += 1 | |
299 | pos += 1 |
|
293 | else: | |
300 | else: |
|
294 | buf.append(symbol.rstrip() +'\n') | |
301 | buf.append(symbol.rstrip() +'\n') |
|
295 | pos = 1 | |
302 | pos = 1 |
|
296 | self.write(''.join(buf)) | |
303 | self.write(''.join(buf)) |
|
297 | self.new_prompt(self.prompt % (self.last_result['number'] + 1)) | |
304 | self.new_prompt(self.prompt % (self.last_result['number'] + 1)) |
|
298 | self.replace_current_edit_buffer(current_buffer) | |
305 | self.replace_current_edit_buffer(current_buffer) |
|
299 | ||
306 |
|
300 | |||
307 | else: |
|
301 | def pop_completion(self, possibilities, offset=0): | |
308 | self.AutoCompSetIgnoreCase(False) |
|
302 | """ Pops up an autocompletion menu. Offset is the offset | |
309 | self.AutoCompSetAutoHide(False) |
|
303 | in characters of the position at which the menu should | |
310 | # compute the length ot the last word |
|
304 | appear, relativ to the cursor. | |
311 | separators = [' ', '(', '[', '{', '\n', '\t', '.'] |
|
305 | """ | |
312 | symbol = self.get_current_edit_buffer() |
|
306 | self.AutoCompSetIgnoreCase(False) | |
313 | for separator in separators: |
|
307 | self.AutoCompSetAutoHide(False) | |
314 | symbol = symbol.split(separator)[-1] |
|
308 | self.AutoCompSetMaxHeight(len(possibilities)) | |
315 |
|
|
309 | self.AutoCompShow(offset, " ".join(possibilities)) | |
316 | self.AutoCompShow(len(symbol), " ".join(possibilities)) |
|
|||
317 |
|
310 | |||
318 |
|
311 | |||
319 | def scroll_to_bottom(self): |
|
312 | def scroll_to_bottom(self): | |
@@ -344,6 +337,10 b' class ConsoleWidget(editwindow.EditWindow):' | |||||
344 | self.ScrollPages(-1) |
|
337 | self.ScrollPages(-1) | |
345 | elif event.KeyCode == wx.WXK_PAGEDOWN and event.ShiftDown(): |
|
338 | elif event.KeyCode == wx.WXK_PAGEDOWN and event.ShiftDown(): | |
346 | self.ScrollPages(1) |
|
339 | self.ScrollPages(1) | |
|
340 | elif event.KeyCode == wx.WXK_UP and event.ShiftDown(): | |||
|
341 | self.ScrollLines(-1) | |||
|
342 | elif event.KeyCode == wx.WXK_DOWN and event.ShiftDown(): | |||
|
343 | self.ScrollLinees(1) | |||
347 | else: |
|
344 | else: | |
348 | catched = False |
|
345 | catched = False | |
349 |
|
346 |
@@ -41,7 +41,7 b' _RUNNING_BUFFER_MARKER = 31' | |||||
41 | class IPythonWxController(PrefilterFrontEnd, ConsoleWidget): |
|
41 | class IPythonWxController(PrefilterFrontEnd, ConsoleWidget): | |
42 |
|
42 | |||
43 | output_prompt = \ |
|
43 | output_prompt = \ | |
44 | '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02' |
|
44 | '\n\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02' | |
45 |
|
45 | |||
46 | #-------------------------------------------------------------------------- |
|
46 | #-------------------------------------------------------------------------- | |
47 | # Public API |
|
47 | # Public API | |
@@ -64,14 +64,13 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
64 |
|
64 | |||
65 |
|
65 | |||
66 |
|
66 | |||
67 |
def do_completion(self |
|
67 | def do_completion(self): | |
68 | """ Do code completion. |
|
68 | """ Do code completion. | |
69 | mode can be 'text', 'popup' or 'none' to use default. |
|
|||
70 | """ |
|
69 | """ | |
71 | line = self.get_current_edit_buffer() |
|
70 | line = self.get_current_edit_buffer() | |
72 | new_line, completions = self.complete(line) |
|
71 | new_line, completions = self.complete(line) | |
73 | if len(completions)>1: |
|
72 | if len(completions)>1: | |
74 |
self.write_completion(completions |
|
73 | self.write_completion(completions) | |
75 | self.replace_current_edit_buffer(new_line) |
|
74 | self.replace_current_edit_buffer(new_line) | |
76 |
|
75 | |||
77 |
|
76 | |||
@@ -91,21 +90,31 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
91 | return False |
|
90 | return False | |
92 | for name in base_symbol_string.split('.')[1:] + ['__doc__']: |
|
91 | for name in base_symbol_string.split('.')[1:] + ['__doc__']: | |
93 | symbol = getattr(symbol, name) |
|
92 | symbol = getattr(symbol, name) | |
94 | self.CallTipShow(self.GetCurrentPos(), symbol) |
|
93 | try: | |
|
94 | self.CallTipShow(self.GetCurrentPos(), symbol) | |||
|
95 | except TypeError: | |||
|
96 | # The retrieve symbol couldn't be converted to a string | |||
|
97 | pass | |||
95 |
|
98 | |||
96 |
|
99 | |||
97 |
def up |
|
100 | def popup_completion(self, create=False): | |
|
101 | """ Updates the popup completion menu if it exists. If create is | |||
|
102 | true, open the menu. | |||
|
103 | """ | |||
98 | line = self.get_current_edit_buffer() |
|
104 | line = self.get_current_edit_buffer() | |
99 |
if self.AutoCompActive() and not line[-1] == '.' |
|
105 | if (self.AutoCompActive() and not line[-1] == '.') \ | |
100 | line = line[:-1] |
|
106 | or create==True: | |
101 | completions = self.complete(line) |
|
107 | suggestion, completions = self.complete(line) | |
102 | choose_single = self.AutoCompGetChooseSingle() |
|
108 | offset=0 | |
103 | self.AutoCompSetChooseSingle(False) |
|
109 | if completions: | |
104 | self.write_completion(completions, mode='popup') |
|
110 | complete_sep = re.compile('[\s\{\}\[\]\(\)\= ]') | |
105 | self.AutoCompSetChooseSingle(choose_single) |
|
111 | residual = complete_sep.split(line)[-1] | |
|
112 | offset = len(residual) | |||
|
113 | self.pop_completion(completions, offset=offset) | |||
106 |
|
114 | |||
107 |
|
115 | |||
108 | def execute(self, python_string, raw_string=None): |
|
116 | def execute(self, python_string, raw_string=None): | |
|
117 | self.CallTipCancel() | |||
109 | self._cursor = wx.BusyCursor() |
|
118 | self._cursor = wx.BusyCursor() | |
110 | if raw_string is None: |
|
119 | if raw_string is None: | |
111 | raw_string = python_string |
|
120 | raw_string = python_string | |
@@ -113,6 +122,10 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
113 | + max(1, len(raw_string.split('\n'))-1) |
|
122 | + max(1, len(raw_string.split('\n'))-1) | |
114 | for i in range(self.current_prompt_line, end_line): |
|
123 | for i in range(self.current_prompt_line, end_line): | |
115 | self.MarkerAdd(i, 31) |
|
124 | self.MarkerAdd(i, 31) | |
|
125 | # Remove the trailing "\n" for cleaner display | |||
|
126 | self.SetSelection(self.GetLength()-1, self.GetLength()) | |||
|
127 | self.ReplaceSelection('') | |||
|
128 | self.GotoPos(self.GetLength()) | |||
116 | PrefilterFrontEnd.execute(self, python_string, raw_string=raw_string) |
|
129 | PrefilterFrontEnd.execute(self, python_string, raw_string=raw_string) | |
117 |
|
130 | |||
118 |
|
131 | |||
@@ -134,10 +147,10 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
134 | if self.AutoCompActive(): |
|
147 | if self.AutoCompActive(): | |
135 | event.Skip() |
|
148 | event.Skip() | |
136 | if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE): |
|
149 | if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE): | |
137 |
wx.CallAfter(self. |
|
150 | wx.CallAfter(self.popup_completion) | |
138 | elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, |
|
151 | elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, | |
139 | wx.WXK_RIGHT): |
|
152 | wx.WXK_RIGHT): | |
140 |
wx.CallAfter(self.up |
|
153 | wx.CallAfter(self.popup_completion) | |
141 | else: |
|
154 | else: | |
142 | # Up history |
|
155 | # Up history | |
143 | if event.KeyCode == wx.WXK_UP and ( |
|
156 | if event.KeyCode == wx.WXK_UP and ( | |
@@ -162,7 +175,7 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
162 | elif event.KeyCode == ord('\t'): |
|
175 | elif event.KeyCode == ord('\t'): | |
163 | last_line = self.get_current_edit_buffer().split('\n')[-1] |
|
176 | last_line = self.get_current_edit_buffer().split('\n')[-1] | |
164 | if not re.match(r'^\s*$', last_line): |
|
177 | if not re.match(r'^\s*$', last_line): | |
165 |
self.do_completion( |
|
178 | self.do_completion() | |
166 | else: |
|
179 | else: | |
167 | event.Skip() |
|
180 | event.Skip() | |
168 | elif event.KeyCode == ord('('): |
|
181 | elif event.KeyCode == ord('('): | |
@@ -176,7 +189,7 b' class IPythonWxController(PrefilterFrontEnd, ConsoleWidget):' | |||||
176 | if event.KeyCode == 59: |
|
189 | if event.KeyCode == 59: | |
177 | # Intercepting '.' |
|
190 | # Intercepting '.' | |
178 | event.Skip() |
|
191 | event.Skip() | |
179 |
|
|
192 | self.popup_completion(create=True) | |
180 | else: |
|
193 | else: | |
181 | ConsoleWidget._on_key_up(self, event, skip=skip) |
|
194 | ConsoleWidget._on_key_up(self, event, skip=skip) | |
182 |
|
195 | |||
@@ -195,7 +208,7 b" if __name__ == '__main__':" | |||||
195 | app = wx.PySimpleApp() |
|
208 | app = wx.PySimpleApp() | |
196 | frame = MainWindow(None, wx.ID_ANY, 'Ipython') |
|
209 | frame = MainWindow(None, wx.ID_ANY, 'Ipython') | |
197 | frame.shell.SetFocus() |
|
210 | frame.shell.SetFocus() | |
198 |
frame.SetSize((6 |
|
211 | frame.SetSize((680, 460)) | |
199 | self = frame.shell |
|
212 | self = frame.shell | |
200 |
|
213 | |||
201 | app.MainLoop() |
|
214 | app.MainLoop() |
General Comments 0
You need to be logged in to leave comments.
Login now