Show More
@@ -111,6 +111,29 b' class NonBlockingIPShell(object):' | |||||
111 | @param time_loop: Define the sleep time between two thread's loop |
|
111 | @param time_loop: Define the sleep time between two thread's loop | |
112 | @type int |
|
112 | @type int | |
113 | ''' |
|
113 | ''' | |
|
114 | #ipython0 initialisation | |||
|
115 | self.initIpython0(argv, user_ns, user_global_ns, | |||
|
116 | cin, cout, cerr, | |||
|
117 | ask_exit_handler) | |||
|
118 | ||||
|
119 | #vars used by _execute | |||
|
120 | self._iter_more = 0 | |||
|
121 | self._history_level = 0 | |||
|
122 | self._complete_sep = re.compile('[\s\{\}\[\]\(\)]') | |||
|
123 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |||
|
124 | ||||
|
125 | #thread working vars | |||
|
126 | self._line_to_execute = '' | |||
|
127 | ||||
|
128 | #vars that will be checked by GUI loop to handle thread states... | |||
|
129 | #will be replaced later by PostEvent GUI funtions... | |||
|
130 | self._doc_text = None | |||
|
131 | self._help_text = None | |||
|
132 | self._add_button = None | |||
|
133 | ||||
|
134 | def initIpython0(self, argv=[], user_ns={}, user_global_ns=None, | |||
|
135 | cin=None, cout=None, cerr=None, | |||
|
136 | ask_exit_handler=None): | |||
114 | #first we redefine in/out/error functions of IPython |
|
137 | #first we redefine in/out/error functions of IPython | |
115 | if cin: |
|
138 | if cin: | |
116 | IPython.Shell.Term.cin = cin |
|
139 | IPython.Shell.Term.cin = cin | |
@@ -146,32 +169,12 b' class NonBlockingIPShell(object):' | |||||
146 | #we replace the ipython default input command caller by our method |
|
169 | #we replace the ipython default input command caller by our method | |
147 | IPython.iplib.raw_input_original = self._raw_input |
|
170 | IPython.iplib.raw_input_original = self._raw_input | |
148 | #we replace the ipython default exit command by our method |
|
171 | #we replace the ipython default exit command by our method | |
149 |
self._IP.exit = |
|
172 | self._IP.exit = ask_exit_handler | |
150 | #we modify Exit and Quit Magic |
|
|||
151 | ip = IPython.ipapi.get() |
|
|||
152 | ip.expose_magic('Exit', self._setDoExit) |
|
|||
153 | ip.expose_magic('Quit', self._setDoExit) |
|
|||
154 | #we replace the help command |
|
173 | #we replace the help command | |
155 | self._IP.user_ns['help'] = _Helper(self._pager_help) |
|
174 | self._IP.user_ns['help'] = _Helper(self._pager_help) | |
156 |
|
175 | |||
157 | sys.excepthook = excepthook |
|
176 | sys.excepthook = excepthook | |
158 |
|
177 | |||
159 | #vars used by _execute |
|
|||
160 | self._iter_more = 0 |
|
|||
161 | self._history_level = 0 |
|
|||
162 | self._complete_sep = re.compile('[\s\{\}\[\]\(\)]') |
|
|||
163 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
|||
164 |
|
||||
165 | #thread working vars |
|
|||
166 | self._line_to_execute = '' |
|
|||
167 |
|
||||
168 | #vars that will be checked by GUI loop to handle thread states... |
|
|||
169 | #will be replaced later by PostEvent GUI funtions... |
|
|||
170 | self._doc_text = None |
|
|||
171 | self._help_text = None |
|
|||
172 | self._ask_exit = False |
|
|||
173 | self._add_button = None |
|
|||
174 |
|
||||
175 | #----------------------- Thread management section ---------------------- |
|
178 | #----------------------- Thread management section ---------------------- | |
176 | def doExecute(self,line): |
|
179 | def doExecute(self,line): | |
177 | """ |
|
180 | """ | |
@@ -179,24 +182,11 b' class NonBlockingIPShell(object):' | |||||
179 | """ |
|
182 | """ | |
180 |
|
183 | |||
181 | self._line_to_execute = line |
|
184 | self._line_to_execute = line | |
182 |
|
185 | #we launch the ipython line execution in a thread to make it interruptible | ||
183 | self.ce = _CodeExecutor(self,self._afterExecute) |
|
186 | self.ce = _CodeExecutor(self,self._afterExecute) | |
184 | self.ce.start() |
|
187 | self.ce.start() | |
185 |
|
188 | |||
186 | #----------------------- IPython management section ---------------------- |
|
189 | #----------------------- IPython management section ---------------------- | |
187 | def getAskExit(self): |
|
|||
188 | ''' |
|
|||
189 | returns the _ask_exit variable that can be checked by GUI to see if |
|
|||
190 | IPython request an exit handling |
|
|||
191 | ''' |
|
|||
192 | return self._ask_exit |
|
|||
193 |
|
||||
194 | def clearAskExit(self): |
|
|||
195 | ''' |
|
|||
196 | clear the _ask_exit var when GUI as handled the request. |
|
|||
197 | ''' |
|
|||
198 | self._ask_exit = False |
|
|||
199 |
|
||||
200 | def getDocText(self): |
|
190 | def getDocText(self): | |
201 | """ |
|
191 | """ | |
202 | Returns the output of the processing that need to be paged (if any) |
|
192 | Returns the output of the processing that need to be paged (if any) | |
@@ -349,20 +339,12 b' class NonBlockingIPShell(object):' | |||||
349 | ''' |
|
339 | ''' | |
350 | pass |
|
340 | pass | |
351 |
|
341 | |||
352 |
|
|
342 | #def _askExit(self): | |
353 | ''' |
|
343 | # ''' | |
354 | set the _ask_exit variable that can be checked by GUI to see if |
|
344 | # Can be redefined to generate post event to exit the Ipython shell | |
355 | IPython request an exit handling |
|
345 | # ''' | |
356 |
|
|
346 | # pass | |
357 | self._ask_exit = True |
|
|||
358 |
|
347 | |||
359 | def _setDoExit(self, toto, arg): |
|
|||
360 | ''' |
|
|||
361 | set the _do_exit variable that can be checked by GUI to see if |
|
|||
362 | IPython do a direct exit of the app |
|
|||
363 | ''' |
|
|||
364 | self._do_exit = True |
|
|||
365 |
|
||||
366 | def _getHistoryMaxIndex(self): |
|
348 | def _getHistoryMaxIndex(self): | |
367 | ''' |
|
349 | ''' | |
368 | returns the max length of the history buffer |
|
350 | returns the max length of the history buffer |
@@ -37,8 +37,8 b' try:' | |||||
37 | except Exception,e: |
|
37 | except Exception,e: | |
38 | raise "Error importing IPython (%s)" % str(e) |
|
38 | raise "Error importing IPython (%s)" % str(e) | |
39 |
|
39 | |||
|
40 | from ipshell_nonblocking import NonBlockingIPShell | |||
40 |
|
41 | |||
41 | from non_blocking_ip_shell import NonBlockingIPShell |
|
|||
42 |
|
42 | |||
43 | class WxNonBlockingIPShell(NonBlockingIPShell): |
|
43 | class WxNonBlockingIPShell(NonBlockingIPShell): | |
44 | ''' |
|
44 | ''' | |
@@ -50,20 +50,19 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||||
50 | ask_exit_handler=None): |
|
50 | ask_exit_handler=None): | |
51 |
|
51 | |||
52 | NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, |
|
52 | NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, | |
53 | cin, cout, cerr, |
|
53 | cin, cout, cerr, | |
54 | ask_exit_handler) |
|
54 | ask_exit_handler) | |
55 |
|
55 | |||
56 | self.parent = parent |
|
56 | self.parent = parent | |
57 |
|
57 | |||
58 | self.ask_exit_callback = ask_exit_handler |
|
58 | self.ask_exit_callback = ask_exit_handler | |
59 |
self._IP. |
|
59 | self._IP.exit = self._askExit | |
60 |
|
60 | |||
61 |
|
||||
62 | def addGUIShortcut(self,text,func): |
|
61 | def addGUIShortcut(self,text,func): | |
63 | wx.CallAfter(self.parent.add_button_handler, |
|
62 | wx.CallAfter(self.parent.add_button_handler, | |
64 | button_info={ 'text':text, |
|
63 | button_info={ 'text':text, | |
65 | 'func':self.parent.doExecuteLine(func)}) |
|
64 | 'func':self.parent.doExecuteLine(func)}) | |
66 |
|
65 | |||
67 | def _askExit(self): |
|
66 | def _askExit(self): | |
68 | wx.CallAfter(self.ask_exit_callback, ()) |
|
67 | wx.CallAfter(self.ask_exit_callback, ()) | |
69 |
|
68 | |||
@@ -475,7 +474,7 b' class IPShellWidget(wx.Panel):' | |||||
475 | ''' |
|
474 | ''' | |
476 | wx.Panel.__init__(self,parent,-1) |
|
475 | wx.Panel.__init__(self,parent,-1) | |
477 |
|
476 | |||
478 |
### IPython |
|
477 | ### IPython non blocking shell instanciation ### | |
479 | self.cout = StringIO() |
|
478 | self.cout = StringIO() | |
480 |
|
479 | |||
481 | self.add_button_handler = add_button_handler |
|
480 | self.add_button_handler = add_button_handler | |
@@ -487,6 +486,7 b' class IPShellWidget(wx.Panel):' | |||||
487 | self.IP = WxNonBlockingIPShell(self, |
|
486 | self.IP = WxNonBlockingIPShell(self, | |
488 | cout=self.cout,cerr=self.cout, |
|
487 | cout=self.cout,cerr=self.cout, | |
489 | ask_exit_handler = ask_exit_handler) |
|
488 | ask_exit_handler = ask_exit_handler) | |
|
489 | ||||
490 | ### IPython wx console view instanciation ### |
|
490 | ### IPython wx console view instanciation ### | |
491 | #If user didn't defined an intro text, we create one for him |
|
491 | #If user didn't defined an intro text, we create one for him | |
492 | #If you really wnat an empty intrp just call wxIPythonViewPanel |
|
492 | #If you really wnat an empty intrp just call wxIPythonViewPanel | |
@@ -514,39 +514,36 b' class IPShellWidget(wx.Panel):' | |||||
514 | #and we focus on the widget :) |
|
514 | #and we focus on the widget :) | |
515 | self.SetFocus() |
|
515 | self.SetFocus() | |
516 |
|
516 | |||
517 | self.cur_state = 'IDLE' |
|
517 | #widget state management (for key handling different cases) | |
|
518 | self.setCurrentState('IDLE') | |||
518 | self.pager_state = 'DONE' |
|
519 | self.pager_state = 'DONE' | |
519 |
|
520 | |||
520 | #---------------------- IPython Thread Management ------------------------ |
|
521 | #---------------------- IPython Thread Management ------------------------ | |
521 | def stateDoExecuteLine(self): |
|
522 | def stateDoExecuteLine(self): | |
522 | #print >>sys.__stdout__,"command:",self.getCurrentLine() |
|
523 | #print >>sys.__stdout__,"command:",self.getCurrentLine() | |
523 |
|
|
524 | line=self.text_ctrl.getCurrentLine() | |
524 |
|
||||
525 | def doExecuteLine(self,line): |
|
|||
526 | #print >>sys.__stdout__,"command:",line |
|
|||
527 | self.IP.doExecute(line.replace('\t',' '*4)) |
|
525 | self.IP.doExecute(line.replace('\t',' '*4)) | |
528 | self.updateHistoryTracker(self.text_ctrl.getCurrentLine()) |
|
526 | self.updateHistoryTracker(self.text_ctrl.getCurrentLine()) | |
529 |
self. |
|
527 | self.setCurrentState('WAIT_END_OF_EXECUTION') | |
530 |
|
||||
531 |
|
528 | |||
532 | def evtStateExecuteDone(self,evt): |
|
529 | def evtStateExecuteDone(self,evt): | |
533 | self.doc = self.IP.getDocText() |
|
530 | self.doc = self.IP.getDocText() | |
534 | self.help = self.IP.getHelpText() |
|
531 | self.help = self.IP.getHelpText() | |
535 | if self.doc: |
|
532 | if self.doc: | |
536 |
self.pager_ |
|
533 | self.pager_lines = self.doc[7:].split('\n') | |
537 |
|
|
534 | self.pager_state = 'INIT' | |
|
535 | self.setCurrentState('SHOW_DOC') | |||
538 | self.pager(self.doc) |
|
536 | self.pager(self.doc) | |
539 | #if self.pager_state == 'DONE': |
|
537 | elif self.help: | |
540 | if self.help: |
|
538 | self.pager_lines = self.help.split('\n') | |
541 |
|
|
539 | self.pager_state = 'INIT' | |
542 |
self. |
|
540 | self.setCurrentState('SHOW_DOC') | |
543 | self.pager(self.help) |
|
541 | self.pager(self.help) | |
544 |
|
||||
545 | else: |
|
542 | else: | |
546 | self.stateShowPrompt() |
|
543 | self.stateShowPrompt() | |
547 |
|
544 | |||
548 | def stateShowPrompt(self): |
|
545 | def stateShowPrompt(self): | |
549 |
self. |
|
546 | self.setCurrentState('SHOW_PROMPT') | |
550 | self.text_ctrl.setPrompt(self.IP.getPrompt()) |
|
547 | self.text_ctrl.setPrompt(self.IP.getPrompt()) | |
551 | self.text_ctrl.setIndentation(self.IP.getIndentation()) |
|
548 | self.text_ctrl.setIndentation(self.IP.getIndentation()) | |
552 | self.text_ctrl.setPromptCount(self.IP.getPromptCount()) |
|
549 | self.text_ctrl.setPromptCount(self.IP.getPromptCount()) | |
@@ -555,62 +552,53 b' class IPShellWidget(wx.Panel):' | |||||
555 | self.text_ctrl.showReturned(rv) |
|
552 | self.text_ctrl.showReturned(rv) | |
556 | self.cout.truncate(0) |
|
553 | self.cout.truncate(0) | |
557 | self.IP.initHistoryIndex() |
|
554 | self.IP.initHistoryIndex() | |
558 |
self. |
|
555 | self.setCurrentState('IDLE') | |
559 |
|
556 | |||
560 | #------------------------ IPython pager ---------------------------------- |
|
557 | def setCurrentState(self, state): | |
561 | def pager(self,text):#,start=0,screen_lines=0,pager_cmd = None): |
|
558 | self.cur_state = state | |
562 | if self.pager_state == 'WAITING': |
|
559 | self.updateStatusTracker(self.cur_state) | |
563 | #print >>sys.__stdout__,"PAGER waiting" |
|
|||
564 | return |
|
|||
565 |
|
560 | |||
566 | if self.pager_state == 'INIT': |
|
561 | #---------------------------- IPython pager --------------------------------------- | |
567 | #print >>sys.__stdout__,"PAGER state:",self.pager_state |
|
562 | def pager(self,text):#,start=0,screen_lines=0,pager_cmd = None): | |
568 | self.pager_lines = text[7:].split('\n') |
|
|||
569 | self.pager_nb_lines = len(self.pager_lines) |
|
|||
570 | self.pager_index = 0 |
|
|||
571 | self.pager_do_remove = False |
|
|||
572 | self.text_ctrl.write('\n') |
|
|||
573 | self.pager_state = 'PROCESS_LINES' |
|
|||
574 |
|
563 | |||
575 |
if self.pager_state == 'INIT |
|
564 | if self.pager_state == 'INIT': | |
576 |
|
|
565 | #print >>sys.__stdout__,"PAGER state:",self.pager_state | |
577 | self.pager_lines = text[:].split('\n') |
|
|||
578 | self.pager_nb_lines = len(self.pager_lines) |
|
566 | self.pager_nb_lines = len(self.pager_lines) | |
579 |
|
|
567 | self.pager_index = 0 | |
580 |
|
|
568 | self.pager_do_remove = False | |
581 |
|
|
569 | self.text_ctrl.write('\n') | |
582 |
|
|
570 | self.pager_state = 'PROCESS_LINES' | |
583 |
|
571 | |||
584 |
|
|
572 | if self.pager_state == 'PROCESS_LINES': | |
585 |
|
|
573 | #print >>sys.__stdout__,"PAGER state:",self.pager_state | |
586 |
|
|
574 | if self.pager_do_remove == True: | |
587 |
|
|
575 | self.text_ctrl.removeCurrentLine() | |
588 |
|
|
576 | self.pager_do_remove = False | |
589 |
|
577 | |||
590 |
|
|
578 | if self.pager_nb_lines > 10: | |
591 |
|
|
579 | #print >>sys.__stdout__,"PAGER processing 10 lines" | |
592 |
|
|
580 | if self.pager_index > 0: | |
593 |
|
|
581 | self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') | |
594 | else: |
|
582 | else: | |
595 |
|
|
583 | self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') | |
596 |
|
584 | |||
597 |
|
|
585 | for line in self.pager_lines[self.pager_index+1:self.pager_index+9]: | |
598 |
|
|
586 | self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n') | |
599 |
|
|
587 | self.pager_index += 10 | |
600 |
|
|
588 | self.pager_nb_lines -= 10 | |
601 |
|
|
589 | self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---") | |
602 |
|
|
590 | self.pager_do_remove = True | |
603 |
|
|
591 | self.pager_state = 'WAITING' | |
604 | return |
|
592 | return | |
605 |
|
|
593 | else: | |
606 |
|
|
594 | #print >>sys.__stdout__,"PAGER processing last lines" | |
607 |
|
|
595 | if self.pager_nb_lines > 0: | |
608 | if self.pager_index > 0: |
|
596 | if self.pager_index > 0: | |
609 |
|
|
597 | self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n') | |
610 | else: |
|
598 | else: | |
611 |
|
|
599 | self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') | |
612 |
|
600 | |||
613 | self.pager_index += 1 |
|
601 | self.pager_index += 1 | |
614 | self.pager_nb_lines -= 1 |
|
602 | self.pager_nb_lines -= 1 | |
615 | if self.pager_nb_lines > 0: |
|
603 | if self.pager_nb_lines > 0: | |
616 | for line in self.pager_lines[self.pager_index:]: |
|
604 | for line in self.pager_lines[self.pager_index:]: | |
@@ -636,7 +624,7 b' class IPShellWidget(wx.Panel):' | |||||
636 | if event.KeyCode == wx.WXK_RETURN: |
|
624 | if event.KeyCode == wx.WXK_RETURN: | |
637 | if self.cur_state == 'IDLE': |
|
625 | if self.cur_state == 'IDLE': | |
638 | #we change the state ot the state machine |
|
626 | #we change the state ot the state machine | |
639 |
self. |
|
627 | self.setCurrentState('DO_EXECUTE_LINE') | |
640 | self.stateDoExecuteLine() |
|
628 | self.stateDoExecuteLine() | |
641 | return |
|
629 | return | |
642 | if self.pager_state == 'WAITING': |
|
630 | if self.pager_state == 'WAITING': |
@@ -2,11 +2,13 b'' | |||||
2 | # -*- coding: iso-8859-15 -*- |
|
2 | # -*- coding: iso-8859-15 -*- | |
3 |
|
3 | |||
4 | import wx.aui |
|
4 | import wx.aui | |
5 | import wx.py |
|
5 | ||
|
6 | #used for about dialog | |||
6 | from wx.lib.wordwrap import wordwrap |
|
7 | from wx.lib.wordwrap import wordwrap | |
7 |
|
8 | |||
8 | from ipython_view import IPShellWidget |
|
9 | #used for ipython GUI objects | |
9 | from ipython_history import * |
|
10 | from IPython.gui.wx.ipython_view import IPShellWidget | |
|
11 | from IPython.gui.wx.ipython_history import IPythonHistoryPanel | |||
10 |
|
12 | |||
11 | __version__ = 0.8 |
|
13 | __version__ = 0.8 | |
12 | __author__ = "Laurent Dufrechou" |
|
14 | __author__ = "Laurent Dufrechou" |
General Comments 0
You need to be logged in to leave comments.
Login now