From e402ed8013f26f5836956d6b5c9308be265a3428 2008-07-12 03:50:55 From: Gael Varoquaux Date: 2008-07-12 03:50:55 Subject: [PATCH] Clean up history. Tweak multiline input. Improve key handling. --- diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py index 36dff24..0fe178e 100644 --- a/IPython/frontend/wx/console_widget.py +++ b/IPython/frontend/wx/console_widget.py @@ -102,7 +102,6 @@ class ConsoleWidget(editwindow.EditWindow): 'IPYTHON' show autocompletion the ipython way 'STC" show it scintilla text control way """ - #stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style) editwindow.EditWindow.__init__(self, parent, id, pos, size, style) self.configure_scintilla() @@ -113,7 +112,7 @@ class ConsoleWidget(editwindow.EditWindow): self.autocomplete_mode = autocomplete_mode - self.Bind(wx.EVT_KEY_DOWN, self._onKeypress) + self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) def configure_scintilla(self): @@ -146,7 +145,6 @@ class ConsoleWidget(editwindow.EditWindow): self._apply_style() - self.indent = 0 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?') #self.SetEdgeMode(stc.STC_EDGE_LINE) @@ -175,9 +173,6 @@ class ConsoleWidget(editwindow.EditWindow): self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment']) - - - def write(self, text): """ Write given text to buffer, while translating the ansi escape sequences. @@ -215,10 +210,6 @@ class ConsoleWidget(editwindow.EditWindow): self.current_prompt_pos = self.GetLength() self.current_prompt_line = self.GetCurrentLine() - autoindent = self.indent * ' ' - autoindent = autoindent.replace(' ','\t') - self.write(autoindent) - def replace_current_edit_buffer(self, text): """ Replace currently entered command line with given text. @@ -243,39 +234,6 @@ class ConsoleWidget(editwindow.EditWindow): """ Applies the colors for the different text elements and the carret. """ - # FIXME: We need to do something for the fonts, but this is - # clearly not the right option. - #we define platform specific fonts -# if wx.Platform == '__WXMSW__': -# faces = { 'times': 'Times New Roman', -# 'mono' : 'Courier New', -# 'helv' : 'Arial', -# 'other': 'Comic Sans MS', -# 'size' : 10, -# 'size2': 8, -# } -# elif wx.Platform == '__WXMAC__': -# faces = { 'times': 'Times New Roman', -# 'mono' : 'Monaco', -# 'helv' : 'Arial', -# 'other': 'Comic Sans MS', -# 'size' : 10, -# 'size2': 8, -# } -# else: -# faces = { 'times': 'Times', -# 'mono' : 'Courier', -# 'helv' : 'Helvetica', -# 'other': 'new century schoolbook', -# 'size' : 10, -# 'size2': 8, -# } -# self.StyleSetSpec(stc.STC_STYLE_DEFAULT, -# "fore:%s,back:%s,size:%d,face:%s" -# % (self.ANSI_STYLES['0;30'][1], -# self.background_color, -# faces['size'], faces['mono'])) - self.SetCaretForeground(self.carret_color) self.StyleClearAll() @@ -335,7 +293,7 @@ class ConsoleWidget(editwindow.EditWindow): self.AutoCompShow(len(last_word), " ".join(possibilities)) - def _onKeypress(self, event, skip=True): + def _on_key_down(self, event, skip=True): """ Key press callback used for correcting behavior for console-like interfaces: the cursor is constraint to be after the last prompt. @@ -343,6 +301,11 @@ class ConsoleWidget(editwindow.EditWindow): Return True if event as been catched. """ catched = False + # Intercept annoying entries (eg: ctrl-D, ctrl-L) + if event.KeyCode in (68, 76) and event.ControlDown() : + skip = False + catched = True + if self.AutoCompActive(): event.Skip() else: @@ -351,7 +314,7 @@ class ConsoleWidget(editwindow.EditWindow): self.GotoPos(self.current_prompt_pos) catched = True - elif event.Modifiers == wx.MOD_SHIFT: + elif event.Modifiers in (wx.MOD_SHIFT, wx.MOD_WIN) : self.selectFromTo(self.current_prompt_pos, self.GetCurrentPos()) catched = True @@ -384,37 +347,6 @@ class ConsoleWidget(editwindow.EditWindow): return catched - def OnUpdateUI(self, evt): - # check for matching braces - braceAtCaret = -1 - braceOpposite = -1 - charBefore = None - caretPos = self.GetCurrentPos() - - if caretPos > 0: - charBefore = self.GetCharAt(caretPos - 1) - styleBefore = self.GetStyleAt(caretPos - 1) - - # check before - if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR: - braceAtCaret = caretPos - 1 - - # check after - if braceAtCaret < 0: - charAfter = self.GetCharAt(caretPos) - styleAfter = self.GetStyleAt(caretPos) - - if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR: - braceAtCaret = caretPos - - if braceAtCaret >= 0: - braceOpposite = self.BraceMatch(braceAtCaret) - - if braceAtCaret != -1 and braceOpposite == -1: - self.BraceBadLight(braceAtCaret) - else: - self.BraceHighlight(braceAtCaret, braceOpposite) - 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 aac0b24..a928006 100644 --- a/IPython/frontend/wx/wx_frontend.py +++ b/IPython/frontend/wx/wx_frontend.py @@ -1,7 +1,7 @@ -# encoding: utf-8 -# -*- test-case-name: ipython1.frontend.cocoa.tests.test_cocoa_frontend -*- +# encoding: utf-8 -*- test-case-name: +# ipython1.frontend.cocoa.tests.test_cocoa_frontend -*- -"""Classes to provide a Wx frontend to the +"""Classes to provide a Wx frontend to the ipython1.kernel.engineservice.EngineService. """ @@ -26,9 +26,9 @@ import re import IPython from IPython.kernel.engineservice import EngineService +from IPython.kernel.core.history import FrontEndHistory from IPython.frontend.frontendbase import FrontEndBase - #------------------------------------------------------------------------------- # Classes to implement the Wx frontend #------------------------------------------------------------------------------- @@ -59,15 +59,18 @@ class IPythonWxController(FrontEndBase, ConsoleWidget): """ Create Shell instance. """ ConsoleWidget.__init__(self, parent, id, pos, size, style) - FrontEndBase.__init__(self, engine=EngineService()) + FrontEndBase.__init__(self, engine=EngineService(), + ) + # FIXME: Something is wrong with the history, I instanciate it + # with an empty cache, but this is not the way to do. self.lines = {} - + # Start the IPython engine self.engine.startService() # Capture Character keys - self.Bind(wx.EVT_KEY_UP, self._on_key_up) + self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) #FIXME: print banner. banner = """IPython1 %s -- An enhanced Interactive Python.""" \ @@ -97,11 +100,13 @@ class IPythonWxController(FrontEndBase, ConsoleWidget): def render_result(self, result): - if 'stdout' in result: - self.write(result['stdout']) - if 'display' in result: - self.write(self.output_prompt % result['number'] - + result['display']['pprint']) + if 'stdout' in result and result['stdout']: + self.write('\n' + result['stdout']) + if 'display' in result and result['display']: + self.write("%s%s\n" % ( + self.output_prompt % result['number'], + result['display']['pprint'] + ) ) def render_error(self, failure): @@ -114,17 +119,36 @@ class IPythonWxController(FrontEndBase, ConsoleWidget): #-------------------------------------------------------------------------- - def _on_key_up(self, event, skip=True): + def _on_key_down(self, event, skip=True): """ Capture the character events, let the parent widget handle them, and put our logic afterward. """ - event.Skip() + current_line_number = self.GetCurrentLine() # Capture enter - if event.KeyCode == 13 and \ + 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 ( + ( 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) + # 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) + else: + ConsoleWidget._on_key_down(self, event, skip=True) + - def _on_enter(self): """ Called when the return key is pressed in a line editing buffer. @@ -132,21 +156,24 @@ class IPythonWxController(FrontEndBase, ConsoleWidget): current_buffer = self.get_current_edit_buffer() current_buffer = current_buffer.replace('\r\n', '\n') current_buffer = current_buffer.replace('\t', 4*' ') + cleaned_buffer = '\n'.join(l.rstrip() + for l in current_buffer.split('\n')) if ( not self.multi_line_input - or re.findall(r"\n[\t ]*\n[\t ]*$", current_buffer)): - if self.is_complete(current_buffer): - result = self.engine.shell.execute(current_buffer) + or re.findall(r"\n[\t ]*$", cleaned_buffer)): + if self.is_complete(cleaned_buffer): + self._add_history(None, cleaned_buffer.rstrip()) + result = self.engine.shell.execute(cleaned_buffer) self.render_result(result) - self.new_prompt(self.prompt % result['number']) + self.new_prompt(self.prompt % (result['number'] + 1)) self.multi_line_input = False else: if self.multi_line_input: - self.write(self._get_indent_string(current_buffer[:-1])) + self.write('\n' + self._get_indent_string(current_buffer)) else: self.multi_line_input = True - self.write('\t') + self.write('\n\t') else: - self.write(self._get_indent_string(current_buffer[:-1])) + self.write('\n'+self._get_indent_string(current_buffer)) def _get_indent_string(self, string): @@ -173,8 +200,8 @@ if __name__ == '__main__': app = wx.PySimpleApp() frame = MainWindow(None, wx.ID_ANY, 'Ipython') frame.shell.SetFocus() - frame.SetSize((780, 460)) - shell = frame.shell + frame.SetSize((660, 460)) + self = frame.shell # app.MainLoop()