/[ascend]/trunk/pygtk/ipython_view.py
ViewVC logotype

Diff of /trunk/pygtk/ipython_view.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1923 by jpye, Sun Mar 9 01:39:10 2008 UTC revision 1924 by jpye, Mon Oct 6 08:21:11 2008 UTC
# Line 1  Line 1 
1  #!/usr/bin/python  #!/usr/bin/python
2  """  '''
3  Provides IPython console widget.  Provides IPython console widget.
4    
5  @author: Eitan Isaacson  @author: Eitan Isaacson
# Line 10  Provides IPython console widget. Line 10  Provides IPython console widget.
10  All rights reserved. This program and the accompanying materials are made  All rights reserved. This program and the accompanying materials are made
11  available under the terms of the BSD which accompanies this distribution, and  available under the terms of the BSD which accompanies this distribution, and
12  is available at U{http://www.opensource.org/licenses/bsd-license.php}  is available at U{http://www.opensource.org/licenses/bsd-license.php}
13  """  '''
14    
15  import gtk, gobject  import gtk, gobject
16  import re  import re
# Line 26  except Exception,e: Line 26  except Exception,e:
26      raise Exception("Error importing IPython (%s)" % str(e))      raise Exception("Error importing IPython (%s)" % str(e))
27    
28  class IterableIPShell:  class IterableIPShell:
29    """    '''
30    Create an IPython instance. Does not start a blocking event loop,    Create an IPython instance. Does not start a blocking event loop,
31    instead allow single iterations. This allows embedding in GTK+    instead allow single iterations. This allows embedding in GTK+
32    without blockage.    without blockage.
# Line 41  class IterableIPShell: Line 41  class IterableIPShell:
41    @type history_level: integer    @type history_level: integer
42    @ivar complete_sep: Seperation delimeters for completion function.    @ivar complete_sep: Seperation delimeters for completion function.
43    @type complete_sep: _sre.SRE_Pattern    @type complete_sep: _sre.SRE_Pattern
44    """    '''
45    def __init__(self,argv=[],user_ns=None,user_global_ns=None,    def __init__(self,argv=[],user_ns=None,user_global_ns=None,
46                 cin=None, cout=None,cerr=None, input_func=None):                 cin=None, cout=None,cerr=None, input_func=None):
47      """          '''
48        
49        
50      @param argv: Command line options for IPython      @param argv: Command line options for IPython
51      @type argv: list      @type argv: list
52      @param user_ns: User namespace.      @param user_ns: User namespace.
# Line 59  class IterableIPShell: Line 61  class IterableIPShell:
61      @type cerr: IO stream      @type cerr: IO stream
62      @param input_func: Replacement for builtin raw_input()      @param input_func: Replacement for builtin raw_input()
63      @type input_func: function      @type input_func: function
64      """      '''
   
65      if input_func:      if input_func:
66        IPython.iplib.raw_input_original = input_func        IPython.iplib.raw_input_original = input_func
67      if cin:      if cin:
# Line 91  class IterableIPShell: Line 92  class IterableIPShell:
92      self.complete_sep =  re.compile('[\s\{\}\[\]\(\)]')      self.complete_sep =  re.compile('[\s\{\}\[\]\(\)]')
93    
94    def execute(self):    def execute(self):
95      """      '''
96      Executes the current line provided by the shell object.      Executes the current line provided by the shell object.
97      """      '''
98      self.history_level = 0      self.history_level = 0
99      orig_stdout = sys.stdout      orig_stdout = sys.stdout
100      sys.stdout = IPython.Shell.Term.cout      sys.stdout = IPython.Shell.Term.cout
# Line 126  class IterableIPShell: Line 127  class IterableIPShell:
127      sys.stdout = orig_stdout      sys.stdout = orig_stdout
128    
129    def historyBack(self):    def historyBack(self):
130      """      '''
131      Provides one history command back.      Provides one history command back.
132            
133      @return: The command string.      @return: The command string.
134      @rtype: string      @rtype: string
135      """      '''
136      self.history_level -= 1      self.history_level -= 1
137      return self._getHistory()      return self._getHistory()
138        
139    def historyForward(self):    def historyForward(self):
140      """      '''
141      Provides one history command forward.      Provides one history command forward.
142            
143      @return: The command string.      @return: The command string.
144      @rtype: string      @rtype: string
145      """      '''
146      self.history_level += 1      self.history_level += 1
147      return self._getHistory()      return self._getHistory()
148        
149    def _getHistory(self):    def _getHistory(self):
150      """      '''
151      Get's the command string of the current history level.      Get's the command string of the current history level.
152            
153      @return: Historic command string.      @return: Historic command string.
154      @rtype: string      @rtype: string
155      """      '''
156      try:      try:
157        rv = self.IP.user_ns['In'][self.history_level].strip('\n')        rv = self.IP.user_ns['In'][self.history_level].strip('\n')
158      except IndexError:      except IndexError:
# Line 160  class IterableIPShell: Line 161  class IterableIPShell:
161      return rv      return rv
162    
163    def updateNamespace(self, ns_dict):    def updateNamespace(self, ns_dict):
164      """      '''
165      Add the current dictionary to the shell namespace.      Add the current dictionary to the shell namespace.
166            
167      @param ns_dict: A dictionary of symbol-values.      @param ns_dict: A dictionary of symbol-values.
168      @type ns_dict: dictionary      @type ns_dict: dictionary
169      """      '''
170      self.IP.user_ns.update(ns_dict)      self.IP.user_ns.update(ns_dict)
171    
172    def complete(self, line):    def complete(self, line):
173      """      '''
174      Returns an auto completed line and/or posibilities for completion.      Returns an auto completed line and/or posibilities for completion.
175            
176      @param line: Given line so far.      @param line: Given line so far.
# Line 178  class IterableIPShell: Line 179  class IterableIPShell:
179      @return: Line completed as for as possible,      @return: Line completed as for as possible,
180      and possible further completions.      and possible further completions.
181      @rtype: tuple      @rtype: tuple
182      """      '''
183      split_line = self.complete_sep.split(line)      split_line = self.complete_sep.split(line)
184      possibilities = self.IP.complete(split_line[-1])      possibilities = self.IP.complete(split_line[-1])
185      if possibilities:      if possibilities:
186        def _commonPrefix(str1, str2):        def _commonPrefix(str1, str2):
187          """          '''
188          Reduction function. returns common prefix of two given strings.          Reduction function. returns common prefix of two given strings.
189                    
190          @param str1: First string.          @param str1: First string.
# Line 193  class IterableIPShell: Line 194  class IterableIPShell:
194                    
195          @return: Common prefix to both strings.          @return: Common prefix to both strings.
196          @rtype: string          @rtype: string
197          """          '''
198          for i in range(len(str1)):          for i in range(len(str1)):
199            if not str2.startswith(str1[:i+1]):            if not str2.startswith(str1[:i+1]):
200              return str1[:i]              return str1[:i]
# Line 206  class IterableIPShell: Line 207  class IterableIPShell:
207        
208    
209    def shell(self, cmd,verbose=0,debug=0,header=''):    def shell(self, cmd,verbose=0,debug=0,header=''):
210      """      '''
211      Replacement method to allow shell commands without them blocking.      Replacement method to allow shell commands without them blocking.
212            
213      @param cmd: Shell command to execute.      @param cmd: Shell command to execute.
# Line 217  class IterableIPShell: Line 218  class IterableIPShell:
218      @type debug: integer      @type debug: integer
219      @param header: Header to be printed before output      @param header: Header to be printed before output
220      @type header: string      @type header: string
221      """      '''
222      stat = 0      stat = 0
223      if verbose or debug: print header+cmd      if verbose or debug: print header+cmd
224      # flush stdout so we don't mangle python's buffering      # flush stdout so we don't mangle python's buffering
# Line 228  class IterableIPShell: Line 229  class IterableIPShell:
229        input.close()        input.close()
230    
231  class ConsoleView(gtk.TextView):  class ConsoleView(gtk.TextView):
232    """    '''
233    Specialized text view for console-like workflow.    Specialized text view for console-like workflow.
234    
235    @cvar ANSI_COLORS: Mapping of terminal colors to X11 names.    @cvar ANSI_COLORS: Mapping of terminal colors to X11 names.
# Line 242  class ConsoleView(gtk.TextView): Line 243  class ConsoleView(gtk.TextView):
243    @type mark: gtk.TextMark    @type mark: gtk.TextMark
244    @ivar line_start: Start of command line mark.    @ivar line_start: Start of command line mark.
245    @type line_start: gtk.TextMark    @type line_start: gtk.TextMark
246    """    '''
247    ANSI_COLORS =  {'0;30': 'Black',     '0;31': 'Red',    ANSI_COLORS =  {'0;30': 'Black',     '0;31': 'Red',
248                    '0;32': 'Green',     '0;33': 'Brown',                    '0;32': 'Green',     '0;33': 'Brown',
249                    '0;34': 'Blue',      '0;35': 'Purple',                    '0;34': 'Blue',      '0;35': 'Purple',
# Line 253  class ConsoleView(gtk.TextView): Line 254  class ConsoleView(gtk.TextView):
254                    '1;36': 'LightCyan', '1;37': 'White'}                    '1;36': 'LightCyan', '1;37': 'White'}
255    
256    def __init__(self):    def __init__(self):
257      """      '''
258      Initialize console view.      Initialize console view.
259      """      '''
260      gtk.TextView.__init__(self)      gtk.TextView.__init__(self)
261      self.modify_font(pango.FontDescription('Mono'))      self.modify_font(pango.FontDescription('Mono'))
262      self.set_cursor_visible(True)      self.set_cursor_visible(True)
# Line 279  class ConsoleView(gtk.TextView): Line 280  class ConsoleView(gtk.TextView):
280      gobject.idle_add(self._write, text, editable)      gobject.idle_add(self._write, text, editable)
281    
282    def _write(self, text, editable=False):    def _write(self, text, editable=False):
283      """      '''
284      Write given text to buffer.      Write given text to buffer.
285            
286      @param text: Text to append.      @param text: Text to append.
287      @type text: string      @type text: string
288      @param editable: If true, added text is editable.      @param editable: If true, added text is editable.
289      @type editable: boolean      @type editable: boolean
290      """      '''
291      segments = self.color_pat.split(text)      segments = self.color_pat.split(text)
292      segment = segments.pop(0)      segment = segments.pop(0)
293      start_mark = self.text_buffer.create_mark(None,      start_mark = self.text_buffer.create_mark(None,
# Line 313  class ConsoleView(gtk.TextView): Line 314  class ConsoleView(gtk.TextView):
314      gobject.idle_add(self._showPrompt, prompt)      gobject.idle_add(self._showPrompt, prompt)
315    
316    def _showPrompt(self, prompt):    def _showPrompt(self, prompt):
317      """      '''
318      Prints prompt at start of line.      Prints prompt at start of line.
319            
320      @param prompt: Prompt to print.      @param prompt: Prompt to print.
321      @type prompt: string      @type prompt: string
322      """      '''
323      self._write(prompt)      self._write(prompt)
324      self.text_buffer.move_mark(self.line_start,      self.text_buffer.move_mark(self.line_start,
325                                 self.text_buffer.get_end_iter())                                 self.text_buffer.get_end_iter())
# Line 327  class ConsoleView(gtk.TextView): Line 328  class ConsoleView(gtk.TextView):
328      gobject.idle_add(self._changeLine, text)      gobject.idle_add(self._changeLine, text)
329    
330    def _changeLine(self, text):    def _changeLine(self, text):
331      """      '''
332      Replace currently entered command line with given text.      Replace currently entered command line with given text.
333            
334      @param text: Text to use as replacement.      @param text: Text to use as replacement.
335      @type text: string      @type text: string
336      """      '''
337      iter = self.text_buffer.get_iter_at_mark(self.line_start)      iter = self.text_buffer.get_iter_at_mark(self.line_start)
338      iter.forward_to_line_end()      iter.forward_to_line_end()
339      self.text_buffer.delete(self.text_buffer.get_iter_at_mark(self.line_start), iter)      self.text_buffer.delete(self.text_buffer.get_iter_at_mark(self.line_start), iter)
340      self._write(text, True)      self._write(text, True)
341    
342    def getCurrentLine(self):    def getCurrentLine(self):
343      """      '''
344      Get text in current command line.      Get text in current command line.
345            
346      @return: Text of current command line.      @return: Text of current command line.
347      @rtype: string      @rtype: string
348      """      '''
349      rv = self.text_buffer.get_slice(      rv = self.text_buffer.get_slice(
350        self.text_buffer.get_iter_at_mark(self.line_start),        self.text_buffer.get_iter_at_mark(self.line_start),
351        self.text_buffer.get_end_iter(), False)        self.text_buffer.get_end_iter(), False)
# Line 354  class ConsoleView(gtk.TextView): Line 355  class ConsoleView(gtk.TextView):
355      gobject.idle_add(self._showReturned, text)      gobject.idle_add(self._showReturned, text)
356    
357    def _showReturned(self, text):    def _showReturned(self, text):
358      """      '''
359      Show returned text from last command and print new prompt.      Show returned text from last command and print new prompt.
360            
361      @param text: Text to show.      @param text: Text to show.
362      @type text: string      @type text: string
363      """      '''
364      iter = self.text_buffer.get_iter_at_mark(self.line_start)      iter = self.text_buffer.get_iter_at_mark(self.line_start)
365      iter.forward_to_line_end()      iter.forward_to_line_end()
366      self.text_buffer.apply_tag_by_name(      self.text_buffer.apply_tag_by_name(
# Line 374  class ConsoleView(gtk.TextView): Line 375  class ConsoleView(gtk.TextView):
375      self.text_buffer.place_cursor(self.text_buffer.get_end_iter())      self.text_buffer.place_cursor(self.text_buffer.get_end_iter())
376    
377    def onKeyPress(self, widget, event):    def onKeyPress(self, widget, event):
378      """      '''
379      Key press callback used for correcting behavior for console-like      Key press callback used for correcting behavior for console-like
380      interfaces. For example 'home' should go to prompt, not to begining of      interfaces. For example 'home' should go to prompt, not to begining of
381      line.      line.
# Line 386  class ConsoleView(gtk.TextView): Line 387  class ConsoleView(gtk.TextView):
387            
388      @return: Return True if event should not trickle.      @return: Return True if event should not trickle.
389      @rtype: boolean      @rtype: boolean
390      """      '''
391      insert_mark = self.text_buffer.get_insert()      insert_mark = self.text_buffer.get_insert()
392      insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)      insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)
393      selection_mark = self.text_buffer.get_selection_bound()      selection_mark = self.text_buffer.get_selection_bound()
394      selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)      selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)
395      start_iter = self.text_buffer.get_iter_at_mark(self.line_start)      start_iter = self.text_buffer.get_iter_at_mark(self.line_start)
396      if event.keyval == gtk.keysyms.Home:      if event.keyval == gtk.keysyms.Home:
397        if event.state == 0:        if event.state & gtk.gdk.CONTROL_MASK or event.state & gtk.gdk.MOD1_MASK:
398          self.text_buffer.place_cursor(start_iter)          pass
399          return True        elif event.state & gtk.gdk.SHIFT_MASK:
       elif event.state == gtk.gdk.SHIFT_MASK:  
400          self.text_buffer.move_mark(insert_mark, start_iter)          self.text_buffer.move_mark(insert_mark, start_iter)
401          return True          return True
402          else:
403            self.text_buffer.place_cursor(start_iter)
404            return True
405      elif event.keyval == gtk.keysyms.Left:      elif event.keyval == gtk.keysyms.Left:
406        insert_iter.backward_cursor_position()        insert_iter.backward_cursor_position()
407        if not insert_iter.editable(True):        if not insert_iter.editable(True):
# Line 419  class ConsoleView(gtk.TextView): Line 422  class ConsoleView(gtk.TextView):
422      return self.onKeyPressExtend(event)      return self.onKeyPressExtend(event)
423    
424    def onKeyPressExtend(self, event):    def onKeyPressExtend(self, event):
425      """      '''
426      For some reason we can't extend onKeyPress directly (bug #500900).      For some reason we can't extend onKeyPress directly (bug #500900).
427      """      '''
428      pass      pass
429    
430  class IPythonView(ConsoleView, IterableIPShell):  class IPythonView(ConsoleView, IterableIPShell):
431    """    '''
432    Sub-class of both modified IPython shell and L{ConsoleView} this makes    Sub-class of both modified IPython shell and L{ConsoleView} this makes
433    a GTK+ IPython console.    a GTK+ IPython console.
434    """    '''
435    def __init__(self):    def __init__(self):
436      """      '''
437      Initialize. Redirect I/O to console.      Initialize. Redirect I/O to console.
438      """      '''
439      ConsoleView.__init__(self)      ConsoleView.__init__(self)
440      self.cout = StringIO()      self.cout = StringIO()
441      IterableIPShell.__init__(self, cout=self.cout,cerr=self.cout,      IterableIPShell.__init__(self, cout=self.cout,cerr=self.cout,
# Line 444  class IPythonView(ConsoleView, IterableI Line 447  class IPythonView(ConsoleView, IterableI
447      self.interrupt = False      self.interrupt = False
448    
449    def raw_input(self, prompt=''):    def raw_input(self, prompt=''):
450      """      '''
451      Custom raw_input() replacement. Get's current line from console buffer.      Custom raw_input() replacement. Get's current line from console buffer.
452            
453      @param prompt: Prompt to print. Here for compatability as replacement.      @param prompt: Prompt to print. Here for compatability as replacement.
# Line 452  class IPythonView(ConsoleView, IterableI Line 455  class IPythonView(ConsoleView, IterableI
455            
456      @return: The current command line text.      @return: The current command line text.
457      @rtype: string      @rtype: string
458      """      '''
459      if self.interrupt:      if self.interrupt:
460        self.interrupt = False        self.interrupt = False
461        raise KeyboardInterrupt        raise KeyboardInterrupt
462      return self.getCurrentLine()      return self.getCurrentLine()
463    
464    def onKeyPressExtend(self, event):    def onKeyPressExtend(self, event):
465      """      '''
466      Key press callback with plenty of shell goodness, like history,      Key press callback with plenty of shell goodness, like history,
467      autocompletions, etc.      autocompletions, etc.
468            
# Line 470  class IPythonView(ConsoleView, IterableI Line 473  class IPythonView(ConsoleView, IterableI
473            
474      @return: True if event should not trickle.      @return: True if event should not trickle.
475      @rtype: boolean      @rtype: boolean
476      """      '''
477      if event.state & gtk.gdk.CONTROL_MASK and event.keyval == 99:      if event.state & gtk.gdk.CONTROL_MASK and event.keyval == 99:
478        self.interrupt = True        self.interrupt = True
479        self._processLine()        self._processLine()
# Line 498  class IPythonView(ConsoleView, IterableI Line 501  class IPythonView(ConsoleView, IterableI
501        return True        return True
502    
503    def _processLine(self):    def _processLine(self):
504      """      '''
505      Process current command line.      Process current command line.
506      """      '''
507      self.history_pos = 0      self.history_pos = 0
508      self.execute()      self.execute()
509      rv = self.cout.getvalue()      rv = self.cout.getvalue()
# Line 508  class IPythonView(ConsoleView, IterableI Line 511  class IPythonView(ConsoleView, IterableI
511      self.showReturned(rv)      self.showReturned(rv)
512      self.cout.truncate(0)      self.cout.truncate(0)
513            
   

Legend:
Removed from v.1923  
changed lines
  Added in v.1924

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22