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