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)
375 Specialized text view for console-like workflow.
377 @cvar ANSI_COLORS: Mapping of terminal control sequence values to
378 tuples containing foreground and background color names.
379 @type ANSI_COLORS: dictionary
381 @ivar text_buffer: Widget's text buffer.
382 @type text_buffer: Gtk.TextBuffer
383 @ivar color_pat: Regex of terminal color pattern
384 @type color_pat: _sre.SRE_Pattern
385 @ivar mark: Scroll mark for automatic scrolling on input.
386 @type mark: Gtk.TextMark
387 @ivar line_start: Start of command line mark.
388 @type line_start: Gtk.TextMark
391 "0;30": (
"Black",
None),
392 "0;31": (
"Red",
None),
393 "0;32": (
"Green",
None),
394 "0;33": (
"Brown",
None),
395 "0;34": (
"Blue",
None),
396 "0;35": (
"Purple",
None),
397 "0;36": (
"Cyan",
None),
398 "0;37": (
"LightGray",
None),
399 "1;30": (
"DarkGray",
None),
400 "1;31": (
"DarkRed",
None),
401 "1;32": (
"SeaGreen",
None),
402 "1;33": (
"Yellow",
None),
403 "1;34": (
"LightBlue",
None),
404 "1;35": (
"MediumPurple",
None),
405 "1;36": (
"LightCyan",
None),
406 "1;37": (
"White",
None),
407 "38;5;124;43": (
"DarkRed",
"Yellow"),
408 "38;5;241": (
"Gray",
None),
409 "38;5;241;43": (
"Gray",
"Yellow"),
410 "39": (
"Black",
None),
411 "39;49": (
"Red",
"White"),
412 "43": (
None,
"Yellow"),
413 "49": (
None,
"White"),
418 Initialize console view.
420 Gtk.TextView.__init__(self)
421 self.modify_font(Pango.FontDescription(
"Mono"))
422 self.set_cursor_visible(
True)
425 "scroll_mark", self.
text_buffer.get_end_iter(),
False
435 self.
text_buffer.create_tag(
"notouch", editable=
False)
438 "line_start", self.
text_buffer.get_end_iter(),
True
442 def write(self, text, editable=False):
444 Write given text to buffer.
446 @param text: Text to append.
447 @param editable: If true, added text is editable.
454 Write given text to buffer.
456 @param text: Text to append.
457 @param editable: If true, added text is editable.
461 segment = segments.pop(0)
467 for tag
in ansi_tags:
468 i = segments.index(tag)
470 self.
text_buffer.get_end_iter(), segments[i + 1], str(tag)
480 self.scroll_mark_onscreen(self.
mark)
484 Prints prompt at start of line.
486 @param prompt: Prompt to print.
493 Prints prompt at start of line.
495 @param prompt: Prompt to print.
503 Replace currently entered command line with given text.
505 @param text: Text to use as replacement.
512 Replace currently entered command line with given text.
514 @param text: Text to use as replacement.
518 iter.forward_to_line_end()
524 Get text in current command line.
526 @return Text of current command line.
537 Show returned text from last command and print new prompt.
539 @param text: Text to show.
546 Show returned text from last command and print new prompt.
548 @param text: Text to show.
552 iter.forward_to_line_end()
563 if self.IP.rl_do_indent:
565 indentation = self.indent_spaces
567 indentation = self.IP.input_splitter.indent_spaces *
" "
572 Key press callback used for correcting behavior for console-like
573 interfaces. For example 'home' should go to prompt, not to beginning of
576 @param widget: Widget that key press accored in.
577 @param event: Event object
578 @return Return True if event should not trickle.
581 insert_iter = self.
text_buffer.get_iter_at_mark(insert_mark)
582 selection_mark = self.
text_buffer.get_selection_bound()
583 selection_iter = self.
text_buffer.get_iter_at_mark(selection_mark)
585 if event.keyval == Gdk.KEY_Home:
587 event.state & Gdk.ModifierType.CONTROL_MASK
588 or event.state & Gdk.ModifierType.MOD1_MASK
591 elif event.state & Gdk.ModifierType.SHIFT_MASK:
592 self.
text_buffer.move_mark(insert_mark, start_iter)
597 elif event.keyval == Gdk.KEY_Left:
598 insert_iter.backward_cursor_position()
599 if not insert_iter.editable(
True):
601 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [ord(
"L"), ord(
"l")]:
603 cursor_offset = self.
text_buffer.get_property(
"cursor-position")
604 cursor_pos_in_line = cursor_offset - start_iter.get_offset() + len(self.
prompt)
614 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval
in [Gdk.KEY_k, Gdk.KEY_K]:
616 if insert_iter.editable(
True):
619 elif event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval == Gdk.KEY_C:
621 self.
text_buffer.copy_clipboard(Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD))
623 elif not event.string:
625 elif start_iter.compare(insert_iter) <= 0
and start_iter.compare(selection_iter) <= 0:
627 elif start_iter.compare(insert_iter) > 0
and start_iter.compare(selection_iter) > 0:
629 elif insert_iter.compare(selection_iter) < 0:
630 self.
text_buffer.move_mark(insert_mark, start_iter)
631 elif insert_iter.compare(selection_iter) > 0:
632 self.
text_buffer.move_mark(selection_mark, start_iter)
638 For some reason we can't extend onKeyPress directly (bug #500900).
639 @param event key press
646class IPythonView(ConsoleView, IterableIPShell):
662 Sub-class of both modified IPython shell and L{ConsoleView} this makes
663 a GTK+ IPython console.
668 Initialize. Redirect I/O to console.
670 ConsoleView.__init__(self)
672 IterableIPShell.__init__(self, cout=self.
cout, cerr=self.
cout, input_func=self.
raw_input)
676 self.
cout.truncate(0)
681 Custom raw_input() replacement. Gets current line from console buffer.
683 @param prompt: Prompt to print. Here for compatibility as replacement.
684 @return The current command line text.
688 raise KeyboardInterrupt
693 Key press callback with plenty of shell goodness, like history,
694 autocompletions, etc.
696 @param event: Event object.
697 @return True if event should not trickle.
700 if event.get_state() & Gdk.ModifierType.CONTROL_MASK
and event.keyval == 99:
704 elif event.keyval == Gdk.KEY_Return:
707 elif event.keyval == Gdk.KEY_Up:
710 elif event.keyval == Gdk.KEY_Down:
713 elif event.keyval == Gdk.KEY_Tab:
717 if len(possibilities) > 1:
720 for symbol
in possibilities:
721 self.
write(symbol +
"\n")
728 Process current command line.
733 rv = self.
cout.getvalue()
737 self.
cout.truncate(0)
741if __name__ ==
"__main__":
742 window = Gtk.Window()
743 window.set_default_size(640, 320)
744 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.