2 Backend to the console plugin.
4 @author: Eitan Isaacson
5 @organization: IBM Corporation
6 @copyright: Copyright (c) 2007 IBM Corporation
9 All rights reserved. This program and the accompanying materials are made
10 available under the terms of the BSD which accompanies this distribution, and
11 is available at U{http://www.opensource.org/licenses/bsd-license.php}
21 from StringIO
import StringIO
24 from pkg_resources
import parse_version
74 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
75 cin=
None, cout=
None,cerr=
None, input_func=
None):
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()
90 if parse_version(IPython.release.version) >= parse_version(
"1.2.1"):
91 IPython.terminal.interactiveshell.raw_input_original = input_func
93 IPython.frontend.terminal.interactiveshell.raw_input_original = input_func
95 io.stdin = io.IOStream(cin)
97 io.stdout = io.IOStream(cout)
99 io.stderr = io.IOStream(cerr)
104 io.raw_input =
lambda x:
None
106 os.environ[
'TERM'] =
'dumb'
107 excepthook = sys.excepthook
109 from IPython.config.loader
import Config
111 cfg.InteractiveShell.colors =
"Linux"
116 old_stdout, old_stderr = sys.stdout, sys.stderr
117 sys.stdout, sys.stderr = io.stdout.stream, io.stderr.stream
121 if parse_version(IPython.release.version) >= parse_version(
"1.2.1"):
122 self.
IP = IPython.terminal.embed.InteractiveShellEmbed.instance(\
123 config=cfg, user_ns=user_ns)
125 self.
IP = IPython.frontend.terminal.embed.InteractiveShellEmbed.instance(\
126 config=cfg, user_ns=user_ns)
128 sys.stdout, sys.stderr = old_stdout, old_stderr
130 self.IP.system =
lambda cmd: self.
shell(self.IP.var_expand(cmd),
131 header=
'IPython system call: ')
136 self.IP.raw_input = input_func
137 sys.excepthook = excepthook
143 self.IP.readline_startup_hook(self.IP.pre_readline)
150 Update self.IP namespace for autocompletion with sys.modules
152 for k, v
in list(sys.modules.items()):
154 self.IP.user_ns.update({k:v})
158 Executes the current line provided by the shell object.
161 orig_stdout = sys.stdout
162 sys.stdout = IPython.utils.io.stdout
164 orig_stdin = sys.stdin
165 sys.stdin = IPython.utils.io.stdin;
168 self.IP.hooks.pre_prompt_hook()
173 self.IP.showtraceback()
174 if self.IP.autoindent:
175 self.IP.rl_do_indent =
True
178 line = self.IP.raw_input(self.
prompt)
179 except KeyboardInterrupt:
180 self.IP.write(
'\nKeyboardInterrupt\n')
181 self.IP.input_splitter.reset()
183 self.IP.showtraceback()
185 self.IP.input_splitter.push(line)
186 self.
iter_more = self.IP.input_splitter.push_accepts_more()
188 if (self.IP.SyntaxTB.last_syntax_error
and
189 self.IP.autoedit_syntax):
190 self.IP.edit_syntax_error()
192 if parse_version(IPython.release.version) >= parse_version(
"2.0.0-dev"):
193 source_raw = self.IP.input_splitter.raw_reset()
195 source_raw = self.IP.input_splitter.source_raw_reset()[1]
196 self.IP.run_cell(source_raw, store_history=
True)
197 self.IP.rl_do_indent =
False
201 self.IP.rl_do_indent =
True
204 sys.stdout = orig_stdout
205 sys.stdin = orig_stdin
209 Generate prompt depending on is_continuation value
211 @param is_continuation
212 @return: The prompt string representation
218 ver = IPython.__version__
220 prompt = self.IP.hooks.generate_prompt(is_continuation)
223 prompt = self.IP.prompt_manager.render(
'in2')
225 prompt = self.IP.prompt_manager.render(
'in')
232 Provides one history command back.
234 @param self this object
235 @return: The command string.
244 Provides one history command forward.
246 @param self this object
247 @return: The command string.
255 Get's the command string of the current history level.
257 @param self this object
258 @return: Historic command string.
268 Add the current dictionary to the shell namespace.
270 @param ns_dict: A dictionary of symbol-values.
273 self.IP.user_ns.update(ns_dict)
277 Returns an auto completed line and/or posibilities for completion.
279 @param line: Given line so far.
280 @return: Line completed as for as possible, and possible further completions.
282 split_line = self.complete_sep.split(line)
284 possibilities = self.IP.complete(split_line[-1])
287 possibilities = [
'', []]
289 def _commonPrefix(str1, str2):
291 Reduction function. returns common prefix of two given strings.
293 @param str1: First string.
294 @param str2: Second string
295 @return: Common prefix to both strings.
297 for i
in range(len(str1)):
298 if not str2.startswith(str1[:i+1]):
302 common_prefix = reduce(_commonPrefix, possibilities[1])
or line[-1]
303 completed = line[:-len(split_line[-1])]+common_prefix
308 return completed, possibilities[1]
311 def shell(self, cmd,verbose=0,debug=0,header=''):
313 Replacement method to allow shell commands without them blocking.
315 @param cmd: Shell command to execute.
316 @param verbose: Verbosity
317 @param debug: Debug level
318 @param header: Header to be printed before output
322 if verbose
or debug:
print header+cmd
325 input, output = os.popen4(cmd)
343 Specialized text view for console-like workflow.
345 @cvar ANSI_COLORS: Mapping of terminal colors to X11 names.
346 @type ANSI_COLORS: dictionary
348 @ivar text_buffer: Widget's text buffer.
349 @type text_buffer: gtk.TextBuffer
350 @ivar color_pat: Regex of terminal color pattern
351 @type color_pat: _sre.SRE_Pattern
352 @ivar mark: Scroll mark for automatic scrolling on input.
353 @type mark: gtk.TextMark
354 @ivar line_start: Start of command line mark.
355 @type line_start: gtk.TextMark
357 ANSI_COLORS = {
'0;30':
'Black',
'0;31':
'Red',
358 '0;32':
'Green',
'0;33':
'Brown',
359 '0;34':
'Blue',
'0;35':
'Purple',
360 '0;36':
'Cyan',
'0;37':
'LightGray',
361 '1;30':
'DarkGray',
'1;31':
'DarkRed',
362 '1;32':
'SeaGreen',
'1;33':
'Yellow',
363 '1;34':
'LightBlue',
'1;35':
'MediumPurple',
364 '1;36':
'LightCyan',
'1;37':
'White'}
368 Initialize console view.
370 gtk.TextView.__init__(self)
371 self.modify_font(pango.FontDescription(
'Mono'))
372 self.set_cursor_visible(
True)
374 self.
mark = self.text_buffer.create_mark(
'scroll_mark',
375 self.text_buffer.get_end_iter(),
378 self.text_buffer.create_tag(code,
381 self.text_buffer.create_tag(
'0')
382 self.text_buffer.create_tag(
'notouch', editable=
False)
385 self.text_buffer.create_mark(
'line_start',
386 self.text_buffer.get_end_iter(),
True)
387 self.connect(
'key-press-event', self.
onKeyPress)
389 def write(self, text, editable=False):
391 Write given text to buffer.
393 @param text: Text to append.
394 @param editable: If true, added text is editable.
397 gobject.idle_add(self.
_write, text, editable)
401 Write given text to buffer.
403 @param text: Text to append.
404 @param editable: If true, added text is editable.
407 segments = self.color_pat.split(text)
408 segment = segments.pop(0)
409 start_mark = self.text_buffer.create_mark(
None,
410 self.text_buffer.get_end_iter(),
412 self.text_buffer.insert(self.text_buffer.get_end_iter(), segment)
415 ansi_tags = self.color_pat.findall(text)
416 for tag
in ansi_tags:
417 i = segments.index(tag)
418 self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
419 segments[i+1], str(tag))
422 self.text_buffer.apply_tag_by_name(
'notouch',
423 self.text_buffer.get_iter_at_mark(start_mark),
424 self.text_buffer.get_end_iter())
425 self.text_buffer.delete_mark(start_mark)
426 self.scroll_mark_onscreen(self.
mark)
430 Prints prompt at start of line.
432 @param prompt: Prompt to print.
439 Prints prompt at start of line.
441 @param prompt: Prompt to print.
446 self.text_buffer.get_end_iter())
450 Replace currently entered command line with given text.
452 @param text: Text to use as replacement.
459 Replace currently entered command line with given text.
461 @param text: Text to use as replacement.
464 iter = self.text_buffer.get_iter_at_mark(self.
line_start)
465 iter.forward_to_line_end()
466 self.text_buffer.delete(self.text_buffer.get_iter_at_mark(self.
line_start), iter)
471 Get text in current command line.
473 @return Text of current command line.
475 rv = self.text_buffer.get_slice(
476 self.text_buffer.get_iter_at_mark(self.
line_start),
477 self.text_buffer.get_end_iter(),
False)
482 Show returned text from last command and print new prompt.
484 @param text: Text to show.
491 Show returned text from last command and print new prompt.
493 @param text: Text to show.
496 iter = self.text_buffer.get_iter_at_mark(self.
line_start)
497 iter.forward_to_line_end()
498 self.text_buffer.apply_tag_by_name(
500 self.text_buffer.get_iter_at_mark(self.
line_start),
506 self.text_buffer.move_mark(self.
line_start,self.text_buffer.get_end_iter())
507 self.text_buffer.place_cursor(self.text_buffer.get_end_iter())
509 if self.IP.rl_do_indent:
510 indentation = self.IP.input_splitter.indent_spaces *
' '
511 self.text_buffer.insert_at_cursor(indentation)
515 Key press callback used for correcting behavior for console-like
516 interfaces. For example 'home' should go to prompt, not to begining of
519 @param widget: Widget that key press accored in.
520 @param event: Event object
521 @return Return True if event should not trickle.
523 insert_mark = self.text_buffer.get_insert()
524 insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)
525 selection_mark = self.text_buffer.get_selection_bound()
526 selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)
527 start_iter = self.text_buffer.get_iter_at_mark(self.
line_start)
528 if event.keyval == gtk.keysyms.Home:
529 if event.state & gtk.gdk.CONTROL_MASK
or event.state & gtk.gdk.MOD1_MASK:
531 elif event.state & gtk.gdk.SHIFT_MASK:
532 self.text_buffer.move_mark(insert_mark, start_iter)
535 self.text_buffer.place_cursor(start_iter)
537 elif event.keyval == gtk.keysyms.Left:
538 insert_iter.backward_cursor_position()
539 if not insert_iter.editable(
True):
541 elif not event.string:
543 elif start_iter.compare(insert_iter) <= 0
and \
544 start_iter.compare(selection_iter) <= 0:
546 elif start_iter.compare(insert_iter) > 0
and \
547 start_iter.compare(selection_iter) > 0:
548 self.text_buffer.place_cursor(start_iter)
549 elif insert_iter.compare(selection_iter) < 0:
550 self.text_buffer.move_mark(insert_mark, start_iter)
551 elif insert_iter.compare(selection_iter) > 0:
552 self.text_buffer.move_mark(selection_mark, start_iter)
558 For some reason we can't extend onKeyPress directly (bug #500900).
559 @param event key press
565 class IPythonView(ConsoleView, IterableIPShell):
581 Sub-class of both modified IPython shell and L{ConsoleView} this makes
582 a GTK+ IPython console.
586 Initialize. Redirect I/O to console.
588 ConsoleView.__init__(self)
590 IterableIPShell.__init__(self, cout=self.
cout,cerr=self.
cout,
595 self.cout.truncate(0)
600 Custom raw_input() replacement. Get's current line from console buffer.
602 @param prompt: Prompt to print. Here for compatability as replacement.
603 @return The current command line text.
607 raise KeyboardInterrupt
612 Key press callback with plenty of shell goodness, like history,
613 autocompletions, etc.
615 @param event: Event object.
616 @return True if event should not trickle.
619 if event.state & gtk.gdk.CONTROL_MASK
and event.keyval == 99:
623 elif event.keyval == gtk.keysyms.Return:
626 elif event.keyval == gtk.keysyms.Up:
629 elif event.keyval == gtk.keysyms.Down:
632 elif event.keyval == gtk.keysyms.Tab:
636 if len(possibilities) > 1:
639 for symbol
in possibilities:
640 self.
write(symbol+
'\n')
647 Process current command line.
652 rv = self.cout.getvalue()
653 if rv: rv = rv.strip(
'\n')
655 self.cout.truncate(0)
658 if __name__ ==
"__main__":
659 window = gtk.Window()
660 window.set_default_size(640, 320)
661 window.connect(
'delete-event',
lambda x, y: gtk.main_quit())
def onKeyPressExtend(self, event)
For some reason we can't extend onKeyPress directly (bug #500900).
def onKeyPressExtend(self, event)
Key press callback with plenty of shell goodness, like history, autocompletions, etc.
def getCurrentLine(self)
Get text in current command line.
def _processLine(self)
Process current command line.
def execute(self)
Executes the current line provided by the shell object.
def _write
Write given text to buffer.
def _getHistory(self)
Get's the command string of the current history level.
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.
history_level
history level
def onKeyPress(self, widget, event)
Key press callback used for correcting behavior for console-like interfaces.
dictionary ANSI_COLORS
color list
def __update_namespace(self)
Update self.IP namespace for autocompletion with sys.modules.
def historyBack(self)
Provides one history command back.
def write
Write given text to buffer.
def generatePrompt(self, is_continuation)
Generate prompt depending on is_continuation value.
def _changeLine(self, text)
Replace currently entered command line with given text.
def historyForward(self)
Provides one history command forward.
def shell
Replacement method to allow shell commands without them blocking.
def updateNamespace(self, ns_dict)
Add the current dictionary to the shell namespace.
def _showPrompt(self, prompt)
Prints prompt at start of line.
def showPrompt(self, prompt)
Prints prompt at start of line.
def complete(self, line)
Returns an auto completed line and/or posibilities for completion.
def raw_input
Custom raw_input() replacement.
def showReturned(self, text)
Show returned text from last command and print new prompt.