home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / gedit-2 / plugins / pythonconsole / console.py < prev   
Encoding:
Python Source  |  2006-08-27  |  9.2 KB  |  291 lines

  1. # -*- coding: utf-8 -*-
  2.  
  3. # pythonconsole.py -- Console widget
  4. #
  5. # Copyright (C) 2006 - Steve Fr├⌐cinaux
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2, or (at your option)
  10. # any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  
  20. # Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
  21. #     Copyright (C), 1998 James Henstridge <james@daa.com.au>
  22. #     Copyright (C), 2005 Adam Hooper <adamh@densi.com>
  23. # Bits from gedit Python Console Plugin
  24. #     Copyrignt (C), 2005 Rapha├½l Slinckx
  25.  
  26. import string
  27. import sys
  28. import re
  29. import traceback
  30. import gobject
  31. import gtk
  32. import pango
  33.  
  34. __all__ = ('PythonConsole', 'OutFile')
  35.  
  36. class PythonConsole(gtk.ScrolledWindow):
  37.     def __init__(self, namespace = {}):
  38.         gtk.ScrolledWindow.__init__(self)
  39.  
  40.         self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC);
  41.         self.set_shadow_type(gtk.SHADOW_IN)
  42.         self.view = gtk.TextView()
  43.         self.view.modify_font(pango.FontDescription('Monospace'))
  44.         self.view.set_editable(True)
  45.         self.view.set_wrap_mode(gtk.WRAP_WORD_CHAR)
  46.         self.add(self.view)
  47.         self.view.show()
  48.  
  49.         buffer = self.view.get_buffer()
  50.         self.normal = buffer.create_tag("normal")
  51.         self.error  = buffer.create_tag("error")
  52.         self.error.set_property("foreground", "red")
  53.         self.command = buffer.create_tag("command")
  54.         self.command.set_property("foreground", "blue")
  55.  
  56.         self.__spaces_pattern = re.compile(r'^\s+')        
  57.         self.namespace = namespace
  58.  
  59.         # Init first line
  60.         buffer.create_mark("input-line", buffer.get_end_iter(), True)
  61.         buffer.insert(buffer.get_end_iter(), ">>> ")
  62.         buffer.create_mark("input", buffer.get_end_iter(), True)
  63.  
  64.         # Init history
  65.         self.history = ['']
  66.         self.history_pos = 0
  67.         self.current_command = ''
  68.         self.namespace['__history__'] = self.history
  69.  
  70.         # Set up hooks for standard output.
  71.         self.stdout = OutFile(self, sys.stdout.fileno(), self.normal)
  72.         self.stderr = OutFile(self, sys.stderr.fileno(), self.error)
  73.         
  74.         # Signals
  75.         self.view.connect("key-press-event", self.__key_press_event_cb)
  76.         buffer.connect("mark-set", self.__mark_set_cb)
  77.         
  78.          
  79.     def __key_press_event_cb(self, view, event):
  80.         if event.keyval == gtk.keysyms.d and event.state == gtk.gdk.CONTROL_MASK:
  81.             self.destroy()
  82.         
  83.         elif event.keyval == gtk.keysyms.Return and event.state == gtk.gdk.CONTROL_MASK:
  84.             # Get the command
  85.             buffer = view.get_buffer()
  86.             inp_mark = buffer.get_mark("input")
  87.             inp = buffer.get_iter_at_mark(inp_mark)
  88.             cur = buffer.get_end_iter()
  89.             line = buffer.get_text(inp, cur)
  90.             self.current_command = self.current_command + line + "\n"
  91.             self.history_add(line)
  92.  
  93.             # Prepare the new line
  94.             cur = buffer.get_end_iter()
  95.             buffer.insert(cur, "\n... ")
  96.             cur = buffer.get_end_iter()
  97.             buffer.move_mark(inp_mark, cur)
  98.             
  99.             # Keep indentation of precendent line
  100.             spaces = re.match(self.__spaces_pattern, line)
  101.             if spaces is not None:
  102.                 buffer.insert(cur, line[spaces.start() : spaces.end()])
  103.                 cur = buffer.get_end_iter()
  104.                 
  105.             buffer.place_cursor(cur)
  106.             gobject.idle_add(self.scroll_to_end)
  107.             return True
  108.         
  109.         elif event.keyval == gtk.keysyms.Return:
  110.             # Get the marks
  111.             buffer = view.get_buffer()
  112.             lin_mark = buffer.get_mark("input-line")
  113.             inp_mark = buffer.get_mark("input")
  114.  
  115.             # Get the command line
  116.             inp = buffer.get_iter_at_mark(inp_mark)
  117.             cur = buffer.get_end_iter()
  118.             line = buffer.get_text(inp, cur)
  119.             self.current_command = self.current_command + line + "\n"
  120.             self.history_add(line)
  121.  
  122.             # Make the line blue
  123.             lin = buffer.get_iter_at_mark(lin_mark)
  124.             buffer.apply_tag(self.command, lin, cur)
  125.             buffer.insert(cur, "\n")
  126.             
  127.             # Eval the command
  128.             self.__run(self.current_command)
  129.             self.current_command = ''
  130.  
  131.             # Prepare the new line
  132.             cur = buffer.get_end_iter()
  133.             buffer.move_mark(lin_mark, cur)
  134.             buffer.insert(cur, ">>> ")
  135.             cur = buffer.get_end_iter()
  136.             buffer.move_mark(inp_mark, cur)
  137.             buffer.place_cursor(cur)
  138.             gobject.idle_add(self.scroll_to_end)
  139.             return True
  140.  
  141.         elif event.keyval == gtk.keysyms.KP_Down or event.keyval == gtk.keysyms.Down:
  142.             # Next entry from history
  143.             view.emit_stop_by_name("key_press_event")
  144.             self.history_down()
  145.             gobject.idle_add(self.scroll_to_end)
  146.             return True
  147.  
  148.         elif event.keyval == gtk.keysyms.KP_Up or event.keyval == gtk.keysyms.Up:
  149.             # Previous entry from history
  150.             view.emit_stop_by_name("key_press_event")
  151.             self.history_up()
  152.             gobject.idle_add(self.scroll_to_end)
  153.             return True
  154.  
  155.         elif event.keyval == gtk.keysyms.KP_Left or event.keyval == gtk.keysyms.Left or \
  156.              event.keyval == gtk.keysyms.BackSpace:
  157.             buffer = view.get_buffer()
  158.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  159.             cur = buffer.get_iter_at_mark(buffer.get_insert())
  160.             return inp.compare(cur) == 0
  161.  
  162.         elif event.keyval == gtk.keysyms.Home:
  163.             # Go to the begin of the command instead of the begin of the line
  164.             buffer = view.get_buffer()
  165.             inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  166.             if event.state == gtk.gdk.SHIFT_MASK:
  167.                 buffer.move_mark_by_name("insert", inp)
  168.             else:
  169.                 buffer.place_cursor(inp)
  170.             return True
  171.         
  172.     def __mark_set_cb(self, buffer, iter, name):
  173.         input = buffer.get_iter_at_mark(buffer.get_mark("input"))
  174.         pos   = buffer.get_iter_at_mark(buffer.get_insert())
  175.         self.view.set_editable(pos.compare(input) != -1)
  176.  
  177.     def get_command_line(self):
  178.         buffer = self.view.get_buffer()
  179.         inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
  180.         cur = buffer.get_end_iter()
  181.         return buffer.get_text(inp, cur)
  182.     
  183.     def set_command_line(self, command):
  184.         buffer = self.view.get_buffer()
  185.         mark = buffer.get_mark("input")
  186.         inp = buffer.get_iter_at_mark(mark)
  187.         cur = buffer.get_end_iter()
  188.         buffer.delete(inp, cur)
  189.         buffer.insert(inp, command)
  190.         buffer.select_range(buffer.get_iter_at_mark(mark), buffer.get_end_iter())
  191.         self.view.grab_focus()
  192.     
  193.     def history_add(self, line):
  194.         if line.strip() != '':
  195.             self.history_pos = len(self.history)
  196.             self.history[self.history_pos - 1] = line
  197.             self.history.append('')
  198.     
  199.     def history_up(self):
  200.         if self.history_pos > 0:
  201.             self.history[self.history_pos] = self.get_command_line()
  202.             self.history_pos = self.history_pos - 1
  203.             self.set_command_line(self.history[self.history_pos])
  204.             
  205.     def history_down(self):
  206.         if self.history_pos < len(self.history) - 1:
  207.             self.history[self.history_pos] = self.get_command_line()
  208.             self.history_pos = self.history_pos + 1
  209.             self.set_command_line(self.history[self.history_pos])
  210.     
  211.     def scroll_to_end(self):
  212.         iter = self.view.get_buffer().get_end_iter()
  213.         self.view.scroll_to_iter(iter, 0.0)
  214.         return False
  215.  
  216.     def write(self, text, tag = None):
  217.         buffer = self.view.get_buffer()
  218.         if tag is None:
  219.             buffer.insert(buffer.get_end_iter(), text)
  220.         else:
  221.             buffer.insert_with_tags(buffer.get_end_iter(), text, tag)
  222.         gobject.idle_add(self.scroll_to_end)
  223.      
  224.      def eval(self, command, display_command = False):
  225.         buffer = self.view.get_buffer()
  226.         lin = buffer.get_mark("input-line")
  227.         buffer.delete(buffer.get_iter_at_mark(lin),
  228.                       buffer.get_end_iter())
  229.  
  230.         if isinstance(command, list) or isinstance(command, tuple):
  231.              for c in command:
  232.                  if display_command:
  233.                      self.write(">>> " + c + "\n", self.command)
  234.                  self.__run(c)
  235.         else:
  236.              if display_command:
  237.                  self.write(">>> " + c + "\n", self.command)
  238.             self.__run(command) 
  239.  
  240.         cur = buffer.get_end_iter()
  241.         buffer.move_mark_by_name("input-line", cur)
  242.         buffer.insert(cur, ">>> ")
  243.         cur = buffer.get_end_iter()
  244.         buffer.move_mark_by_name("input", cur)
  245.         self.view.scroll_to_iter(buffer.get_end_iter(), 0.0)
  246.     
  247.      def __run(self, command):
  248.         sys.stdout, self.stdout = self.stdout, sys.stdout
  249.         sys.stderr, self.stderr = self.stderr, sys.stderr
  250.         
  251.         try:
  252.             try:
  253.                 r = eval(command, self.namespace, self.namespace)
  254.                 if r is not None:
  255.                     print `r`
  256.             except SyntaxError:
  257.                 exec command in self.namespace
  258.         except:
  259.             if hasattr(sys, 'last_type') and sys.last_type == SystemExit:
  260.                 self.destroy()
  261.             else:
  262.                 traceback.print_exc()
  263.  
  264.         sys.stdout, self.stdout = self.stdout, sys.stdout
  265.         sys.stderr, self.stderr = self.stderr, sys.stderr
  266.  
  267.     def destroy(self):
  268.         pass
  269.         #gtk.ScrolledWindow.destroy(self)
  270.         
  271. class OutFile:
  272.     """A fake output file object. It sends output to a TK test widget,
  273.     and if asked for a file number, returns one set on instance creation"""
  274.     def __init__(self, console, fn, tag):
  275.         self.fn = fn
  276.         self.console = console
  277.         self.tag = tag
  278.     def close(self):         pass
  279.     def flush(self):         pass
  280.     def fileno(self):        return self.fn
  281.     def isatty(self):        return 0
  282.     def read(self, a):       return ''
  283.     def readline(self):      return ''
  284.     def readlines(self):     return []
  285.     def write(self, s):      self.console.write(s, self.tag)
  286.     def writelines(self, l): self.console.write(l, self.tag)
  287.     def seek(self, a):       raise IOError, (29, 'Illegal seek')
  288.     def tell(self):          raise IOError, (29, 'Illegal seek')
  289.     truncate = tell
  290.