2Backend to the console plugin.
5@organization: IBM Corporation
6@copyright: Copyright (c) 2007 IBM Corporation
9All rights reserved. This program and the accompanying materials are made
10available under the terms of the BSD which accompanies this distribution, and
11is available at U{http://www.opensource.org/licenses/bsd-license.php}
17gi.require_version(
'Gtk',
'3.0')
18from gi.repository
import Gtk
19from gi.repository
import Gdk
20from gi.repository
import GLib
21from gi.repository
import Pango
23from pkg_resources
import parse_version
29from io
import StringIO
30from functools
import reduce
67 def __init__(self, argv=[], user_ns=None, user_global_ns=None,
68 cin=None, cout=None, cerr=None, input_func=None):
71 @param self: this object
72 @param argv: Command line options
for IPython
73 @param user_ns: User namespace.
74 @param user_global_ns: User
global namespace.
75 @param cin: Console standard input.
76 @param cout: Console standard output.
77 @param cerr: Console standard error.
78 @param input_func: Replacement
for builtin raw_input()
82 IPython.terminal.interactiveshell.raw_input_original = input_func
83 if IPython.version_info < (8,):
85 io.stdin = io.IOStream(cin)
87 io.stdout = io.IOStream(cout)
89 io.stderr = io.IOStream(cerr)
100 io.raw_input =
lambda x:
None
102 os.environ[
'TERM'] =
'dumb'
103 excepthook = sys.excepthook
105 from traitlets.config.loader
import Config
107 cfg.InteractiveShell.colors =
"Linux"
108 cfg.Completer.use_jedi =
False
110 if IPython.version_info < (8,):
113 old_stdout, old_stderr = sys.stdout, sys.stderr
114 sys.stdout, sys.stderr = io.stdout.stream, io.stderr.stream
118 self.
IP = IPython.terminal.embed.InteractiveShellEmbed.instance(\
119 config=cfg, user_ns=user_ns)
121 if IPython.version_info < (8,):
122 sys.stdout, sys.stderr = old_stdout, old_stderr
124 self.
IP.system =
lambda cmd: self.
shell(self.
IP.var_expand(cmd),
125 header=
'IPython system call: ')
130 self.
IP.raw_input = input_func
131 sys.excepthook = excepthook
150 Update self.IP namespace for autocompletion
with sys.modules
153 for k, v
in list(sys.modules.items()):
155 self.
IP.user_ns.update({k:v})
159 Executes the current line provided by the shell object.
164 if IPython.version_info < (8,):
168 orig_stdout = sys.stdout
169 sys.stdout = IPython.utils.io.stdout
171 orig_stdin = sys.stdin
172 sys.stdin = IPython.utils.io.stdin
176 self.
IP.hooks.pre_prompt_hook()
181 self.
IP.showtraceback()
182 if self.
IP.autoindent:
183 self.
IP.rl_do_indent =
True
186 line = self.
IP.raw_input(self.
prompt)
187 except KeyboardInterrupt:
188 self.
IP.write(
'\nKeyboardInterrupt\n')
192 self.
IP.input_splitter.reset()
194 self.
IP.showtraceback()
197 self.
lines.append(line)
201 self.
IP.input_splitter.push(line)
202 self.
iter_more = self.
IP.input_splitter.push_accepts_more()
205 source_raw =
'\n'.join(self.
lines)
208 source_raw = self.
IP.input_splitter.raw_reset()
209 self.
IP.run_cell(source_raw, store_history=
True)
210 self.
IP.rl_do_indent =
False
214 self.
IP.rl_do_indent =
True
218 if IPython.version_info < (8,):
219 sys.stdout = orig_stdout
220 sys.stdin = orig_stdin
224 Generate prompt depending on is_continuation value
226 @param is_continuation
227 @return: The prompt string representation
240 Provides one history command back.
242 @param self this object
243 @return: The command string.
252 Provides one history command forward.
254 @param self this object
255 @return: The command string.
263 Gets the command string of the current history level.
265 @param self this object
266 @return: Historic command string.
276 Add the current dictionary to the shell namespace.
278 @param ns_dict: A dictionary of symbol-values.
281 self.IP.user_ns.update(ns_dict)
285 Returns an auto completed line and/
or possibilities
for completion.
287 @param line: Given line so far.
288 @return: Line completed
as for as possible,
and possible further completions.
292 possibilities = self.
IP.
complete(split_line[-1])
295 possibilities = [
'', []]
297 def _commonPrefix(str1, str2):
299 Reduction function. returns common prefix of two given strings.
301 @param str1: First string.
302 @param str2: Second string
303 @return: Common prefix to both strings.
305 for i
in range(len(str1)):
306 if not str2.startswith(str1[:i+1]):
310 common_prefix = reduce(_commonPrefix, possibilities[1])
or split_line[-1]
311 completed = line[:-len(split_line[-1])]+common_prefix
316 return completed, possibilities[1]
319 def shell(self, cmd,verbose=0,debug=0,header=''):
321 Replacement method to allow shell commands without them blocking.
323 @param cmd: Shell command to execute.
324 @param verbose: Verbosity
325 @param debug: Debug level
326 @param header: Header to be printed before output
330 if verbose
or debug: print(header+cmd)
333 input, output = os.popen4(cmd)
351 Specialized text view for console-like workflow.
353 @cvar ANSI_COLORS: Mapping of terminal control sequence values to
354 tuples containing foreground
and background color names.
355 @type ANSI_COLORS: dictionary
357 @ivar text_buffer: Widget
's text buffer. @type text_buffer: Gtk.TextBuffer
358 @ivar color_pat: Regex of terminal color pattern
359 @type color_pat: _sre.SRE_Pattern
360 @ivar mark: Scroll mark
for automatic scrolling on input.
361 @type mark: Gtk.TextMark
362 @ivar line_start: Start of command line mark.
363 @type line_start: Gtk.TextMark
365 ANSI_COLORS = {'0;30': (
'Black',
None),
366 '0;31': (
'Red',
None),
367 '0;32': (
'Green',
None),
368 '0;33': (
'Brown',
None),
369 '0;34': (
'Blue',
None),
370 '0;35': (
'Purple',
None),
371 '0;36': (
'Cyan',
None),
372 '0;37': (
'LightGray',
None),
373 '1;30': (
'DarkGray',
None),
374 '1;31': (
'DarkRed',
None),
375 '1;32': (
'SeaGreen',
None),
376 '1;33': (
'Yellow',
None),
377 '1;34': (
'LightBlue',
None),
378 '1;35': (
'MediumPurple',
None),
379 '1;36': (
'LightCyan',
None),
380 '1;37': (
'White',
None),
381 '38;5;124;43': (
'DarkRed',
'Yellow'),
382 '38;5;241': (
'Gray',
None),
383 '38;5;241;43': (
'Gray',
'Yellow'),
384 '39': (
'Black',
None),
385 '39;49': (
'Red',
'White'),
386 '43': (
None,
'Yellow'),
387 '49': (
None,
'White')}
391 Initialize console view.
393 Gtk.TextView.__init__(self)
394 self.modify_font(Pango.FontDescription('Mono'))
395 self.set_cursor_visible(
True)
406 self.
text_buffer.create_tag(
'notouch', editable=
False)
407 self.
color_pat = re.compile(
'\x01?\x1b\[(.*?)m\x02?')
411 self.connect(
'key-press-event', self.
onKeyPress)
413 def write(self, text, editable=False):
415 Write given text to buffer.
417 @param text: Text to append.
418 @param editable: If true, added text
is editable.
421 GLib.idle_add(self._write, text, editable)
423 def _write(self, text, editable=False):
425 Write given text to buffer.
427 @param text: Text to append.
428 @param editable: If true, added text
is editable.
432 segment = segments.pop(0)
440 for tag
in ansi_tags:
441 i = segments.index(tag)
443 segments[i+1], str(tag))
450 self.scroll_mark_onscreen(self.
mark)
454 Prints prompt at start of line.
456 @param prompt: Prompt to
print.
463 Prints prompt at start of line.
465 @param prompt: Prompt to
print.
474 Replace currently entered command line with given text.
476 @param text: Text to use
as replacement.
483 Replace currently entered command line with given text.
485 @param text: Text to use
as replacement.
489 iter.forward_to_line_end()
495 Get text in current command line.
497 @return Text of current command line.
506 Show returned text from last command
and print new prompt.
508 @param text: Text to show.
515 Show returned text from last command
and print new prompt.
517 @param text: Text to show.
521 iter.forward_to_line_end()
533 if self.IP.rl_do_indent:
534 if self.no_input_splitter:
535 indentation = self.indent_spaces
537 indentation = self.IP.input_splitter.indent_spaces *
' '
542 Key press callback used for correcting behavior
for console-like
543 interfaces. For example
'home' should go to prompt,
not to beginning of
546 @param widget: Widget that key press accored
in.
547 @param event: Event object
548 @return Return
True if event should
not trickle.
551 insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)
552 selection_mark = self.text_buffer.get_selection_bound()
553 selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)
555 if event.keyval == Gdk.KEY_Home:
556 if event.state & Gdk.ModifierType.CONTROL_MASK
or event.state & Gdk.ModifierType.MOD1_MASK:
558 elif event.state & Gdk.ModifierType.SHIFT_MASK:
559 self.
text_buffer.move_mark(insert_mark, start_iter)
564 elif event.keyval == Gdk.KEY_Left:
565 insert_iter.backward_cursor_position()
566 if not insert_iter.editable(
True):
568 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [ord(
'L'), ord(
'l')]:
570 cursor_offset = self.
text_buffer.get_property(
'cursor-position')
571 cursor_pos_in_line = cursor_offset - start_iter.get_offset() + len(self.prompt)
573 self.
text_buffer.set_text(self.prompt + current_input)
577 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [Gdk.KEY_k, Gdk.KEY_K]:
579 if insert_iter.editable(
True):
582 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval == Gdk.KEY_C:
584 self.
text_buffer.copy_clipboard(Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD))
586 elif not event.string:
588 elif start_iter.compare(insert_iter) <= 0
and \
589 start_iter.compare(selection_iter) <= 0:
591 elif start_iter.compare(insert_iter) > 0
and \
592 start_iter.compare(selection_iter) > 0:
594 elif insert_iter.compare(selection_iter) < 0:
595 self.
text_buffer.move_mark(insert_mark, start_iter)
596 elif insert_iter.compare(selection_iter) > 0:
597 self.
text_buffer.move_mark(selection_mark, start_iter)
603 For some reason we can't extend onKeyPress directly (bug #500900).
604 @param event key press
626 Sub-class of both modified IPython
shell and L{ConsoleView} this makes
627 a GTK+ IPython console.
631 Initialize. Redirect I/O to console.
633 ConsoleView.__init__(self)
634 self.cout = StringIO()
635 IterableIPShell.__init__(self, cout=self.cout, cerr=self.cout,
645 Custom raw_input() replacement. Gets current line from console buffer.
647 @param prompt: Prompt to
print. Here
for compatibility
as replacement.
648 @return The current command line text.
652 raise KeyboardInterrupt
657 Key press callback with plenty of shell goodness, like history,
658 autocompletions, etc.
660 @param event: Event object.
661 @return True if event should
not trickle.
664 if event.get_state() & Gdk.ModifierType.CONTROL_MASK
and event.keyval == 99:
668 elif event.keyval == Gdk.KEY_Return:
671 elif event.keyval == Gdk.KEY_Up:
674 elif event.keyval == Gdk.KEY_Down:
677 elif event.keyval == Gdk.KEY_Tab:
681 if len(possibilities) > 1:
684 for symbol
in possibilities:
685 self.
write(symbol+
'\n')
692 Process current command line.
697 rv = self.cout.getvalue()
698 if rv: rv = rv.strip(
'\n')
700 self.
cout.truncate(0)
703if __name__ ==
"__main__":
704 window = Gtk.Window()
705 window.set_default_size(640, 320)
706 window.connect(
'delete-event',
lambda x, y: Gtk.main_quit())
def write(self, text, editable=False)
Write given text to buffer.
def changeLine(self, text)
Replace currently entered command line with given text.
dict ANSI_COLORS
color list
def _showPrompt(self, prompt)
Prints prompt at start of line.
def _showReturned(self, text)
Show returned text from last command and print new prompt.
def getCurrentLine(self)
Get text in current command line.
def onKeyPressExtend(self, event)
For some reason we can't extend onKeyPress directly (bug #500900).
def _write(self, text, editable=False)
Write given text to buffer.
def _changeLine(self, text)
Replace currently entered command line with given text.
def showPrompt(self, prompt)
Prints prompt at start of line.
def showReturned(self, text)
Show returned text from last command and print new prompt.
def onKeyPress(self, widget, event)
Key press callback used for correcting behavior for console-like interfaces.
def onKeyPressExtend(self, event)
Key press callback with plenty of shell goodness, like history, autocompletions, etc.
def raw_input(self, prompt='')
Custom raw_input() replacement.
def _processLine(self)
Process current command line.
no_input_splitter
no input splitter
def updateNamespace(self, ns_dict)
Add the current dictionary to the shell namespace.
def _getHistory(self)
Gets the command string of the current history level.
def __update_namespace(self)
Update self.IP namespace for autocompletion with sys.modules.
def __init__(self, argv=[], user_ns=None, user_global_ns=None, cin=None, cout=None, cerr=None, input_func=None)
Initializer.
def historyBack(self)
Provides one history command back.
history_level
history level
def generatePrompt(self, is_continuation)
Generate prompt depending on is_continuation value.
def historyForward(self)
Provides one history command forward.
indent_spaces
indent spaces
def shell(self, cmd, verbose=0, debug=0, header='')
Replacement method to allow shell commands without them blocking.
def execute(self)
Executes the current line provided by the shell object.
def complete(self, line)
Returns an auto completed line and/or possibilities for completion.