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(
"Gdk",
"3.0")
20gi.require_version(
"Gtk",
"3.0")
24from functools
import reduce
25from io
import StringIO
27from gi.repository
import Gdk, GLib, Gtk, Pango
28from packaging.version
import Version
77 Constructor for the IterableIPShell class
78 @param self: this object
79 @param argv: Command line options for IPython
80 @param user_ns: User namespace.
81 @param user_global_ns: User global namespace.
82 @param cin: Console standard input.
83 @param cout: Console standard output.
84 @param cerr: Console standard error.
85 @param input_func: Replacement for builtin raw_input()
89 IPython.terminal.interactiveshell.raw_input_original = input_func
90 if IPython.version_info < (8,):
92 io.stdin = io.IOStream(cin)
94 io.stdout = io.IOStream(cout)
96 io.stderr = io.IOStream(cerr)
107 io.raw_input =
lambda x:
None
109 os.environ[
"TERM"] =
"dumb"
110 excepthook = sys.excepthook
112 from traitlets.config.loader
import Config
115 cfg.InteractiveShell.colors =
"Linux"
116 cfg.Completer.use_jedi =
False
118 if IPython.version_info < (8,):
121 old_stdout, old_stderr = sys.stdout, sys.stderr
122 sys.stdout, sys.stderr = io.stdout.stream, io.stderr.stream
126 self.
IP = IPython.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
128 if IPython.version_info < (8,):
129 sys.stdout, sys.stderr = old_stdout, old_stderr
131 self.
IP.system =
lambda cmd: self.
shell(
132 self.
IP.var_expand(cmd), header=
"IPython system call: "
138 self.
IP.raw_input = input_func
139 sys.excepthook = excepthook
158 Update self.IP namespace for autocompletion with sys.modules
161 for k, v
in list(sys.modules.items()):
163 self.
IP.user_ns.update({k: v})
167 Executes the current line provided by the shell object.
172 if IPython.version_info < (8,):
176 orig_stdout = sys.stdout
177 sys.stdout = IPython.utils.io.stdout
179 orig_stdin = sys.stdin
180 sys.stdin = IPython.utils.io.stdin
184 self.
IP.hooks.pre_prompt_hook()
189 self.
IP.showtraceback()
190 if self.
IP.autoindent:
191 self.
IP.rl_do_indent =
True
194 line = self.
IP.raw_input(self.
prompt)
195 except KeyboardInterrupt:
196 self.
IP.write(
"\nKeyboardInterrupt\n")
200 self.
IP.input_splitter.reset()
202 self.
IP.showtraceback()
205 self.
lines.append(line)
209 self.
IP.input_splitter.push(line)
210 self.
iter_more = self.
IP.input_splitter.push_accepts_more()
213 source_raw =
"\n".join(self.
lines)
216 source_raw = self.
IP.input_splitter.raw_reset()
217 self.
IP.run_cell(source_raw, store_history=
True)
218 self.
IP.rl_do_indent =
False
222 self.
IP.rl_do_indent =
True
226 if IPython.version_info < (8,):
227 sys.stdout = orig_stdout
228 sys.stdin = orig_stdin
232 Generate prompt depending on is_continuation value
234 @param is_continuation
235 @return: The prompt string representation
247 Provides one history command back.
249 @param self this object
250 @return: The command string.
259 Provides one history command forward.
261 @param self this object
262 @return: The command string.
270 Gets the command string of the current history level.
272 @param self this object
273 @return: Historic command string.
283 Add the current dictionary to the shell namespace.
285 @param ns_dict: A dictionary of symbol-values.
288 self.
IP.user_ns.update(ns_dict)
292 Returns an auto completed line and/or possibilities for completion.
294 @param line: Given line so far.
295 @return: Line completed as for as possible, and possible further completions.
299 possibilities = self.
IP.
complete(split_line[-1])
302 possibilities = [
"", []]
305 def _commonPrefix(str1, str2):
307 Reduction function. returns common prefix of two given strings.
309 @param str1: First string.
310 @param str2: Second string
311 @return: Common prefix to both strings.
313 for i
in range(len(str1)):
314 if not str2.startswith(str1[: i + 1]):
319 common_prefix = reduce(_commonPrefix, possibilities[1])
or split_line[-1]
320 completed = line[: -len(split_line[-1])] + common_prefix
325 return completed, possibilities[1]
327 def shell(self, cmd, verbose=0, debug=0, header=""):
329 Replacement method to allow shell commands without them blocking.
331 @param cmd: Shell command to execute.
332 @param verbose: Verbosity
333 @param debug: Debug level
334 @param header: Header to be printed before output
342 input, output = os.popen4(cmd)
376 Specialized text view for console-like workflow.
378 @cvar ANSI_COLORS: Mapping of terminal control sequence values to
379 tuples containing foreground and background color names.
380 @type ANSI_COLORS: dictionary
382 @ivar text_buffer: Widget's text buffer.
383 @type text_buffer: Gtk.TextBuffer
384 @ivar color_pat: Regex of terminal color pattern
385 @type color_pat: _sre.SRE_Pattern
386 @ivar mark: Scroll mark for automatic scrolling on input.
387 @type mark: Gtk.TextMark
388 @ivar line_start: Start of command line mark.
389 @type line_start: Gtk.TextMark
392 "0;30": (
"Black",
None),
393 "0;31": (
"Red",
None),
394 "0;32": (
"Green",
None),
395 "0;33": (
"Brown",
None),
396 "0;34": (
"Blue",
None),
397 "0;35": (
"Purple",
None),
398 "0;36": (
"Cyan",
None),
399 "0;37": (
"LightGray",
None),
400 "1;30": (
"DarkGray",
None),
401 "1;31": (
"DarkRed",
None),
402 "1;32": (
"SeaGreen",
None),
403 "1;33": (
"Yellow",
None),
404 "1;34": (
"LightBlue",
None),
405 "1;35": (
"MediumPurple",
None),
406 "1;36": (
"LightCyan",
None),
407 "1;37": (
"White",
None),
408 "38;5;124;43": (
"DarkRed",
"Yellow"),
409 "38;5;241": (
"Gray",
None),
410 "38;5;241;43": (
"Gray",
"Yellow"),
411 "39": (
"Black",
None),
412 "39;49": (
"Red",
"White"),
413 "43": (
None,
"Yellow"),
414 "49": (
None,
"White"),
419 Initialize console view.
421 Gtk.TextView.__init__(self)
422 self.set_monospace(
True)
423 self.set_cursor_visible(
True)
426 "scroll_mark", self.
text_buffer.get_end_iter(),
False
436 self.
text_buffer.create_tag(
"notouch", editable=
False)
439 "line_start", self.
text_buffer.get_end_iter(),
True
443 def write(self, text, editable=False):
445 Write given text to buffer.
447 @param text: Text to append.
448 @param editable: If true, added text is editable.
455 Write given text to buffer.
457 @param text: Text to append.
458 @param editable: If true, added text is editable.
462 segment = segments.pop(0)
468 for tag
in ansi_tags:
469 i = segments.index(tag)
471 self.
text_buffer.get_end_iter(), segments[i + 1], str(tag)
481 self.scroll_mark_onscreen(self.
mark)
485 Prints prompt at start of line.
487 @param prompt: Prompt to print.
494 Prints prompt at start of line.
496 @param prompt: Prompt to print.
504 Replace currently entered command line with given text.
506 @param text: Text to use as replacement.
513 Replace currently entered command line with given text.
515 @param text: Text to use as replacement.
519 iter.forward_to_line_end()
525 Get text in current command line.
527 @return Text of current command line.
538 Show returned text from last command and print new prompt.
540 @param text: Text to show.
547 Show returned text from last command and print new prompt.
549 @param text: Text to show.
553 iter.forward_to_line_end()
564 if self.IP.rl_do_indent:
566 indentation = self.indent_spaces
568 indentation = self.IP.input_splitter.indent_spaces *
" "
573 Key press callback used for correcting behavior for console-like
574 interfaces. For example 'home' should go to prompt, not to beginning of
577 @param widget: Widget that key press accored in.
578 @param event: Event object
579 @return Return True if event should not trickle.
582 insert_iter = self.
text_buffer.get_iter_at_mark(insert_mark)
583 selection_mark = self.
text_buffer.get_selection_bound()
584 selection_iter = self.
text_buffer.get_iter_at_mark(selection_mark)
586 if event.keyval == Gdk.KEY_Home:
588 event.state & Gdk.ModifierType.CONTROL_MASK
589 or event.state & Gdk.ModifierType.MOD1_MASK
592 elif event.state & Gdk.ModifierType.SHIFT_MASK:
593 self.
text_buffer.move_mark(insert_mark, start_iter)
598 elif event.keyval == Gdk.KEY_Left:
599 insert_iter.backward_cursor_position()
600 if not insert_iter.editable(
True):
602 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [ord(
"L"), ord(
"l")]:
604 cursor_offset = self.
text_buffer.get_property(
"cursor-position")
605 cursor_pos_in_line = cursor_offset - start_iter.get_offset() + len(self.
prompt)
615 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [Gdk.KEY_k, Gdk.KEY_K]:
617 if insert_iter.editable(
True):
620 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval == Gdk.KEY_C:
622 self.
text_buffer.copy_clipboard(Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD))
624 elif not event.string:
626 elif start_iter.compare(insert_iter) <= 0
and start_iter.compare(selection_iter) <= 0:
628 elif start_iter.compare(insert_iter) > 0
and start_iter.compare(selection_iter) > 0:
630 elif insert_iter.compare(selection_iter) < 0:
631 self.
text_buffer.move_mark(insert_mark, start_iter)
632 elif insert_iter.compare(selection_iter) > 0:
633 self.
text_buffer.move_mark(selection_mark, start_iter)
639 For some reason we can't extend onKeyPress directly (bug #500900).
640 @param event key press
647class IPythonView(ConsoleView, IterableIPShell):
663 Sub-class of both modified IPython shell and L{ConsoleView} this makes
664 a GTK+ IPython console.
669 Initialize. Redirect I/O to console.
671 ConsoleView.__init__(self)
673 IterableIPShell.__init__(self, cout=self.
cout, cerr=self.
cout, input_func=self.
raw_input)
677 self.
cout.truncate(0)
682 Custom raw_input() replacement. Gets current line from console buffer.
684 @param prompt: Prompt to print. Here for compatibility as replacement.
685 @return The current command line text.
689 raise KeyboardInterrupt
694 Key press callback with plenty of shell goodness, like history,
695 autocompletions, etc.
697 @param event: Event object.
698 @return True if event should not trickle.
701 if event.get_state() & Gdk.ModifierType.CONTROL_MASK
and event.keyval == 99:
705 elif event.keyval == Gdk.KEY_Return:
708 elif event.keyval == Gdk.KEY_Up:
711 elif event.keyval == Gdk.KEY_Down:
714 elif event.keyval == Gdk.KEY_Tab:
718 if len(possibilities) > 1:
721 for symbol
in possibilities:
722 self.
write(symbol +
"\n")
729 Process current command line.
734 rv = self.
cout.getvalue()
738 self.
cout.truncate(0)
742if __name__ ==
"__main__":
743 window = Gtk.Window()
744 window.set_default_size(640, 320)
745 window.connect(
"delete-event",
lambda x, y: Gtk.main_quit())
write(self, text, editable=False)
Write given text to buffer.
getCurrentLine(self)
Get text in current command line.
onKeyPressExtend(self, event)
For some reason we can't extend onKeyPress directly (bug #500900).
_showPrompt(self, prompt)
Prints prompt at start of line.
_changeLine
_changeLine function
_write(self, text, editable=False)
Write given text to buffer.
showReturned(self, text)
Show returned text from last command and print new prompt.
_changeLine(self, text)
Replace currently entered command line with given text.
onKeyPress
onKeyPress function
no_input_splitter
no input splitter
_showPrompt
_showPrompt function
showPrompt(self, prompt)
Prints prompt at start of line.
_showReturned(self, text)
Show returned text from last command and print new prompt.
dict ANSI_COLORS
color list
changeLine(self, text)
Replace currently entered command line with given text.
onKeyPress(self, widget, event)
Key press callback used for correcting behavior for console-like interfaces.
_showReturned
_showReturned function
onKeyPressExtend(self, event)
Key press callback with plenty of shell goodness, like history, autocompletions, etc.
_processLine(self)
Process current command line.
raw_input(self, prompt="")
Custom raw_input() replacement.
no_input_splitter
no input splitter
historyBack(self)
Provides one history command back.
_getHistory(self)
Gets the command string of the current history level.
historyForward(self)
Provides one history command forward.
complete(self, line)
Returns an auto completed line and/or possibilities for completion.
updateNamespace(self, ns_dict)
Add the current dictionary to the shell namespace.
shell(self, cmd, verbose=0, debug=0, header="")
Replacement method to allow shell commands without them blocking.
__update_namespace(self)
Update self.IP namespace for autocompletion with sys.modules.
execute(self)
Executes the current line provided by the shell object.
history_level
history level
indent_spaces
indent spaces
__init__(self, argv=[], user_ns=None, user_global_ns=None, cin=None, cout=None, cerr=None, input_func=None)
Constructor for the IterableIPShell class.
generatePrompt(self, is_continuation)
Generate prompt depending on is_continuation value.