diff --git a/IPython/frontend/linefrontendbase.py b/IPython/frontend/linefrontendbase.py index 27dd070..c82e645 100644 --- a/IPython/frontend/linefrontendbase.py +++ b/IPython/frontend/linefrontendbase.py @@ -87,8 +87,8 @@ class LineFrontEndBase(FrontEndBase): def is_complete(self, string): - if ( len(self.get_current_edit_buffer().split('\n'))>1 - and not re.findall(r"\n[\t ]*$", string)): + if ( len(self.get_current_edit_buffer().split('\n'))>2 + and not re.findall(r"\n[\t ]*\n[\t ]*$", string)): return False else: return FrontEndBase.is_complete(self, string) @@ -103,7 +103,7 @@ class LineFrontEndBase(FrontEndBase): # Create a false result, in case there is an exception self.last_result = dict(number=self.prompt_number) try: - self.history.input_cache[-1] = raw_string + self.history.input_cache[-1] = raw_string.rstrip() result = self.shell.execute(python_string) self.last_result = result self.render_result(result) @@ -121,8 +121,7 @@ class LineFrontEndBase(FrontEndBase): self.new_prompt(self.prompt % (self.last_result['number'] + 1)) # Start a new empty history entry self._add_history(None, '') - # The result contains useful information that can be used - # elsewhere. + self.history_cursor = len(self.history.input_cache) - 1 def _on_enter(self): @@ -131,13 +130,12 @@ class LineFrontEndBase(FrontEndBase): """ current_buffer = self.get_current_edit_buffer() cleaned_buffer = self.prefilter_input(current_buffer) - if self.is_complete(cleaned_buffer + '\n'): - # The '\n' is important in case prefiltering empties the - # line, to get a new prompt. + if self.is_complete(cleaned_buffer): self.execute(cleaned_buffer, raw_string=current_buffer) else: - if len(current_buffer.split('\n'))>1: - self.write(self._get_indent_string(current_buffer)) + if len(current_buffer.split('\n'))>2: + # We need to clean the trailing '\n' + self.write(self._get_indent_string(current_buffer[:-1])) else: self.write('\t') diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py index a845a0b..24765af 100644 --- a/IPython/frontend/wx/console_widget.py +++ b/IPython/frontend/wx/console_widget.py @@ -99,7 +99,7 @@ class ConsoleWidget(editwindow.EditWindow): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, - autocomplete_mode='IPYTHON'): + autocomplete_mode='STC'): """ Autocomplete_mode: Can be 'IPYTHON' or 'STC' 'IPYTHON' show autocompletion the ipython way 'STC" show it scintilla text control way @@ -152,7 +152,11 @@ class ConsoleWidget(editwindow.EditWindow): self.SetTabWidth(4) self.EnsureCaretVisible() - + # Tell autocompletion to choose automaticaly out of a single + # choice list + self.AutoCompSetChooseSingle(True) + self.AutoCompSetMaxHeight(10) + self.SetMargins(3, 3) #text is moved away from border with 3px # Suppressing Scintilla margins self.SetMarginWidth(0, 0) @@ -271,7 +275,7 @@ class ConsoleWidget(editwindow.EditWindow): self.StyleSetSpec(style[0], "bold,fore:%s" % style[1]) - def writeCompletion(self, possibilities): + def write_completion(self, possibilities): if self.autocomplete_mode == 'IPYTHON': max_len = len(max(possibilities, key=len)) max_symbol = ' '*max_len @@ -304,6 +308,7 @@ class ConsoleWidget(editwindow.EditWindow): last_word = self.get_current_edit_buffer() for breaker in splitter: last_word = last_word.split(breaker)[-1] + self.AutoCompSetMaxHeight(len(possibilities)) self.AutoCompShow(len(last_word), " ".join(possibilities)) @@ -329,7 +334,7 @@ class ConsoleWidget(editwindow.EditWindow): # Intercept some specific keys. if event.KeyCode == ord('L') and event.ControlDown() : self.scroll_to_bottom() - if event.KeyCode == ord('K') and event.ControlDown() : + elif event.KeyCode == ord('K') and event.ControlDown() : self.replace_current_edit_buffer('') elif event.KeyCode == wx.WXK_PAGEUP and event.ShiftDown(): self.ScrollPages(-1) diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py index 6997aed..0580b9a 100644 --- a/IPython/frontend/wx/wx_frontend.py +++ b/IPython/frontend/wx/wx_frontend.py @@ -22,6 +22,7 @@ __docformat__ = "restructuredtext en" import wx +import re from console_widget import ConsoleWidget from IPython.frontend.prefilterfrontend import PrefilterFrontEnd @@ -48,7 +49,23 @@ class IPythonWxController(PrefilterFrontEnd, ConsoleWidget): # Capture Character keys self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) - + + + def do_completion(self): + line = self.get_current_edit_buffer() + completions = self.complete(line) + self.write_completion(completions) + + + def execute(self, *args, **kwargs): + self._cursor = wx.BusyCursor() + PrefilterFrontEnd.execute(self, *args, **kwargs) + + + def after_execute(self): + PrefilterFrontEnd.after_execute(self) + del self._cursor + #-------------------------------------------------------------------------- # Private API #-------------------------------------------------------------------------- @@ -59,28 +76,37 @@ class IPythonWxController(PrefilterFrontEnd, ConsoleWidget): widget handle them, and put our logic afterward. """ current_line_number = self.GetCurrentLine() - # Up history - if event.KeyCode == wx.WXK_UP and ( - ( current_line_number == self.current_prompt_line and - event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) - or event.ControlDown() ): - new_buffer = self.get_history_previous( - self.get_current_edit_buffer()) - if new_buffer is not None: - self.replace_current_edit_buffer(new_buffer) - if self.GetCurrentLine() > self.current_prompt_line: - # Go to first line, for seemless history up. - self.GotoPos(self.current_prompt_pos) - # Down history - elif event.KeyCode == wx.WXK_DOWN and ( - ( current_line_number == self.LineCount -1 and - event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) - or event.ControlDown() ): - new_buffer = self.get_history_next() - if new_buffer is not None: - self.replace_current_edit_buffer(new_buffer) + if self.AutoCompActive(): + event.Skip() else: - ConsoleWidget._on_key_down(self, event, skip=skip) + # Up history + if event.KeyCode == wx.WXK_UP and ( + ( current_line_number == self.current_prompt_line and + event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) + or event.ControlDown() ): + new_buffer = self.get_history_previous( + self.get_current_edit_buffer()) + if new_buffer is not None: + self.replace_current_edit_buffer(new_buffer) + if self.GetCurrentLine() > self.current_prompt_line: + # Go to first line, for seemless history up. + self.GotoPos(self.current_prompt_pos) + # Down history + elif event.KeyCode == wx.WXK_DOWN and ( + ( current_line_number == self.LineCount -1 and + event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) + or event.ControlDown() ): + new_buffer = self.get_history_next() + if new_buffer is not None: + self.replace_current_edit_buffer(new_buffer) + elif event.KeyCode == ord('\t'): + last_line = self.get_current_edit_buffer().split('\n')[-1] + if not re.match(r'^\s*$', last_line): + self.do_completion() + else: + event.Skip() + else: + ConsoleWidget._on_key_down(self, event, skip=skip)