From fdaa4ba6bf7c05dfd608964ad0b034166f293547 2008-07-12 20:55:23 From: Gael Varoquaux Date: 2008-07-12 20:55:23 Subject: [PATCH] History is now working. + misc keybindings. --- diff --git a/IPython/frontend/frontendbase.py b/IPython/frontend/frontendbase.py index 932db6c..9d0ecfa 100644 --- a/IPython/frontend/frontendbase.py +++ b/IPython/frontend/frontendbase.py @@ -141,7 +141,7 @@ class IFrontEnd(Interface): pass - def get_history_previous(currentBlock): + def get_history_previous(current_block): """Returns the block previous in the history. Saves currentBlock if the history_cursor is currently at the end of the input history""" pass @@ -294,14 +294,14 @@ class FrontEndBase(object): return result - def get_history_previous(self, currentBlock): + def get_history_previous(self, current_block): """ Returns previous history string and decrement history cursor. """ command = self.history.get_history_item(self.history_cursor - 1) if command is not None: - if(self.history_cursor == len(self.history.input_cache)): - self.history.input_cache[self.history_cursor] = currentBlock + if(self.history_cursor+1 == len(self.history.input_cache)): + self.history.input_cache[self.history_cursor] = current_block self.history_cursor -= 1 return command diff --git a/IPython/frontend/linefrontendbase.py b/IPython/frontend/linefrontendbase.py index 30847c3..f71dab2 100644 --- a/IPython/frontend/linefrontendbase.py +++ b/IPython/frontend/linefrontendbase.py @@ -31,11 +31,6 @@ class LineFrontEndBase(FrontEndBase): # Are we entering multi line input? multi_line_input = False - # The added tab stop to the string. It may, for instance, come from - # copy and pasting something with tabs. - tab_stop = 0 - # FIXME: We still have to deal with this. - #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- @@ -81,7 +76,7 @@ class LineFrontEndBase(FrontEndBase): return failure - def on_enter(self): + def _on_enter(self): """ Called when the return key is pressed in a line editing buffer. """ @@ -93,11 +88,14 @@ class LineFrontEndBase(FrontEndBase): if ( not self.multi_line_input or re.findall(r"\n[\t ]*$", cleaned_buffer)): if self.is_complete(cleaned_buffer): - self._add_history(None, cleaned_buffer.rstrip()) + self.history.input_cache[-1] = \ + current_buffer result = self.shell.execute(cleaned_buffer) self.render_result(result) self.new_prompt(self.prompt % (result['number'] + 1)) self.multi_line_input = False + # Start a new empty history entry + self._add_history(None, '') else: if self.multi_line_input: self.write('\n' + self._get_indent_string(current_buffer)) diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py index c0d5c31..d132b52 100644 --- a/IPython/frontend/wx/console_widget.py +++ b/IPython/frontend/wx/console_widget.py @@ -113,6 +113,7 @@ class ConsoleWidget(editwindow.EditWindow): self.autocomplete_mode = autocomplete_mode self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) + self.Bind(wx.EVT_KEY_UP, self._on_key_up) def configure_scintilla(self): @@ -124,11 +125,11 @@ class ConsoleWidget(editwindow.EditWindow): self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT, stc.STC_CMD_ZOOMIN) - self.CmdKeyAssign(stc.STC_KEY_PRIOR, stc.STC_SCMOD_SHIFT, - stc.STC_CMD_PAGEUP) + #self.CmdKeyAssign(stc.STC_KEY_PRIOR, stc.STC_SCMOD_SHIFT, + # stc.STC_CMD_PAGEUP) - self.CmdKeyAssign(stc.STC_KEY_NEXT, stc.STC_SCMOD_SHIFT, - stc.STC_CMD_PAGEDOWN) + #self.CmdKeyAssign(stc.STC_KEY_NEXT, stc.STC_SCMOD_SHIFT, + # stc.STC_CMD_PAGEDOWN) # Keys: we need to clear some of the keys the that don't play # well with a console. @@ -259,17 +260,6 @@ class ConsoleWidget(editwindow.EditWindow): self.StyleSetSpec(style[0], "bold,fore:%s" % style[1]) - def removeFromTo(self, from_pos, to_pos): - if from_pos < to_pos: - self.SetSelection(from_pos, to_pos) - self.DeleteBack() - - - def selectFromTo(self, from_pos, to_pos): - self.SetSelectionStart(from_pos) - self.SetSelectionEnd(to_pos) - - def writeCompletion(self, possibilities): if self.autocomplete_mode == 'IPYTHON': max_len = len(max(possibilities, key=len)) @@ -310,6 +300,11 @@ class ConsoleWidget(editwindow.EditWindow): maxrange = self.GetScrollRange(wx.VERTICAL) self.ScrollLines(maxrange) + def on_enter(self): + """ Called when the return key is hit. + """ + pass + def _on_key_down(self, event, skip=True): """ Key press callback used for correcting behavior for @@ -319,22 +314,35 @@ class ConsoleWidget(editwindow.EditWindow): Return True if event as been catched. """ catched = False + # Intercept some specific keys. if event.KeyCode == ord('L') and event.ControlDown() : - skip = False catched = True self.scroll_to_bottom() + elif event.KeyCode == wx.WXK_PAGEUP and event.ShiftDown(): + catched = True + self.ScrollPages(-1) + elif event.KeyCode == wx.WXK_PAGEDOWN and event.ShiftDown(): + catched = True + self.ScrollPages(1) if self.AutoCompActive(): event.Skip() else: - if event.KeyCode == wx.WXK_HOME: + if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \ + event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN): + catched = True + self._on_enter() + + elif event.KeyCode == wx.WXK_HOME: if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN): self.GotoPos(self.current_prompt_pos) catched = True elif event.Modifiers in (wx.MOD_SHIFT, wx.MOD_WIN) : - self.selectFromTo(self.current_prompt_pos, - self.GetCurrentPos()) + # FIXME: This behavior is not ideal: if the selection + # is already started, it will jump. + self.SetSelectionStart(self.current_prompt_pos) + self.SetSelectionEnd(self.GetCurrentPos()) catched = True elif event.KeyCode == wx.WXK_UP: @@ -355,16 +363,18 @@ class ConsoleWidget(editwindow.EditWindow): if skip and not catched: event.Skip() - if event.KeyCode not in (wx.WXK_PAGEUP, wx.WXK_PAGEDOWN)\ - and event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN, - wx.MOD_SHIFT): - # If cursor is outside the editing region, put it back. - if self.GetCurrentPos() < self.current_prompt_pos: - self.GotoPos(self.current_prompt_pos) - return catched + def _on_key_up(self, event, skip=True): + """ If cursor is outside the editing region, put it back. + """ + event.Skip() + if self.GetCurrentPos() < self.current_prompt_pos: + self.GotoPos(self.current_prompt_pos) + + + if __name__ == '__main__': # Some simple code to test the console widget. diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py index 5bb0229..abf0272 100644 --- a/IPython/frontend/wx/wx_frontend.py +++ b/IPython/frontend/wx/wx_frontend.py @@ -63,12 +63,8 @@ class IPythonWxController(LineFrontEndBase, ConsoleWidget): widget handle them, and put our logic afterward. """ current_line_number = self.GetCurrentLine() - # Capture enter - if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \ - event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN): - self.on_enter() # Up history - elif event.KeyCode == wx.WXK_UP and ( + 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() ): @@ -76,6 +72,9 @@ class IPythonWxController(LineFrontEndBase, ConsoleWidget): 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 @@ -85,7 +84,7 @@ class IPythonWxController(LineFrontEndBase, ConsoleWidget): if new_buffer is not None: self.replace_current_edit_buffer(new_buffer) else: - ConsoleWidget._on_key_down(self, event, skip=True) + ConsoleWidget._on_key_down(self, event, skip=skip) diff --git a/IPython/kernel/core/history.py b/IPython/kernel/core/history.py index 1baa029..736aac6 100644 --- a/IPython/kernel/core/history.py +++ b/IPython/kernel/core/history.py @@ -56,7 +56,7 @@ class History(object): """ Returns the history string at index, where index is the distance from the end (positive). """ - if index>0 and index=0 and index