From c7654f669c71df102e62f106611f1c95cb53faef 2010-09-07 04:41:18 From: Fernando Perez Date: 2010-09-07 04:41:18 Subject: [PATCH] Move terminal-only magics to the terminal class. This lets us keep in the base class only what's common to all frontends. --- diff --git a/IPython/core/magic.py b/IPython/core/magic.py index 793ea63..1d6a7de 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -425,12 +425,6 @@ Currently the magic system has the following functions:\n""" Magic.auto_status[self.shell.automagic] ) ) page.page(outmsg) - def magic_autoindent(self, parameter_s = ''): - """Toggle autoindent on/off (if available).""" - - self.shell.set_autoindent() - print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent] - def magic_automagic(self, parameter_s = ''): """Make magic functions callable without having to type the initial %. @@ -2428,22 +2422,6 @@ Defaulting color scheme to 'NoColor'""" else: shell.inspector.set_active_scheme('NoColor') - def magic_color_info(self,parameter_s = ''): - """Toggle color_info. - - The color_info configuration parameter controls whether colors are - used for displaying object details (by things like %psource, %pfile or - the '?' system). This function toggles this value with each call. - - Note that unless you have a fairly recent pager (less works better - than more) in your system, using colored object information displays - will not work properly. Test it and see.""" - - self.shell.color_info = not self.shell.color_info - self.magic_colors(self.shell.colors) - print 'Object introspection functions have now coloring:', - print ['OFF','ON'][int(self.shell.color_info)] - def magic_Pprint(self, parameter_s=''): """Toggle pretty printing on/off.""" @@ -2544,7 +2522,6 @@ Defaulting color scheme to 'NoColor'""" print "Removing %stored alias",aname del stored[aname] self.db['stored_aliases'] = stored - def magic_rehashx(self, parameter_s = ''): """Update the alias table with all executable files in $PATH. @@ -3150,100 +3127,6 @@ Defaulting color scheme to 'NoColor'""" self.user_ns[par] = SList(block.splitlines()) print "Block assigned to '%s'" % par - def magic_cpaste(self, parameter_s=''): - """Allows you to paste & execute a pre-formatted code block from clipboard. - - You must terminate the block with '--' (two minus-signs) alone on the - line. You can also provide your own sentinel with '%paste -s %%' ('%%' - is the new sentinel for this operation) - - The block is dedented prior to execution to enable execution of method - definitions. '>' and '+' characters at the beginning of a line are - ignored, to allow pasting directly from e-mails, diff files and - doctests (the '...' continuation prompt is also stripped). The - executed block is also assigned to variable named 'pasted_block' for - later editing with '%edit pasted_block'. - - You can also pass a variable name as an argument, e.g. '%cpaste foo'. - This assigns the pasted block to variable 'foo' as string, without - dedenting or executing it (preceding >>> and + is still stripped) - - '%cpaste -r' re-executes the block previously entered by cpaste. - - Do not be alarmed by garbled output on Windows (it's a readline bug). - Just press enter and type -- (and press enter again) and the block - will be what was just pasted. - - IPython statements (magics, shell escapes) are not supported (yet). - - See also - -------- - paste: automatically pull code from clipboard. - """ - - opts,args = self.parse_options(parameter_s,'rs:',mode='string') - par = args.strip() - if opts.has_key('r'): - self._rerun_pasted() - return - - sentinel = opts.get('s','--') - - block = self._strip_pasted_lines_for_code( - self._get_pasted_lines(sentinel)) - - self._execute_block(block, par) - - def magic_paste(self, parameter_s=''): - """Allows you to paste & execute a pre-formatted code block from clipboard. - - The text is pulled directly from the clipboard without user - intervention and printed back on the screen before execution (unless - the -q flag is given to force quiet mode). - - The block is dedented prior to execution to enable execution of method - definitions. '>' and '+' characters at the beginning of a line are - ignored, to allow pasting directly from e-mails, diff files and - doctests (the '...' continuation prompt is also stripped). The - executed block is also assigned to variable named 'pasted_block' for - later editing with '%edit pasted_block'. - - You can also pass a variable name as an argument, e.g. '%paste foo'. - This assigns the pasted block to variable 'foo' as string, without - dedenting or executing it (preceding >>> and + is still stripped) - - Options - ------- - - -r: re-executes the block previously entered by cpaste. - - -q: quiet mode: do not echo the pasted text back to the terminal. - - IPython statements (magics, shell escapes) are not supported (yet). - - See also - -------- - cpaste: manually paste code into terminal until you mark its end. - """ - opts,args = self.parse_options(parameter_s,'rq',mode='string') - par = args.strip() - if opts.has_key('r'): - self._rerun_pasted() - return - - text = self.shell.hooks.clipboard_get() - block = self._strip_pasted_lines_for_code(text.splitlines()) - - # By default, echo back to terminal unless quiet mode is requested - if not opts.has_key('q'): - write = self.shell.write - write(self.shell.pycolorize(block)) - if not block.endswith('\n'): - write('\n') - write("## -- End pasted text --\n") - - self._execute_block(block, par) - def magic_quickref(self,arg): """ Show a quick reference sheet """ import IPython.core.usage diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py index de9adaa..245fa48 100644 --- a/IPython/frontend/terminal/interactiveshell.py +++ b/IPython/frontend/terminal/interactiveshell.py @@ -517,6 +517,114 @@ class TerminalInteractiveShell(InteractiveShell): self.ask_exit() else: self.ask_exit() + + #------------------------------------------------------------------------ + # Magic overrides + #------------------------------------------------------------------------ + # Once the base class stops inheriting from magic, this code needs to be + # moved into a separate machinery as well. For now, at least isolate here + # the magics which this class needs to implement differently from the base + # class, or that are unique to it. + + def magic_autoindent(self, parameter_s = ''): + """Toggle autoindent on/off (if available).""" + + self.shell.set_autoindent() + print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent] + + def magic_cpaste(self, parameter_s=''): + """Paste & execute a pre-formatted code block from clipboard. + + You must terminate the block with '--' (two minus-signs) alone on the + line. You can also provide your own sentinel with '%paste -s %%' ('%%' + is the new sentinel for this operation) + + The block is dedented prior to execution to enable execution of method + definitions. '>' and '+' characters at the beginning of a line are + ignored, to allow pasting directly from e-mails, diff files and + doctests (the '...' continuation prompt is also stripped). The + executed block is also assigned to variable named 'pasted_block' for + later editing with '%edit pasted_block'. + + You can also pass a variable name as an argument, e.g. '%cpaste foo'. + This assigns the pasted block to variable 'foo' as string, without + dedenting or executing it (preceding >>> and + is still stripped) + + '%cpaste -r' re-executes the block previously entered by cpaste. + + Do not be alarmed by garbled output on Windows (it's a readline bug). + Just press enter and type -- (and press enter again) and the block + will be what was just pasted. + + IPython statements (magics, shell escapes) are not supported (yet). + + See also + -------- + paste: automatically pull code from clipboard. + """ + + opts,args = self.parse_options(parameter_s,'rs:',mode='string') + par = args.strip() + if opts.has_key('r'): + self._rerun_pasted() + return + + sentinel = opts.get('s','--') + + block = self._strip_pasted_lines_for_code( + self._get_pasted_lines(sentinel)) + + self._execute_block(block, par) + + def magic_paste(self, parameter_s=''): + """Paste & execute a pre-formatted code block from clipboard. + + The text is pulled directly from the clipboard without user + intervention and printed back on the screen before execution (unless + the -q flag is given to force quiet mode). + + The block is dedented prior to execution to enable execution of method + definitions. '>' and '+' characters at the beginning of a line are + ignored, to allow pasting directly from e-mails, diff files and + doctests (the '...' continuation prompt is also stripped). The + executed block is also assigned to variable named 'pasted_block' for + later editing with '%edit pasted_block'. + + You can also pass a variable name as an argument, e.g. '%paste foo'. + This assigns the pasted block to variable 'foo' as string, without + dedenting or executing it (preceding >>> and + is still stripped) + + Options + ------- + + -r: re-executes the block previously entered by cpaste. + + -q: quiet mode: do not echo the pasted text back to the terminal. + + IPython statements (magics, shell escapes) are not supported (yet). + + See also + -------- + cpaste: manually paste code into terminal until you mark its end. + """ + opts,args = self.parse_options(parameter_s,'rq',mode='string') + par = args.strip() + if opts.has_key('r'): + self._rerun_pasted() + return + + text = self.shell.hooks.clipboard_get() + block = self._strip_pasted_lines_for_code(text.splitlines()) + + # By default, echo back to terminal unless quiet mode is requested + if not opts.has_key('q'): + write = self.shell.write + write(self.shell.pycolorize(block)) + if not block.endswith('\n'): + write('\n') + write("## -- End pasted text --\n") + + self._execute_block(block, par) InteractiveShellABC.register(TerminalInteractiveShell) diff --git a/IPython/zmq/zmqshell.py b/IPython/zmq/zmqshell.py index f0362df..4fdbd5e 100644 --- a/IPython/zmq/zmqshell.py +++ b/IPython/zmq/zmqshell.py @@ -78,6 +78,61 @@ class ZMQInteractiveShell(InteractiveShell): displayhook_class = Type(ZMQDisplayHook) + + def auto_rewrite_input(self, cmd): + """Called to show the auto-rewritten input for autocall and friends. + + FIXME: this payload is currently not correctly processed by the + frontend. + """ + new = self.displayhook.prompt1.auto_rewrite() + cmd + payload = dict( + source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input', + transformed_input=new, + ) + self.payload_manager.write_payload(payload) + + def ask_exit(self): + """Engage the exit actions.""" + payload = dict( + source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit', + exit=True, + ) + self.payload_manager.write_payload(payload) + + def _showtraceback(self, etype, evalue, stb): + + exc_content = { + u'traceback' : stb, + u'ename' : unicode(etype.__name__), + u'evalue' : unicode(evalue) + } + + dh = self.displayhook + exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header) + # Send exception info over pub socket for other clients than the caller + # to pick up + dh.pub_socket.send_json(exc_msg) + + # FIXME - Hack: store exception info in shell object. Right now, the + # caller is reading this info after the fact, we need to fix this logic + # to remove this hack. Even uglier, we need to store the error status + # here, because in the main loop, the logic that sets it is being + # skipped because runlines swallows the exceptions. + exc_content[u'status'] = u'error' + self._reply_content = exc_content + # /FIXME + + return exc_content + + #------------------------------------------------------------------------ + # Magic overrides + #------------------------------------------------------------------------ + # Once the base class stops inheriting from magic, this code needs to be + # moved into a separate machinery as well. For now, at least isolate here + # the magics which this class needs to implement differently from the base + # class, or that are unique to it. + def magic_doctest_mode(self,parameter_s=''): """Toggle doctest mode on and off. @@ -423,55 +478,12 @@ class ZMQInteractiveShell(InteractiveShell): self.payload_manager.write_payload(payload) def magic_gui(self, *args, **kwargs): - raise NotImplementedError('GUI support must be enabled in command line options.') + raise NotImplementedError( + 'GUI support must be enabled in command line options.') def magic_pylab(self, *args, **kwargs): - raise NotImplementedError('pylab support must be enabled in commandl in options.') - - def auto_rewrite_input(self, cmd): - """Called to show the auto-rewritten input for autocall and friends. - - FIXME: this payload is currently not correctly processed by the - frontend. - """ - new = self.displayhook.prompt1.auto_rewrite() + cmd - payload = dict( - source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input', - transformed_input=new, - ) - self.payload_manager.write_payload(payload) - - def ask_exit(self): - """Engage the exit actions.""" - payload = dict( - source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit', - exit=True, - ) - self.payload_manager.write_payload(payload) - - def _showtraceback(self, etype, evalue, stb): - - exc_content = { - u'traceback' : stb, - u'ename' : unicode(etype.__name__), - u'evalue' : unicode(evalue) - } + raise NotImplementedError( + 'pylab support must be enabled in command line options.') - dh = self.displayhook - exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header) - # Send exception info over pub socket for other clients than the caller - # to pick up - dh.pub_socket.send_json(exc_msg) - - # FIXME - Hack: store exception info in shell object. Right now, the - # caller is reading this info after the fact, we need to fix this logic - # to remove this hack. Even uglier, we need to store the error status - # here, because in the main loop, the logic that sets it is being - # skipped because runlines swallows the exceptions. - exc_content[u'status'] = u'error' - self._reply_content = exc_content - # /FIXME - - return exc_content InteractiveShellABC.register(ZMQInteractiveShell)