35 gi.require_version(
'Gtk',
'3.0')
36 from gi.repository
import GObject
37 from gi.repository
import Gtk
38 from gi.repository
import Gdk
39 from gi.repository
import Pango
45 ansi_colors = {
'0;30':
'#2E3436',
65 A fake output file object. It sends output to the console widget, 66 and if asked for a file number, returns one set on instance creation 69 def __init__(self, console, fn=-1, style=None):
75 def fileno(self):
return self.fn
76 def isatty(self):
return False 77 def read(self, a):
return '' 78 def readline(self):
return '' 79 def readlines(self):
return []
82 def writelines(self, l):
85 def seek(self, a):
raise IOError(29,
'Illegal seek')
86 def tell(self):
raise IOError(29,
'Illegal seek')
93 A fake input file object. It receives input from a GTK TextView widget, 94 and if asked for a file number, returns one set on instance creation 96 def __init__(self, console, fn=-1):
101 def fileno(self):
return self.fn
102 def isatty(self):
return False 103 def read(self, a):
return self.
readline()
108 iter = buffer.get_iter_at_mark(buffer.get_insert())
109 buffer.move_mark (buffer.get_mark(
'linestart'), iter)
116 def readlines(self):
return []
117 def write(self, s):
return None
118 def writelines(self, l):
return None 119 def seek(self, a):
raise IOError(29,
'Illegal seek')
120 def tell(self):
raise IOError(29,
'Illegal seek')
126 """ GTK python console """ 128 def __init__(self, argv=[], shelltype='python', banner=[],
129 filename=None, size=100, user_local_ns=None, user_global_ns=None):
131 """ Console interface building + initialization""" 135 GObject.GObject.__init__(self)
136 self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
137 self.set_shadow_type (Gtk.ShadowType.NONE)
138 self.set_border_width(0)
139 self.
view = Gtk.TextView()
140 self.
view.modify_font (Pango.FontDescription(
"Mono 10"))
141 self.
view.set_editable (
True)
142 self.
view.set_wrap_mode(
True)
143 self.
view.set_left_margin(0)
144 self.
view.set_right_margin(0)
146 self.
buffer.create_tag (
'title',
148 weight=Pango.Weight.BOLD,
151 self.
buffer.create_tag (
'subtitle',
155 self.
buffer.create_tag (
'output',
158 self.
buffer.create_tag (
'error',
160 style=Pango.Style.OBLIQUE,
162 self.
buffer.create_tag (
'prompt',
164 weight=Pango.Weight.BOLD,
166 self.
buffer.create_tag(
'0')
167 self.
color_pat = re.compile(
r'\x01?\x1b\[(.*?)m\x02?')
168 for code
in ansi_colors:
169 self.
buffer.create_tag(code,
170 foreground=ansi_colors[code],
172 for text, style
in banner:
173 self.
write (text, style)
174 iter = self.
buffer.get_iter_at_mark(self.
buffer.get_insert())
175 self.
buffer.create_mark (
'linestart', iter,
True)
176 self.
view.add_events(Gdk.EventMask.KEY_PRESS_MASK)
185 self.
cout = io.StringIO()
186 self.
cout.truncate(0)
188 if not user_local_ns:
189 user_local_ns = locals()
190 if not user_global_ns:
191 user_global_ns = globals()
193 if shelltype==
'ipython':
202 self.
stdout = ConsoleOut (self, sys.stdout.fileno(),
'output')
203 self.
stderr = ConsoleOut (self, sys.stderr.fileno(),
'error')
204 self.
stdin = ConsoleIn (self, sys.stdin.fileno())
208 if not os.path.exists (self.
fifoname):
212 self.
shell.eval(self)
213 self.
cout.truncate(0)
215 def history_init(self, filename, size):
218 if filename
and os.path.exists(filename):
219 readline.read_history_file(filename)
220 readline.set_history_length(size)
223 def history_save(self):
227 def history_add(self, item):
229 readline.add_history (item)
232 def history_reset(self):
235 def history_next(self):
237 if self.
history_index <= readline.get_current_history_length():
242 def history_prev(self):
249 def raw_input(self, prompt=''):
252 raise KeyboardInterrupt
256 """ Give focus to the TextView """ 261 """ Write text using given style (if any) """ 263 segment = segments.pop(0)
264 start,end = self.
buffer.get_bounds()
266 self.
buffer.insert(end, segment)
268 self.
buffer.insert_with_tags_by_name(end, segment, style)
271 for tag
in ansi_tags:
272 i = segments.index(tag)
273 self.
buffer.insert_with_tags_by_name(self.
buffer.get_end_iter(),
276 self.
view.scroll_mark_onscreen(self.
buffer.get_insert())
279 """ Overwrite text after prompt with text """ 281 mark = self.
buffer.get_mark(
'linestart')
282 start = self.
buffer.get_iter_at_mark(mark)
283 end = self.
buffer.get_end_iter()
284 self.
buffer.delete (start,end)
285 self.
write (text, style)
288 """ Get last line (without prompt) """ 290 mark = self.
buffer.get_mark(
'linestart')
291 start = self.
buffer.get_iter_at_mark(mark)
292 end = self.
buffer.get_end_iter()
293 return self.
buffer.get_text (start,end,
True)
297 """ Display prompt """ 299 iter = self.
buffer.get_end_iter()
300 self.
buffer.place_cursor (iter)
302 iter = self.
buffer.get_iter_at_mark(self.
buffer.get_insert())
303 self.
buffer.move_mark (self.
buffer.get_mark(
'linestart'), iter)
305 self.
view.scroll_mark_onscreen(self.
buffer.get_insert())
306 while Gtk.events_pending():
310 """ Handle key press event """ 312 keyname = Gdk.keyval_name (event.keyval)
315 if keyname
in [
'Return',
'KP_Enter']:
327 elif keyname
in [
'Left',
'BackSpace']:
328 mark = self.
buffer.get_mark(
'linestart')
329 linestart = self.
buffer.get_iter_at_mark(mark)
330 iter = self.
buffer.get_iter_at_mark(self.
buffer.get_insert())
331 if iter.compare(linestart) <= 0:
334 elif keyname ==
'Right':
338 elif keyname ==
'Down':
343 elif keyname ==
'Up':
348 elif keyname ==
'Home':
349 mark = self.
buffer.get_mark(
'linestart')
350 linestart = self.
buffer.get_iter_at_mark(mark)
351 self.
buffer.place_cursor (linestart)
355 elif keyname ==
'Tab':
359 completed, possibilities = self.
shell.complete(line)
360 if len(possibilities) > 1:
363 for symbol
in possibilities:
364 self.
write(symbol+
'\n')
370 elif event.get_state() & Gdk.ModifierType.CONTROL_MASK:
371 if keyname
in [
'a',
'A']:
372 mark = self.
buffer.get_mark(
'linestart')
373 linestart = self.
buffer.get_iter_at_mark(mark)
374 self.
buffer.place_cursor (linestart)
376 elif keyname
in [
'e',
'E']:
377 end = self.
buffer.get_end_iter()
378 self.
buffer.place_cursor (end)
380 elif keyname
in [
'k',
'K']:
381 start = self.
buffer.get_iter_at_mark (self.
buffer.get_insert())
382 end = self.
buffer.get_end_iter()
384 self.
buffer.delete(start,end)
386 elif keyname
in [
'y',
'Y']:
388 iter = self.
buffer.get_iter_at_mark (self.
buffer.get_insert())
391 elif keyname
in [
'l',
'L']:
392 start = self.
buffer.get_start_iter()
393 end = self.
buffer.get_end_iter()
394 end.backward_sentence_start()
395 self.
buffer.delete (start,end)
396 elif keyname
in [
'd',
'D']:
402 mark = self.
buffer.get_mark(
'linestart')
403 linestart = self.
buffer.get_iter_at_mark(mark)
404 iter = self.
buffer.get_iter_at_mark(self.
buffer.get_insert())
405 if iter.compare(linestart) < 0:
406 iter = self.
buffer.get_end_iter()
407 self.
buffer.place_cursor (iter)
418 sys_stdout = os.dup(1)
419 sys_stderr = os.dup(2)
423 self.
shell.eval(self)
424 self.
view.scroll_mark_onscreen(self.
buffer.get_insert())
425 while Gtk.events_pending():
429 os.dup2 (sys_stdout, 1)
430 os.dup2 (sys_stderr, 2)
431 os.close (sys_stdout)
432 os.close (sys_stderr)
def overwrite(self, text, style=None)
def write(self, text, style=None)
def raw_input(self, prompt='')
def history_add(self, item)
def __init__(self, argv=[], shelltype='python', banner=[], filename=None, size=100, user_local_ns=None, user_global_ns=None)
def history_init(self, filename, size)
def key_press_event(self, widget, event)
def prompt(self, style=None)