37 from StringIO
import StringIO
42 ansi_colors = {
'0;30':
'#2E3436',
62 A fake output file object. It sends output to the console widget,
63 and if asked for a file number, returns one set on instance creation
66 def __init__(self, console, fn=-1, style=None):
72 def fileno(self):
return self.fn
73 def isatty(self):
return False
74 def read(self, a):
return ''
75 def readline(self):
return ''
76 def readlines(self):
return []
78 self.console.write (s, self.
style)
79 def writelines(self, l):
81 self.console.write (s, self.
style)
82 def seek(self, a):
raise IOError, (29,
'Illegal seek')
83 def tell(self):
raise IOError, (29,
'Illegal seek')
90 A fake input file object. It receives input from a GTK TextView widget,
91 and if asked for a file number, returns one set on instance creation
93 def __init__(self, console, fn=-1):
98 def fileno(self):
return self.fn
99 def isatty(self):
return False
100 def read(self, a):
return self.
readline()
102 self.console.input_mode =
True
103 buffer = self.console.buffer
105 iter = buffer.get_iter_at_mark(buffer.get_insert())
106 buffer.move_mark (buffer.get_mark(
'linestart'), iter)
107 while self.console.input_mode:
110 s = self.console.input
111 self.console.input =
''
113 def readlines(self):
return []
114 def write(self, s):
return None
115 def writelines(self, l):
return None
116 def seek(self, a):
raise IOError, (29,
'Illegal seek')
117 def tell(self):
raise IOError, (29,
'Illegal seek')
123 """ GTK python console """
125 def __init__(self, argv=[], shelltype='python', banner=[],
126 filename=
None, size=100):
128 """ Console interface building + initialization"""
132 gtk.ScrolledWindow.__init__(self)
133 self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
134 self.set_shadow_type (gtk.SHADOW_NONE)
135 self.set_border_width(0)
136 self.
view = gtk.TextView()
137 self.view.modify_font (pango.FontDescription(
"Mono 10"))
138 self.view.set_editable (
True)
139 self.view.set_wrap_mode(
True)
140 self.view.set_left_margin(0)
141 self.view.set_right_margin(0)
142 self.
buffer = self.view.get_buffer()
143 self.buffer.create_tag (
'title',
145 weight=pango.WEIGHT_BOLD,
148 self.buffer.create_tag (
'subtitle',
152 self.buffer.create_tag (
'output',
155 self.buffer.create_tag (
'error',
157 style=pango.STYLE_OBLIQUE,
159 self.buffer.create_tag (
'prompt',
161 weight=pango.WEIGHT_BOLD,
163 self.buffer.create_tag(
'0')
164 self.
color_pat = re.compile(
'\x01?\x1b\[(.*?)m\x02?')
165 for code
in ansi_colors:
166 self.buffer.create_tag(code,
167 foreground=ansi_colors[code],
169 for text, style
in banner:
170 self.
write (text, style)
171 iter = self.buffer.get_iter_at_mark(self.buffer.get_insert())
172 self.buffer.create_mark (
'linestart', iter,
True)
173 self.view.add_events(gtk.gdk.KEY_PRESS_MASK)
182 self.
cout = StringIO()
183 self.cout.truncate(0)
184 if shelltype==
'ipython':
193 self.
stdout = ConsoleOut (self, sys.stdout.fileno(),
'output')
194 self.
stderr = ConsoleOut (self, sys.stderr.fileno(),
'error')
195 self.
stdin = ConsoleIn (self, sys.stdin.fileno())
199 if not os.path.exists (self.
fifoname):
203 self.shell.eval(self)
204 self.cout.truncate(0)
206 def history_init(self, filename, size):
209 if filename
and os.path.exists(filename):
210 readline.read_history_file(filename)
211 readline.set_history_length(size)
214 def history_save(self):
218 def history_add(self, item):
220 readline.add_history (item)
223 def history_reset(self):
226 def history_next(self):
228 if self.
history_index <= readline.get_current_history_length():
233 def history_prev(self):
240 def raw_input(self, prompt=''):
243 raise KeyboardInterrupt
247 """ Give focus to the TextView """
249 self.view.grab_focus()
252 """ Write text using given style (if any) """
253 segments = self.color_pat.split(text)
254 segment = segments.pop(0)
255 start,end = self.buffer.get_bounds()
257 self.buffer.insert(end, segment)
259 self.buffer.insert_with_tags_by_name(end, segment, style)
261 ansi_tags = self.color_pat.findall(text)
262 for tag
in ansi_tags:
263 i = segments.index(tag)
264 self.buffer.insert_with_tags_by_name(self.buffer.get_end_iter(),
267 self.view.scroll_mark_onscreen(self.buffer.get_insert())
270 """ Overwrite text after prompt with text """
272 mark = self.buffer.get_mark(
'linestart')
273 start = self.buffer.get_iter_at_mark(mark)
274 end = self.buffer.get_end_iter()
275 self.buffer.delete (start,end)
276 self.
write (text, style)
279 """ Get last line (without prompt) """
281 mark = self.buffer.get_mark(
'linestart')
282 start = self.buffer.get_iter_at_mark(mark)
283 end = self.buffer.get_end_iter()
284 return self.buffer.get_text (start,end,
True)
288 """ Display prompt """
290 iter = self.buffer.get_end_iter()
291 self.buffer.place_cursor (iter)
292 self.
write (self.shell.prompt, style)
293 iter = self.buffer.get_iter_at_mark(self.buffer.get_insert())
294 self.buffer.move_mark (self.buffer.get_mark(
'linestart'), iter)
296 self.view.scroll_mark_onscreen(self.buffer.get_insert())
297 while gtk.events_pending():
301 """ Handle key press event """
303 keyname = gtk.gdk.keyval_name (event.keyval)
306 if keyname
in [
'Return',
'KP_Enter']:
318 elif keyname
in [
'Left',
'BackSpace']:
319 mark = self.buffer.get_mark(
'linestart')
320 linestart = self.buffer.get_iter_at_mark(mark)
321 iter = self.buffer.get_iter_at_mark(self.buffer.get_insert())
322 if iter.compare(linestart) <= 0:
325 elif keyname ==
'Right':
329 elif keyname ==
'Down':
334 elif keyname ==
'Up':
339 elif keyname ==
'Home':
340 mark = self.buffer.get_mark(
'linestart')
341 linestart = self.buffer.get_iter_at_mark(mark)
342 self.buffer.place_cursor (linestart)
346 elif keyname ==
'Tab':
350 completed, possibilities = self.shell.complete(line)
351 if len(possibilities) > 1:
354 for symbol
in possibilities:
355 self.
write(symbol+
'\n')
361 elif event.state & gtk.gdk.CONTROL_MASK:
362 if keyname
in [
'a',
'A']:
363 mark = self.buffer.get_mark(
'linestart')
364 linestart = self.buffer.get_iter_at_mark(mark)
365 self.buffer.place_cursor (linestart)
367 elif keyname
in [
'e',
'E']:
368 end = self.buffer.get_end_iter()
369 self.buffer.place_cursor (end)
371 elif keyname
in [
'k',
'K']:
372 start = self.buffer.get_iter_at_mark (self.buffer.get_insert())
373 end = self.buffer.get_end_iter()
374 self.
killbuffer = self.buffer.get_text(start,end)
375 self.buffer.delete(start,end)
377 elif keyname
in [
'y',
'Y']:
379 iter = self.buffer.get_iter_at_mark (self.buffer.get_insert())
382 elif keyname
in [
'l',
'L']:
383 start = self.buffer.get_start_iter()
384 end = self.buffer.get_end_iter()
385 end.backward_sentence_start()
386 self.buffer.delete (start,end)
387 elif keyname
in [
'd',
'D']:
393 mark = self.buffer.get_mark(
'linestart')
394 linestart = self.buffer.get_iter_at_mark(mark)
395 iter = self.buffer.get_iter_at_mark(self.buffer.get_insert())
396 if iter.compare(linestart) < 0:
397 iter = self.buffer.get_end_iter()
398 self.buffer.place_cursor (iter)
409 sys_stdout = os.dup(1)
410 sys_stderr = os.dup(2)
414 self.shell.eval(self)
415 self.view.scroll_mark_onscreen(self.buffer.get_insert())
416 while gtk.events_pending():
420 os.dup2 (sys_stdout, 1)
421 os.dup2 (sys_stderr, 2)
422 os.close (sys_stdout)
423 os.close (sys_stderr)