Show More
@@ -295,6 +295,17 b' class LineFrontEndBase(FrontEndBase):' | |||
|
295 | 295 | self.write(prompt) |
|
296 | 296 | |
|
297 | 297 | |
|
298 | def continuation_prompt(self): | |
|
299 | """Returns the current continuation prompt. | |
|
300 | Overridden to generate a continuation prompt matching the length of the | |
|
301 | current prompt.""" | |
|
302 | ||
|
303 | # FIXME: This is a bad hack.. I need to find a way to use the 'Prompt2' | |
|
304 | # class in IPython/kernel/prompts.py. Basically, I am trying to get the | |
|
305 | # length of the current prompt ("In ['number']"). | |
|
306 | return ("."*(5+len(str(self.last_result['number']))) + ':') | |
|
307 | ||
|
308 | ||
|
298 | 309 | def execute_command(self, command, hidden=False): |
|
299 | 310 | """ Execute a command, not only in the model, but also in the |
|
300 | 311 | view, if any. |
@@ -310,14 +321,19 b' class LineFrontEndBase(FrontEndBase):' | |||
|
310 | 321 | buffer. |
|
311 | 322 | """ |
|
312 | 323 | current_buffer = self.input_buffer |
|
313 | cleaned_buffer = self.prefilter_input(current_buffer) | |
|
324 | # XXX: This string replace is ugly, but there should be no way it | |
|
325 | # fails. | |
|
326 | prompt_less_buffer = re.sub('^' + self.continuation_prompt(), | |
|
327 | '', current_buffer).replace('\n' + self.continuation_prompt(), | |
|
328 | '\n') | |
|
329 | cleaned_buffer = self.prefilter_input(prompt_less_buffer) | |
|
314 | 330 | if self.is_complete(cleaned_buffer): |
|
315 | 331 | self.execute(cleaned_buffer, raw_string=current_buffer) |
|
316 | 332 | else: |
|
317 |
self.input_buffer += self. |
|
|
318 | current_buffer[:-1]) | |
|
333 | self.input_buffer += self.continuation_prompt() + \ | |
|
334 | self._get_indent_string(prompt_less_buffer[:-1]) | |
|
319 | 335 | if len(current_buffer.split('\n')) == 2: |
|
320 |
self.input_buffer += '\t |
|
|
336 | self.input_buffer += '\t' | |
|
321 | 337 | if current_buffer[:-1].split('\n')[-1].rstrip().endswith(':'): |
|
322 | 338 | self.input_buffer += '\t' |
|
323 | 339 |
@@ -24,6 +24,7 b' __docformat__ = "restructuredtext en"' | |||
|
24 | 24 | import sys |
|
25 | 25 | import pydoc |
|
26 | 26 | import os |
|
27 | import re | |
|
27 | 28 | import __builtin__ |
|
28 | 29 | |
|
29 | 30 | from IPython.ipmaker import make_IPython |
@@ -113,9 +114,9 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||
|
113 | 114 | |
|
114 | 115 | |
|
115 | 116 | if not 'banner' in kwargs and self.banner is None: |
|
116 |
self.banner = self.ipython0.BANNER |
|
|
117 | This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code.""" | |
|
117 | self.banner = self.ipython0.BANNER | |
|
118 | 118 | |
|
119 | # FIXME: __init__ and start should be two different steps | |
|
119 | 120 | self.start() |
|
120 | 121 | |
|
121 | 122 | #-------------------------------------------------------------------------- |
@@ -182,7 +183,9 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
182 | 183 | def complete(self, line): |
|
183 | 184 | # FIXME: This should be factored out in the linefrontendbase |
|
184 | 185 | # method. |
|
186 | word = self._get_completion_text(line) | |
|
185 | 187 | word = line.split('\n')[-1].split(' ')[-1] |
|
188 | print 'Completion', word | |
|
186 | 189 | completions = self.ipython0.complete(word) |
|
187 | 190 | # FIXME: The proper sort should be done in the complete method. |
|
188 | 191 | key = lambda x: x.replace('_', '') |
@@ -255,3 +258,18 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
255 | 258 | """ |
|
256 | 259 | self.ipython0.atexit_operations() |
|
257 | 260 | |
|
261 | ||
|
262 | def _get_completion_text(self, line): | |
|
263 | """ Returns the text to be completed by breaking the line at specified | |
|
264 | delimiters. | |
|
265 | """ | |
|
266 | # Break at: spaces, '=', all parentheses (except if balanced). | |
|
267 | # FIXME2: In the future, we need to make the implementation similar to | |
|
268 | # that in the 'pyreadline' module (modes/basemode.py) where we break at | |
|
269 | # each delimiter and try to complete the residual line, until we get a | |
|
270 | # successful list of completions. | |
|
271 | expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})' | |
|
272 | complete_sep = re.compile(expression) | |
|
273 | text = complete_sep.split(line)[-1] | |
|
274 | return text | |
|
275 |
@@ -216,6 +216,16 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
216 | 216 | """ |
|
217 | 217 | return self.GetSize()[0]/self.GetCharWidth() |
|
218 | 218 | |
|
219 | ||
|
220 | def clear_screen(self): | |
|
221 | """ Empty completely the widget. | |
|
222 | """ | |
|
223 | self.ClearAll() | |
|
224 | self.new_prompt(self.input_prompt_template.substitute( | |
|
225 | number=(self.last_result['number'] + 1))) | |
|
226 | ||
|
227 | ||
|
228 | ||
|
219 | 229 | #-------------------------------------------------------------------------- |
|
220 | 230 | # EditWindow API |
|
221 | 231 | #-------------------------------------------------------------------------- |
@@ -391,15 +401,16 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
391 | 401 | catched = True |
|
392 | 402 | |
|
393 | 403 | elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK): |
|
394 | if self.GetCurrentPos() > self.current_prompt_pos: | |
|
404 | if not self._keep_cursor_in_buffer(): | |
|
395 | 405 | event.Skip() |
|
396 | 406 | catched = True |
|
397 | 407 | |
|
398 | 408 | if skip and not catched: |
|
399 | 409 | # Put the cursor back in the edit region |
|
400 | if self.GetCurrentPos() < self.current_prompt_pos: | |
|
401 | self.GotoPos(self.current_prompt_pos) | |
|
402 | else: | |
|
410 | if not self._keep_cursor_in_buffer(): | |
|
411 | if (self.GetCurrentPos() == self.GetLength() | |
|
412 | and event.KeyCode == wx.WXK_DELETE): | |
|
413 | pass | |
|
403 | 414 | event.Skip() |
|
404 | 415 | |
|
405 | 416 | return catched |
@@ -408,9 +419,44 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
408 | 419 | def _on_key_up(self, event, skip=True): |
|
409 | 420 | """ If cursor is outside the editing region, put it back. |
|
410 | 421 | """ |
|
422 | if skip: | |
|
411 | 423 | event.Skip() |
|
412 | if self.GetCurrentPos() < self.current_prompt_pos: | |
|
424 | self._keep_cursor_in_buffer() | |
|
425 | ||
|
426 | ||
|
427 | def _keep_cursor_in_buffer(self): | |
|
428 | """ Checks if the cursor is where it is allowed to be. If not, | |
|
429 | put it back. | |
|
430 | ||
|
431 | Returns | |
|
432 | ------- | |
|
433 | cursor_moved: Boolean | |
|
434 | whether or not the cursor was moved by this routine. | |
|
435 | ||
|
436 | Notes | |
|
437 | ------ | |
|
438 | WARNING: This does proper checks only for horizontal | |
|
439 | movements. | |
|
440 | """ | |
|
441 | current_pos = self.GetCurrentPos() | |
|
442 | if current_pos < self.current_prompt_pos: | |
|
413 | 443 | self.GotoPos(self.current_prompt_pos) |
|
444 | return True | |
|
445 | line, line_pos = self.GetCurLine() | |
|
446 | # Jump the continuation prompt | |
|
447 | continuation_prompt = self.continuation_prompt() | |
|
448 | if ( line.startswith(continuation_prompt) | |
|
449 | and line_pos < len(continuation_prompt)+1): | |
|
450 | if line_pos < 2: | |
|
451 | # We are at the beginning of the line, trying to move | |
|
452 | # forward: jump forward. | |
|
453 | self.GotoPos(current_pos + 1 + | |
|
454 | len(continuation_prompt) - line_pos) | |
|
455 | else: | |
|
456 | # Jump back up | |
|
457 | self.GotoPos(self.GetLineEndPosition(self.GetCurrentLine()-1)) | |
|
458 | return True | |
|
459 | return False | |
|
414 | 460 | |
|
415 | 461 | |
|
416 | 462 |
@@ -485,6 +485,12 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
485 | 485 | wx.CallAfter(self._popup_completion, create=True) |
|
486 | 486 | else: |
|
487 | 487 | ConsoleWidget._on_key_up(self, event, skip=skip) |
|
488 | if (self.input_buffer.split('\n')[-1] == self.continuation_prompt() | |
|
489 | and self._input_state == 'readline'): | |
|
490 | # Make sure the continuation_prompt is followed by a whitespace | |
|
491 | position = self.GetCurrentPos() | |
|
492 | self.input_buffer += ' ' | |
|
493 | self.GotoPos(position) | |
|
488 | 494 | |
|
489 | 495 | |
|
490 | 496 | def _on_enter(self): |
General Comments 0
You need to be logged in to leave comments.
Login now