diff --git a/IPython/gui/wx/ipshell_nonblocking.py b/IPython/gui/wx/ipshell_nonblocking.py index 93e9dae..9fb2183 100644 --- a/IPython/gui/wx/ipshell_nonblocking.py +++ b/IPython/gui/wx/ipshell_nonblocking.py @@ -21,15 +21,13 @@ import re import sys import os import locale -import time -import pydoc,__builtin__,site from thread_ex import ThreadEx -from StringIO import StringIO try: - import IPython + import IPython except Exception,e: - raise "Error importing IPython (%s)" % str(e) + print "Error importing IPython (%s)" % str(e) + raise Exception, e ############################################################################## class _Helper(object): @@ -37,7 +35,7 @@ class _Helper(object): This is a wrapper around pydoc.help (with a twist). """ - def __init__(self,pager): + def __init__(self, pager): self._pager = pager def __repr__(self): @@ -46,10 +44,12 @@ class _Helper(object): def __call__(self, *args, **kwds): class DummyWriter(object): - def __init__(self,pager): + '''Dumy class to handle help output''' + def __init__(self, pager): self._pager = pager - def write(self,data): + def write(self, data): + '''hook to fill self._pager''' self._pager(data) import pydoc @@ -61,13 +61,14 @@ class _Helper(object): ############################################################################## class _CodeExecutor(ThreadEx): - + ''' Thread that execute ipython code ''' def __init__(self, instance, after): ThreadEx.__init__(self) self.instance = instance - self._afterExecute=after + self._afterExecute = after def run(self): + '''Thread main loop''' try: self.instance._doc_text = None self.instance._help_text = None @@ -90,7 +91,7 @@ class NonBlockingIPShell(object): via raise_exc() ''' - def __init__(self,argv=[],user_ns={},user_global_ns=None, + def __init__(self, argv=[], user_ns={}, user_global_ns=None, cin=None, cout=None, cerr=None, ask_exit_handler=None): ''' @@ -112,6 +113,8 @@ class NonBlockingIPShell(object): @type int ''' #ipython0 initialisation + self._IP = None + self._term = None self.initIpython0(argv, user_ns, user_global_ns, cin, cout, cerr, ask_exit_handler) @@ -134,6 +137,8 @@ class NonBlockingIPShell(object): def initIpython0(self, argv=[], user_ns={}, user_global_ns=None, cin=None, cout=None, cerr=None, ask_exit_handler=None): + ''' Initialize an ithon0 instance ''' + #first we redefine in/out/error functions of IPython if cin: IPython.Shell.Term.cin = cin @@ -151,20 +156,20 @@ class NonBlockingIPShell(object): excepthook = sys.excepthook self._IP = IPython.Shell.make_IPython( - argv,user_ns=user_ns, - user_global_ns=user_global_ns, - embedded=True, - shell_class=IPython.Shell.InteractiveShell) + argv,user_ns=user_ns, + user_global_ns=user_global_ns, + embedded=True, + shell_class=IPython.Shell.InteractiveShell) #we replace IPython default encoding by wx locale encoding loc = locale.getpreferredencoding() if loc: - self._IP.stdin_encoding = loc + self._IP.stdin_encoding = loc #we replace the ipython default pager by our pager - self._IP.set_hook('show_in_pager',self._pager) + self._IP.set_hook('show_in_pager', self._pager) #we replace the ipython default shell command caller by our shell handler - self._IP.set_hook('shell_hook',self._shell) + self._IP.set_hook('shell_hook', self._shell) #we replace the ipython default input command caller by our method IPython.iplib.raw_input_original = self._raw_input @@ -183,15 +188,15 @@ class NonBlockingIPShell(object): sys.excepthook = excepthook #----------------------- Thread management section ---------------------- - def doExecute(self,line): + def doExecute(self, line): """ Tell the thread to process the 'line' command """ self._line_to_execute = line #we launch the ipython line execution in a thread to make it interruptible - self.ce = _CodeExecutor(self,self._afterExecute) - self.ce.start() + ce = _CodeExecutor(self, self._afterExecute) + ce.start() #----------------------- IPython management section ---------------------- def getDocText(self): @@ -307,9 +312,9 @@ class NonBlockingIPShell(object): history = '' #the below while loop is used to suppress empty history lines while((history == '' or history == '\n') and self._history_level >0): - if self._history_level>=1: - self._history_level -= 1 - history = self._getHistory() + if self._history_level >= 1: + self._history_level -= 1 + history = self._getHistory() return history def historyForward(self): @@ -321,16 +326,17 @@ class NonBlockingIPShell(object): ''' history = '' #the below while loop is used to suppress empty history lines - while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()): - if self._history_level < self._getHistoryMaxIndex(): - self._history_level += 1 - history = self._getHistory() + while((history == '' or history == '\n') \ + and self._history_level <= self._getHistoryMaxIndex()): + if self._history_level < self._getHistoryMaxIndex(): + self._history_level += 1 + history = self._getHistory() + else: + if self._history_level == self._getHistoryMaxIndex(): + history = self._getHistory() + self._history_level += 1 else: - if self._history_level == self._getHistoryMaxIndex(): - history = self._getHistory() - self._history_level += 1 - else: - history = '' + history = '' return history def initHistoryIndex(self): @@ -371,24 +377,24 @@ class NonBlockingIPShell(object): rv = self._IP.input_hist_raw[self._history_level].strip('\n') return rv - def _pager_help(self,text): + def _pager_help(self, text): ''' This function is used as a callback replacment to IPython help pager function - It puts the 'text' value inside the self._help_text string that can be retrived via getHelpText - function. + It puts the 'text' value inside the self._help_text string that can be retrived via + getHelpText function. ''' if self._help_text == None: self._help_text = text else: self._help_text += text - def _pager(self,IP,text): + def _pager(self, IP, text): ''' This function is used as a callback replacment to IPython pager function - It puts the 'text' value inside the self._doc_text string that can be retrived via getDocText - function. + It puts the 'text' value inside the self._doc_text string that can be retrived via + getDocText function. ''' self._doc_text = text @@ -429,8 +435,7 @@ class NonBlockingIPShell(object): self._IP.showtraceback() else: self._iter_more = self._IP.push(line) - if (self._IP.SyntaxTB.last_syntax_error and - self._IP.rc.autoedit_syntax): + if (self._IP.SyntaxTB.last_syntax_error and self._IP.rc.autoedit_syntax): self._IP.edit_syntax_error() if self._iter_more: self._prompt = str(self._IP.outputcache.prompt2).strip() @@ -452,8 +457,8 @@ class NonBlockingIPShell(object): ''' stdin, stdout = os.popen4(cmd) result = stdout.read().decode('cp437').encode(locale.getpreferredencoding()) - #we use print command because the shell command is called inside IPython instance and thus is - #redirected to thread cout + #we use print command because the shell command is called + #inside IPython instance and thus is redirected to thread cout #"\x01\x1b[1;36m\x02" <-- add colour to the text... print "\x01\x1b[1;36m\x02"+result stdout.close() diff --git a/IPython/gui/wx/ipython_view.py b/IPython/gui/wx/ipython_view.py index 940dd8e..fa72bbd 100644 --- a/IPython/gui/wx/ipython_view.py +++ b/IPython/gui/wx/ipython_view.py @@ -28,13 +28,7 @@ import wx import wx.stc as stc import re -import sys -import locale from StringIO import StringIO -try: - import IPython -except Exception,e: - raise "Error importing IPython (%s)" % str(e) from ipshell_nonblocking import NonBlockingIPShell @@ -47,7 +41,7 @@ class WxNonBlockingIPShell(NonBlockingIPShell): cin=None, cout=None, cerr=None, ask_exit_handler=None): - NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, + NonBlockingIPShell.__init__(self, argv, user_ns, user_global_ns, cin, cout, cerr, ask_exit_handler) @@ -56,7 +50,7 @@ class WxNonBlockingIPShell(NonBlockingIPShell): self.ask_exit_callback = ask_exit_handler self._IP.exit = self._askExit - def addGUIShortcut(self,text,func): + def addGUIShortcut(self, text, func): wx.CallAfter(self.parent.add_button_handler, button_info={ 'text':text, 'func':self.parent.doExecuteLine(func)}) @@ -85,27 +79,27 @@ class WxConsoleView(stc.StyledTextCtrl): @ivar color_pat: Regex of terminal color pattern @type color_pat: _sre.SRE_Pattern ''' - ANSI_STYLES_BLACK={'0;30': [0,'WHITE'], '0;31': [1,'RED'], - '0;32': [2,'GREEN'], '0;33': [3,'BROWN'], - '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'], - '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'], - '1;30': [8,'DARK GREY'], '1;31': [9,'RED'], - '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'], - '1;34': [12,'LIGHT BLUE'], '1;35': - [13,'MEDIUM VIOLET RED'], - '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']} - - ANSI_STYLES_WHITE={'0;30': [0,'BLACK'], '0;31': [1,'RED'], - '0;32': [2,'GREEN'], '0;33': [3,'BROWN'], - '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'], - '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'], - '1;30': [8,'DARK GREY'], '1;31': [9,'RED'], - '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'], - '1;34': [12,'LIGHT BLUE'], '1;35': - [13,'MEDIUM VIOLET RED'], - '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']} - - def __init__(self,parent,prompt,intro="",background_color="BLACK", + ANSI_STYLES_BLACK = {'0;30': [0, 'WHITE'], '0;31': [1, 'RED'], + '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'], + '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'], + '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'], + '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'], + '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'], + '1;34': [12, 'LIGHT BLUE'], '1;35': + [13, 'MEDIUM VIOLET RED'], + '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']} + + ANSI_STYLES_WHITE = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'], + '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'], + '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'], + '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'], + '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'], + '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'], + '1;34': [12, 'LIGHT BLUE'], '1;35': + [13, 'MEDIUM VIOLET RED'], + '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']} + + def __init__(self, parent, prompt, intro="", background_color="BLACK", pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize, style=0, autocomplete_mode = 'IPYTHON'): ''' @@ -146,17 +140,17 @@ class WxConsoleView(stc.StyledTextCtrl): #self.SetUseAntiAliasing(True) self.SetLayoutCache(stc.STC_CACHE_PAGE) self.SetUndoCollection(False) - self.SetUseTabs(True) - self.SetIndent(4) - self.SetTabWidth(4) + self.SetUseTabs(True) + self.SetIndent(4) + self.SetTabWidth(4) self.EnsureCaretVisible() - self.SetMargins(3,3) #text is moved away from border with 3px + self.SetMargins(3, 3) #text is moved away from border with 3px # Suppressing Scintilla margins - self.SetMarginWidth(0,0) - self.SetMarginWidth(1,0) - self.SetMarginWidth(2,0) + self.SetMarginWidth(0, 0) + self.SetMarginWidth(1, 0) + self.SetMarginWidth(2, 0) self.background_color = background_color self.buildStyles() @@ -176,13 +170,13 @@ class WxConsoleView(stc.StyledTextCtrl): def buildStyles(self): #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, - } + 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', @@ -225,11 +219,11 @@ class WxConsoleView(stc.StyledTextCtrl): ####################################################################### - def setBackgroundColor(self,color): + def setBackgroundColor(self, color): self.background_color = color self.buildStyles() - def getBackgroundColor(self,color): + def getBackgroundColor(self, color): return self.background_color def asyncWrite(self, text): @@ -240,20 +234,20 @@ class WxConsoleView(stc.StyledTextCtrl): @type text: string ''' try: - #print >>sys.__stdout__,'entering' - wx.MutexGuiEnter() - #print >>sys.__stdout__,'locking the GUI' + #print >>sys.__stdout__,'entering' + wx.MutexGuiEnter() + #print >>sys.__stdout__,'locking the GUI' - #be sure not to be interrutpted before the MutexGuiLeave! - self.write(text) + #be sure not to be interrutpted before the MutexGuiLeave! + self.write(text) - #print >>sys.__stdout__,'done' + #print >>sys.__stdout__,'done' except KeyboardInterrupt: - #print >>sys.__stdout__,'got keyboard interrupt' - wx.MutexGuiLeave() - #print >>sys.__stdout__,'interrupt unlock the GUI' - raise KeyboardInterrupt + #print >>sys.__stdout__,'got keyboard interrupt' + wx.MutexGuiLeave() + #print >>sys.__stdout__,'interrupt unlock the GUI' + raise KeyboardInterrupt wx.MutexGuiLeave() #print >>sys.__stdout__,'normal unlock the GUI' @@ -267,7 +261,7 @@ class WxConsoleView(stc.StyledTextCtrl): ''' segments = self.color_pat.split(text) segment = segments.pop(0) - self.StartStyling(self.getCurrentLineEnd(),0xFF) + self.StartStyling(self.getCurrentLineEnd(), 0xFF) self.AppendText(segment) if segments: @@ -275,11 +269,11 @@ class WxConsoleView(stc.StyledTextCtrl): for tag in ansi_tags: i = segments.index(tag) - self.StartStyling(self.getCurrentLineEnd(),0xFF) + self.StartStyling(self.getCurrentLineEnd(), 0xFF) self.AppendText(segments[i+1]) if tag != '0': - self.SetStyling(len(segments[i+1]),self.ANSI_STYLES[tag][0]) + self.SetStyling(len(segments[i+1]), self.ANSI_STYLES[tag][0]) segments.pop(i) @@ -291,13 +285,13 @@ class WxConsoleView(stc.StyledTextCtrl): ''' return len(str(self.prompt_count)) + 7 - def setPrompt(self,prompt): + def setPrompt(self, prompt): self.prompt = prompt - def setIndentation(self,indentation): + def setIndentation(self, indentation): self.indent = indentation - def setPromptCount(self,count): + def setPromptCount(self, count): self.prompt_count = count def showPrompt(self): @@ -322,7 +316,7 @@ class WxConsoleView(stc.StyledTextCtrl): @param text: Text to use as replacement. @type text: string ''' - self.SetSelection(self.getCurrentPromptStart(),self.getCurrentLineEnd()) + self.SetSelection(self.getCurrentPromptStart(), self.getCurrentLineEnd()) self.ReplaceSelection(text) self.moveCursor(self.getCurrentLineEnd()) @@ -350,30 +344,30 @@ class WxConsoleView(stc.StyledTextCtrl): if self.GetCurrentPos() < self.getCurrentPromptStart(): self.GotoPos(self.getCurrentPromptStart()) - def removeFromTo(self,from_pos,to_pos): + def removeFromTo(self, from_pos, to_pos): if from_pos < to_pos: - self.SetSelection(from_pos,to_pos) + self.SetSelection(from_pos, to_pos) self.DeleteBack() def removeCurrentLine(self): self.LineDelete() - def moveCursor(self,position): + def moveCursor(self, position): self.GotoPos(position) def getCursorPos(self): return self.GetCurrentPos() - def selectFromTo(self,from_pos,to_pos): + def selectFromTo(self, from_pos, to_pos): self.SetSelectionStart(from_pos) self.SetSelectionEnd(to_pos) - def writeHistory(self,history): - self.removeFromTo(self.getCurrentPromptStart(),self.getCurrentLineEnd()) + def writeHistory(self, history): + self.removeFromTo(self.getCurrentPromptStart(), self.getCurrentLineEnd()) self.changeLine(history) def setCompletionMethod(self, completion): - if completion in ['IPYTHON','STC']: + if completion in ['IPYTHON', 'STC']: self.autocomplete_mode = completion else: raise AttributeError @@ -383,28 +377,26 @@ class WxConsoleView(stc.StyledTextCtrl): def writeCompletion(self, possibilities): if self.autocomplete_mode == 'IPYTHON': - max_len = len(max(possibilities,key=len)) - max_symbol =' '*max_len + max_len = len(max(possibilities, key=len)) + max_symbol = ' '*max_len #now we check how much symbol we can put on a line... - cursor_pos = self.getCursorPos() test_buffer = max_symbol + ' '*4 - current_lines = self.GetLineCount() allowed_symbols = 80/len(test_buffer) if allowed_symbols == 0: - allowed_symbols = 1 + allowed_symbols = 1 pos = 1 buf = '' for symbol in possibilities: #buf += symbol+'\n'#*spaces) - if pos>sys.__stdout__,"PAGER state:",self.pager_state - self.pager_nb_lines = len(self.pager_lines) - self.pager_index = 0 - self.pager_do_remove = False - self.text_ctrl.write('\n') - self.pager_state = 'PROCESS_LINES' + #print >>sys.__stdout__,"PAGER state:",self.pager_state + self.pager_nb_lines = len(self.pager_lines) + self.pager_index = 0 + self.pager_do_remove = False + self.text_ctrl.write('\n') + self.pager_state = 'PROCESS_LINES' if self.pager_state == 'PROCESS_LINES': - #print >>sys.__stdout__,"PAGER state:",self.pager_state - if self.pager_do_remove == True: - self.text_ctrl.removeCurrentLine() - self.pager_do_remove = False - - if self.pager_nb_lines > 10: - #print >>sys.__stdout__,"PAGER processing 10 lines" - if self.pager_index > 0: - self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') - else: - self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') - - for line in self.pager_lines[self.pager_index+1:self.pager_index+9]: - self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n') - self.pager_index += 10 - self.pager_nb_lines -= 10 - self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---") - self.pager_do_remove = True - self.pager_state = 'WAITING' - return + #print >>sys.__stdout__,"PAGER state:",self.pager_state + if self.pager_do_remove == True: + self.text_ctrl.removeCurrentLine() + self.pager_do_remove = False + + if self.pager_nb_lines > 10: + #print >>sys.__stdout__,"PAGER processing 10 lines" + if self.pager_index > 0: + self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') else: - #print >>sys.__stdout__,"PAGER processing last lines" - if self.pager_nb_lines > 0: - if self.pager_index > 0: - self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') - else: - self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') - - self.pager_index += 1 - self.pager_nb_lines -= 1 - if self.pager_nb_lines > 0: - for line in self.pager_lines[self.pager_index:]: - self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n') - self.pager_nb_lines = 0 - self.pager_state = 'DONE' - self.stateShowPrompt() - + self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') + + for line in self.pager_lines[self.pager_index+1:self.pager_index+9]: + self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n') + self.pager_index += 10 + self.pager_nb_lines -= 10 + self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---") + self.pager_do_remove = True + self.pager_state = 'WAITING' + return + else: + #print >>sys.__stdout__,"PAGER processing last lines" + if self.pager_nb_lines > 0: + if self.pager_index > 0: + self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') + else: + self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') + + self.pager_index += 1 + self.pager_nb_lines -= 1 + if self.pager_nb_lines > 0: + for line in self.pager_lines[self.pager_index:]: + self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n') + self.pager_nb_lines = 0 + self.pager_state = 'DONE' + self.stateShowPrompt() + #------------------------ Key Handler ------------------------------------ def keyPress(self, event): '''