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}
19gi.require_version(
"Gtk",
"3.0")
23from functools
import reduce
24from io
import StringIO
26from gi.repository
import Gdk, GLib, Gtk, Pango
27from pkg_resources
import parse_version
76 Constructor for the IterableIPShell
class
77 @param self: this object
78 @param argv: Command line options
for IPython
79 @param user_ns: User namespace.
80 @param user_global_ns: User
global namespace.
81 @param cin: Console standard input.
82 @param cout: Console standard output.
83 @param cerr: Console standard error.
84 @param input_func: Replacement
for builtin raw_input()
88 IPython.terminal.interactiveshell.raw_input_original = input_func
89 if IPython.version_info < (8,):
91 io.stdin = io.IOStream(cin)
93 io.stdout = io.IOStream(cout)
95 io.stderr = io.IOStream(cerr)
106 io.raw_input =
lambda x:
None
108 os.environ[
"TERM"] =
"dumb"
109 excepthook = sys.excepthook
111 from traitlets.config.loader
import Config
114 cfg.InteractiveShell.colors =
"Linux"
115 cfg.Completer.use_jedi =
False
117 if IPython.version_info < (8,):
120 old_stdout, old_stderr = sys.stdout, sys.stderr
121 sys.stdout, sys.stderr = io.stdout.stream, io.stderr.stream
125 self.
IP = IPython.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
127 if IPython.version_info < (8,):
128 sys.stdout, sys.stderr = old_stdout, old_stderr
130 self.
IP.system =
lambda cmd: self.
shell(
131 self.
IP.var_expand(cmd), header=
"IPython system call: "
137 self.
IP.raw_input = input_func
138 sys.excepthook = excepthook
157 Update self.IP namespace for autocompletion
with sys.modules
160 for k, v
in list(sys.modules.items()):
162 self.
IP.user_ns.update({k: v})
166 Executes the current line provided by the shell object.
171 if IPython.version_info < (8,):
175 orig_stdout = sys.stdout
176 sys.stdout = IPython.utils.io.stdout
178 orig_stdin = sys.stdin
179 sys.stdin = IPython.utils.io.stdin
183 self.
IP.hooks.pre_prompt_hook()
188 self.
IP.showtraceback()
189 if self.
IP.autoindent:
190 self.
IP.rl_do_indent =
True
193 line = self.
IP.raw_input(self.
prompt)
194 except KeyboardInterrupt:
195 self.
IP.write(
"\nKeyboardInterrupt\n")
199 self.
IP.input_splitter.reset()
201 self.
IP.showtraceback()
204 self.
lines.append(line)
208 self.
IP.input_splitter.push(line)
209 self.
iter_more = self.
IP.input_splitter.push_accepts_more()
212 source_raw =
"\n".join(self.
lines)
215 source_raw = self.
IP.input_splitter.raw_reset()
216 self.
IP.run_cell(source_raw, store_history=
True)
217 self.
IP.rl_do_indent =
False
221 self.
IP.rl_do_indent =
True
225 if IPython.version_info < (8,):
226 sys.stdout = orig_stdout
227 sys.stdin = orig_stdin
231 Generate prompt depending on is_continuation value
233 @param is_continuation
234 @return: The prompt string representation
246 Provides one history command back.
248 @param self this object
249 @return: The command string.
258 Provides one history command forward.
260 @param self this object
261 @return: The command string.
269 Gets the command string of the current history level.
271 @param self this object
272 @return: Historic command string.
282 Add the current dictionary to the shell namespace.
284 @param ns_dict: A dictionary of symbol-values.
287 self.IP.user_ns.update(ns_dict)
291 Returns an auto completed line and/
or possibilities
for completion.
293 @param line: Given line so far.
294 @return: Line completed
as for as possible,
and possible further completions.
298 possibilities = self.
IP.
complete(split_line[-1])
301 possibilities = [
"", []]
304 def _commonPrefix(str1, str2):
306 Reduction function. returns common prefix of two given strings.
308 @param str1: First string.
309 @param str2: Second string
310 @return: Common prefix to both strings.
312 for i
in range(len(str1)):
313 if not str2.startswith(str1[: i + 1]):
318 common_prefix = reduce(_commonPrefix, possibilities[1])
or split_line[-1]
319 completed = line[: -len(split_line[-1])] + common_prefix
324 return completed, possibilities[1]
326 def shell(self, cmd, verbose=0, debug=0, header=""):
328 Replacement method to allow shell commands without them blocking.
330 @param cmd: Shell command to execute.
331 @param verbose: Verbosity
332 @param debug: Debug level
333 @param header: Header to be printed before output
341 input, output = os.popen4(cmd)
373 Specialized text view for console-like workflow.
375 @cvar ANSI_COLORS: Mapping of terminal control sequence values to
376 tuples containing foreground
and background color names.
377 @type ANSI_COLORS: dictionary
379 @ivar text_buffer: Widget
's text buffer. @type text_buffer: Gtk.TextBuffer
380 @ivar color_pat: Regex of terminal color pattern
381 @type color_pat: _sre.SRE_Pattern
382 @ivar mark: Scroll mark
for automatic scrolling on input.
383 @type mark: Gtk.TextMark
384 @ivar line_start: Start of command line mark.
385 @type line_start: Gtk.TextMark
388 "0;30": (
"Black",
None),
389 "0;31": (
"Red",
None),
390 "0;32": (
"Green",
None),
391 "0;33": (
"Brown",
None),
392 "0;34": (
"Blue",
None),
393 "0;35": (
"Purple",
None),
394 "0;36": (
"Cyan",
None),
395 "0;37": (
"LightGray",
None),
396 "1;30": (
"DarkGray",
None),
397 "1;31": (
"DarkRed",
None),
398 "1;32": (
"SeaGreen",
None),
399 "1;33": (
"Yellow",
None),
400 "1;34": (
"LightBlue",
None),
401 "1;35": (
"MediumPurple",
None),
402 "1;36": (
"LightCyan",
None),
403 "1;37": (
"White",
None),
404 "38;5;124;43": (
"DarkRed",
"Yellow"),
405 "38;5;241": (
"Gray",
None),
406 "38;5;241;43": (
"Gray",
"Yellow"),
407 "39": (
"Black",
None),
408 "39;49": (
"Red",
"White"),
409 "43": (
None,
"Yellow"),
410 "49": (
None,
"White"),
415 Initialize console view.
417 Gtk.TextView.__init__(self)
418 self.modify_font(Pango.FontDescription("Mono"))
419 self.set_cursor_visible(
True)
432 self.
text_buffer.create_tag(
"notouch", editable=
False)
433 self.
color_pat = re.compile(
"\x01?\x1b\[(.*?)m\x02?")
437 self.connect(
"key-press-event", self.
onKeyPress)
439 def write(self, text, editable=False):
441 Write given text to buffer.
443 @param text: Text to append.
444 @param editable: If true, added text
is editable.
447 GLib.idle_add(self._write, text, editable)
449 def _write(self, text, editable=False):
451 Write given text to buffer.
453 @param text: Text to append.
454 @param editable: If true, added text
is editable.
458 segment = segments.pop(0)
464 for tag
in ansi_tags:
465 i = segments.index(tag)
467 self.
text_buffer.get_end_iter(), segments[i + 1], str(tag)
477 self.scroll_mark_onscreen(self.
mark)
481 Prints prompt at start of line.
483 @param prompt: Prompt to
print.
490 Prints prompt at start of line.
492 @param prompt: Prompt to
print.
500 Replace currently entered command line with given text.
502 @param text: Text to use
as replacement.
509 Replace currently entered command line with given text.
511 @param text: Text to use
as replacement.
515 iter.forward_to_line_end()
521 Get text in current command line.
523 @return Text of current command line.
534 Show returned text from last command
and print new prompt.
536 @param text: Text to show.
543 Show returned text from last command
and print new prompt.
545 @param text: Text to show.
549 iter.forward_to_line_end()
560 if self.IP.rl_do_indent:
561 if self.no_input_splitter:
562 indentation = self.indent_spaces
564 indentation = self.IP.input_splitter.indent_spaces *
" "
569 Key press callback used for correcting behavior
for console-like
570 interfaces. For example
'home' should go to prompt,
not to beginning of
573 @param widget: Widget that key press accored
in.
574 @param event: Event object
575 @return Return
True if event should
not trickle.
578 insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)
579 selection_mark = self.text_buffer.get_selection_bound()
580 selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)
582 if event.keyval == Gdk.KEY_Home:
584 event.state & Gdk.ModifierType.CONTROL_MASK
585 or event.state & Gdk.ModifierType.MOD1_MASK
588 elif event.state & Gdk.ModifierType.SHIFT_MASK:
589 self.
text_buffer.move_mark(insert_mark, start_iter)
594 elif event.keyval == Gdk.KEY_Left:
595 insert_iter.backward_cursor_position()
596 if not insert_iter.editable(
True):
598 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [ord(
"L"), ord(
"l")]:
600 cursor_offset = self.
text_buffer.get_property(
"cursor-position")
601 cursor_pos_in_line = cursor_offset - start_iter.get_offset() + len(self.prompt)
605 self.
text_buffer.set_text(self.prompt + current_input)
611 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [Gdk.KEY_k, Gdk.KEY_K]:
613 if insert_iter.editable(
True):
616 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval == Gdk.KEY_C:
618 self.
text_buffer.copy_clipboard(Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD))
620 elif not event.string:
622 elif start_iter.compare(insert_iter) <= 0
and start_iter.compare(selection_iter) <= 0:
624 elif start_iter.compare(insert_iter) > 0
and start_iter.compare(selection_iter) > 0:
626 elif insert_iter.compare(selection_iter) < 0:
627 self.
text_buffer.move_mark(insert_mark, start_iter)
628 elif insert_iter.compare(selection_iter) > 0:
629 self.
text_buffer.move_mark(selection_mark, start_iter)
635 For some reason we can't extend onKeyPress directly (bug #500900).
636 @param event key press
659 Sub-class of both modified IPython
shell and L{ConsoleView} this makes
660 a GTK+ IPython console.
665 Initialize. Redirect I/O to console.
667 ConsoleView.__init__(self)
668 self.cout = StringIO()
678 Custom raw_input() replacement. Gets current line from console buffer.
680 @param prompt: Prompt to
print. Here
for compatibility
as replacement.
681 @return The current command line text.
685 raise KeyboardInterrupt
690 Key press callback with plenty of shell goodness, like history,
691 autocompletions, etc.
693 @param event: Event object.
694 @return True if event should
not trickle.
697 if event.get_state() & Gdk.ModifierType.CONTROL_MASK
and event.keyval == 99:
701 elif event.keyval == Gdk.KEY_Return:
704 elif event.keyval == Gdk.KEY_Up:
707 elif event.keyval == Gdk.KEY_Down:
710 elif event.keyval == Gdk.KEY_Tab:
714 if len(possibilities) > 1:
717 for symbol
in possibilities:
718 self.
write(symbol +
"\n")
725 Process current command line.
730 rv = self.cout.getvalue()
734 self.
cout.truncate(0)
738if __name__ ==
"__main__":
739 window = Gtk.Window()
740 window.set_default_size(640, 320)
741 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 _showReturned(self, text)
Show returned text from last command and print new prompt.
def getCurrentLine(self)
Get text in current command line.
def _showPrompt(self, prompt)
Prints prompt at start of line.
def onKeyPressExtend(self, event)
For some reason we can't extend onKeyPress directly (bug #500900).
def onKeyPress(self, widget, event)
Key press callback used for correcting behavior for console-like interfaces.
def showPrompt(self, prompt)
Prints prompt at start of line.
def _write(self, text, editable=False)
Write given text to buffer.
def _changeLine(self, text)
Replace currently entered command line with given text.
def showReturned(self, text)
Show returned text from last command and print new prompt.
def onKeyPressExtend(self, event)
Key press callback with plenty of shell goodness, like history, autocompletions, etc.
def _processLine(self)
Process current command line.
def raw_input(self, prompt="")
Custom raw_input() replacement.
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)
Constructor for the IterableIPShell class.
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.