Exemple #1
0
    def __init__(self, shell):
        """Create a new history manager associated with a shell instance.
        """
        # We need a pointer back to the shell for various tasks.
        self.shell = shell
        
        # List of input with multi-line handling.
        self.input_hist = InputList()
        # This one will hold the 'raw' input history, without any
        # pre-processing.  This will allow users to retrieve the input just as
        # it was exactly typed in by the user, with %hist -r.
        self.input_hist_raw = InputList()

        # list of visited directories
        try:
            self.dir_hist = [os.getcwd()]
        except OSError:
            self.dir_hist = []

        # dict of output history
        self.output_hist = {}

        # Now the history file
        if shell.profile:
            histfname = 'history-%s' % shell.profile
        else:
            histfname = 'history'
        self.hist_file = os.path.join(shell.ipython_dir, histfname)

        # Objects related to shadow history management
        self._init_shadow_hist()
    
        self._i00, self._i, self._ii, self._iii = '','','',''

        # Object is fully initialized, we can now call methods on it.
        
        # Fill the history zero entry, user counter starts at 1
        self.store_inputs('\n', '\n')

        # For backwards compatibility, we must put these back in the shell
        # object, until we've removed all direct uses of the history objects in
        # the shell itself.
        shell.input_hist = self.input_hist
        shell.input_hist_raw = self.input_hist_raw
        shell.output_hist = self.output_hist
        shell.dir_hist = self.dir_hist
        shell.histfile = self.hist_file
        shell.shadowhist = self.shadow_hist
        shell.db = self.shadow_db
    def mainloop(self, display_banner=None):
        """Start the mainloop.

        If an optional banner argument is given, it will override the
        internally created default banner.
        """
        
        with nested(self.builtin_trap, self.display_trap):

            # if you run stuff with -c <cmd>, raw hist is not updated
            # ensure that it's in sync
            if len(self.input_hist) != len (self.input_hist_raw):
                self.input_hist_raw = InputList(self.input_hist)

            while 1:
                try:
                    self.interact(display_banner=display_banner)
                    #self.interact_with_readline()                
                    # XXX for testing of a readline-decoupled repl loop, call
                    # interact_with_readline above
                    break
                except KeyboardInterrupt:
                    # this should not be necessary, but KeyboardInterrupt
                    # handling seems rather unpredictable...
                    self.write("\nKeyboardInterrupt in interact()\n")
Exemple #3
0
class HistoryManager(object):
    """A class to organize all history-related functionality in one place.
    """
    # Public interface

    # An instance of the IPython shell we are attached to
    shell = None
    # An InputList instance to hold processed history
    input_hist = None
    # An InputList instance to hold raw history (as typed by user)
    input_hist_raw = None
    # A list of directories visited during session
    dir_hist = None
    # A dict of output history, keyed with ints from the shell's execution count
    output_hist = None
    # String with path to the history file
    hist_file = None
    # PickleShareDB instance holding the raw data for the shadow history
    shadow_db = None
    # ShadowHist instance with the actual shadow history
    shadow_hist = None
    
    # Private interface
    # Variables used to store the three last inputs from the user.  On each new
    # history update, we populate the user's namespace with these, shifted as
    # necessary.
    _i00, _i, _ii, _iii = '','','',''
    
    def __init__(self, shell):
        """Create a new history manager associated with a shell instance.
        """
        # We need a pointer back to the shell for various tasks.
        self.shell = shell
        
        # List of input with multi-line handling.
        self.input_hist = InputList()
        # This one will hold the 'raw' input history, without any
        # pre-processing.  This will allow users to retrieve the input just as
        # it was exactly typed in by the user, with %hist -r.
        self.input_hist_raw = InputList()

        # list of visited directories
        try:
            self.dir_hist = [os.getcwd()]
        except OSError:
            self.dir_hist = []

        # dict of output history
        self.output_hist = {}

        # Now the history file
        if shell.profile:
            histfname = 'history-%s' % shell.profile
        else:
            histfname = 'history'
        self.hist_file = os.path.join(shell.ipython_dir, histfname)

        # Objects related to shadow history management
        self._init_shadow_hist()
    
        self._i00, self._i, self._ii, self._iii = '','','',''

        # Object is fully initialized, we can now call methods on it.
        
        # Fill the history zero entry, user counter starts at 1
        self.store_inputs('\n', '\n')

        # For backwards compatibility, we must put these back in the shell
        # object, until we've removed all direct uses of the history objects in
        # the shell itself.
        shell.input_hist = self.input_hist
        shell.input_hist_raw = self.input_hist_raw
        shell.output_hist = self.output_hist
        shell.dir_hist = self.dir_hist
        shell.histfile = self.hist_file
        shell.shadowhist = self.shadow_hist
        shell.db = self.shadow_db

    def _init_shadow_hist(self):
        try:
            self.shadow_db = PickleShareDB(os.path.join(
                                           self.shell.ipython_dir, 'db'))
        except UnicodeDecodeError:
            print("Your ipython_dir can't be decoded to unicode!")
            print("Please set HOME environment variable to something that")
            print(r"only has ASCII characters, e.g. c:\home")
            print("Now it is", self.ipython_dir)
            sys.exit()
        self.shadow_hist = ShadowHist(self.shadow_db, self.shell)
        
    def save_hist(self):
        """Save input history to a file (via readline library)."""

        try:
            self.shell.readline.write_history_file(self.hist_file)
        except:
            print('Unable to save IPython command history to file: ' + 
                  `self.hist_file`)

    def reload_hist(self):
        """Reload the input history from disk file."""

        try:
            self.shell.readline.clear_history()
            self.shell.readline.read_history_file(self.hist_file)
        except AttributeError:
            pass

    def get_history(self, index=None, raw=False, output=True):
        """Get the history list.

        Get the input and output history.

        Parameters
        ----------
        index : n or (n1, n2) or None
            If n, then the last entries. If a tuple, then all in
            range(n1, n2). If None, then all entries. Raises IndexError if
            the format of index is incorrect.
        raw : bool
            If True, return the raw input.
        output : bool
            If True, then return the output as well.

        Returns
        -------
        If output is True, then return a dict of tuples, keyed by the prompt
        numbers and with values of (input, output). If output is False, then
        a dict, keyed by the prompt number with the values of input. Raises
        IndexError if no history is found.
        """
        if raw:
            input_hist = self.input_hist_raw
        else:
            input_hist = self.input_hist
        if output:
            output_hist = self.output_hist
        n = len(input_hist)
        if index is None:
            start=0; stop=n
        elif isinstance(index, int):
            start=n-index; stop=n
        elif isinstance(index, tuple) and len(index) == 2:
            start=index[0]; stop=index[1]
        else:
            raise IndexError('Not a valid index for the input history: %r'
                             % index)
        hist = {}
        for i in range(start, stop):
            if output:
                hist[i] = (input_hist[i], output_hist.get(i))
            else:
                hist[i] = input_hist[i]
        if not hist:
            raise IndexError('No history for range of indices: %r' % index)
        return hist

    def store_inputs(self, source, source_raw=None):
        """Store source and raw input in history and create input cache
        variables _i*.
        
        Parameters
        ----------
        source : str
          Python input.

        source_raw : str, optional
          If given, this is the raw input without any IPython transformations
          applied to it.  If not given, ``source`` is used.
        """
        if source_raw is None:
            source_raw = source
        self.input_hist.append(source)
        self.input_hist_raw.append(source_raw)
        self.shadow_hist.add(source)

        # update the auto _i variables
        self._iii = self._ii
        self._ii = self._i
        self._i = self._i00
        self._i00 = source_raw

        # hackish access to user namespace to create _i1,_i2... dynamically
        new_i = '_i%s' % self.shell.execution_count
        to_main = {'_i': self._i,
                   '_ii': self._ii,
                   '_iii': self._iii,
                   new_i : self._i00 }
        self.shell.user_ns.update(to_main)

    def sync_inputs(self):
        """Ensure raw and translated histories have same length."""
        if len(self.input_hist) != len (self.input_hist_raw):
            self.input_hist_raw = InputList(self.input_hist)

    def reset(self):
        """Clear all histories managed by this object."""
        self.input_hist[:] = []
        self.input_hist_raw[:] = []
        self.output_hist.clear()
        # The directory history can't be completely empty
        self.dir_hist[:] = [os.getcwd()]
Exemple #4
0
 def sync_inputs(self):
     """Ensure raw and translated histories have same length."""
     if len(self.input_hist) != len (self.input_hist_raw):
         self.input_hist_raw = InputList(self.input_hist)
class TerminalInteractiveShell(InteractiveShell):

    autoedit_syntax = CBool(False, config=True)
    banner = Str('')
    banner1 = Str(default_banner, config=True)
    banner2 = Str('', config=True)
    confirm_exit = CBool(True, config=True)
    # This display_banner only controls whether or not self.show_banner()
    # is called when mainloop/interact are called.  The default is False
    # because for the terminal based application, the banner behavior
    # is controlled by Global.display_banner, which IPythonApp looks at
    # to determine if *it* should call show_banner() by hand or not.
    display_banner = CBool(False) # This isn't configurable!
    embedded = CBool(False)
    embedded_active = CBool(False)
    editor = Str(get_default_editor(), config=True)
    pager = Str('less', config=True)

    screen_length = Int(0, config=True)
    term_title = CBool(False, config=True)

    def __init__(self, config=None, ipython_dir=None, user_ns=None,
                 user_global_ns=None, custom_exceptions=((),None),
                 usage=None, banner1=None, banner2=None,
                 display_banner=None):

        super(TerminalInteractiveShell, self).__init__(
            config=config, ipython_dir=ipython_dir, user_ns=user_ns,
            user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
        )
        self.init_term_title()
        self.init_usage(usage)
        self.init_banner(banner1, banner2, display_banner)

    #-------------------------------------------------------------------------
    # Things related to the terminal
    #-------------------------------------------------------------------------

    @property
    def usable_screen_length(self):
        if self.screen_length == 0:
            return 0
        else:
            num_lines_bot = self.separate_in.count('\n')+1
            return self.screen_length - num_lines_bot

    def init_term_title(self):
        # Enable or disable the terminal title.
        if self.term_title:
            toggle_set_term_title(True)
            set_term_title('IPython: ' + abbrev_cwd())
        else:
            toggle_set_term_title(False)

    #-------------------------------------------------------------------------
    # Things related to aliases
    #-------------------------------------------------------------------------

    def init_alias(self):
        # The parent class defines aliases that can be safely used with any
        # frontend.
        super(TerminalInteractiveShell, self).init_alias()

        # Now define aliases that only make sense on the terminal, because they
        # need direct access to the console in a way that we can't emulate in
        # GUI or web frontend
        if os.name == 'posix':
            aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
                       ('man', 'man')]
        elif os.name == 'nt':
            aliases = [('cls', 'cls')]


        for name, cmd in aliases:
            self.alias_manager.define_alias(name, cmd)

    #-------------------------------------------------------------------------
    # Things related to the banner and usage
    #-------------------------------------------------------------------------

    def _banner1_changed(self):
        self.compute_banner()

    def _banner2_changed(self):
        self.compute_banner()

    def _term_title_changed(self, name, new_value):
        self.init_term_title()

    def init_banner(self, banner1, banner2, display_banner):
        if banner1 is not None:
            self.banner1 = banner1
        if banner2 is not None:
            self.banner2 = banner2
        if display_banner is not None:
            self.display_banner = display_banner
        self.compute_banner()

    def show_banner(self, banner=None):
        if banner is None:
            banner = self.banner
        self.write(banner)

    def compute_banner(self):
        self.banner = self.banner1
        if self.profile:
            self.banner += '\nIPython profile: %s\n' % self.profile
        if self.banner2:
            self.banner += '\n' + self.banner2

    def init_usage(self, usage=None):
        if usage is None:
            self.usage = interactive_usage
        else:
            self.usage = usage

    #-------------------------------------------------------------------------
    # Mainloop and code execution logic
    #-------------------------------------------------------------------------

    def mainloop(self, display_banner=None):
        """Start the mainloop.

        If an optional banner argument is given, it will override the
        internally created default banner.
        """
        
        with nested(self.builtin_trap, self.display_trap):

            # if you run stuff with -c <cmd>, raw hist is not updated
            # ensure that it's in sync
            if len(self.input_hist) != len (self.input_hist_raw):
                self.input_hist_raw = InputList(self.input_hist)

            while 1:
                try:
                    self.interact(display_banner=display_banner)
                    #self.interact_with_readline()                
                    # XXX for testing of a readline-decoupled repl loop, call
                    # interact_with_readline above
                    break
                except KeyboardInterrupt:
                    # this should not be necessary, but KeyboardInterrupt
                    # handling seems rather unpredictable...
                    self.write("\nKeyboardInterrupt in interact()\n")

    def interact(self, display_banner=None):
        """Closely emulate the interactive Python console."""

        # batch run -> do not interact        
        if self.exit_now:
            return

        if display_banner is None:
            display_banner = self.display_banner
        if display_banner:
            self.show_banner()

        more = 0
        
        # Mark activity in the builtins
        __builtin__.__dict__['__IPYTHON__active'] += 1
        
        if self.has_readline:
            self.readline_startup_hook(self.pre_readline)
        # exit_now is set by a call to %Exit or %Quit, through the
        # ask_exit callback.
        
        while not self.exit_now:
            self.hooks.pre_prompt_hook()
            if more:
                try:
                    prompt = self.hooks.generate_prompt(True)
                except:
                    self.showtraceback()
                if self.autoindent:
                    self.rl_do_indent = True
                    
            else:
                try:
                    prompt = self.hooks.generate_prompt(False)
                except:
                    self.showtraceback()
            try:
                line = self.raw_input(prompt, more)
                if self.exit_now:
                    # quick exit on sys.std[in|out] close
                    break
                if self.autoindent:
                    self.rl_do_indent = False
                    
            except KeyboardInterrupt:
                #double-guard against keyboardinterrupts during kbdint handling
                try:
                    self.write('\nKeyboardInterrupt\n')
                    self.resetbuffer()
                    # keep cache in sync with the prompt counter:
                    self.displayhook.prompt_count -= 1
    
                    if self.autoindent:
                        self.indent_current_nsp = 0
                    more = 0
                except KeyboardInterrupt:
                    pass
            except EOFError:
                if self.autoindent:
                    self.rl_do_indent = False
                    if self.has_readline:
                        self.readline_startup_hook(None)
                self.write('\n')
                self.exit()
            except bdb.BdbQuit:
                warn('The Python debugger has exited with a BdbQuit exception.\n'
                     'Because of how pdb handles the stack, it is impossible\n'
                     'for IPython to properly format this particular exception.\n'
                     'IPython will resume normal operation.')
            except:
                # exceptions here are VERY RARE, but they can be triggered
                # asynchronously by signal handlers, for example.
                self.showtraceback()
            else:
                more = self.push_line(line)
                if (self.SyntaxTB.last_syntax_error and
                    self.autoedit_syntax):
                    self.edit_syntax_error()

        # We are off again...
        __builtin__.__dict__['__IPYTHON__active'] -= 1

        # Turn off the exit flag, so the mainloop can be restarted if desired
        self.exit_now = False

    def raw_input(self,prompt='',continue_prompt=False):
        """Write a prompt and read a line.

        The returned line does not include the trailing newline.
        When the user enters the EOF key sequence, EOFError is raised.

        Optional inputs:

          - prompt(''): a string to be printed to prompt the user.

          - continue_prompt(False): whether this line is the first one or a
          continuation in a sequence of inputs.
        """
        # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))

        # Code run by the user may have modified the readline completer state.
        # We must ensure that our completer is back in place.

        if self.has_readline:
            self.set_readline_completer()
        
        try:
            line = raw_input_original(prompt).decode(self.stdin_encoding)
        except ValueError:
            warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
                 " or sys.stdout.close()!\nExiting IPython!")
            self.ask_exit()
            return ""

        # Try to be reasonably smart about not re-indenting pasted input more
        # than necessary.  We do this by trimming out the auto-indent initial
        # spaces, if the user's actual input started itself with whitespace.
        #debugx('self.buffer[-1]')

        if self.autoindent:
            if num_ini_spaces(line) > self.indent_current_nsp:
                line = line[self.indent_current_nsp:]
                self.indent_current_nsp = 0
            
        # store the unfiltered input before the user has any chance to modify
        # it.
        if line.strip():
            if continue_prompt:
                self.input_hist_raw[-1] += '%s\n' % line
                if self.has_readline and self.readline_use:
                    try:
                        histlen = self.readline.get_current_history_length()
                        if histlen > 1:
                            newhist = self.input_hist_raw[-1].rstrip()
                            self.readline.remove_history_item(histlen-1)
                            self.readline.replace_history_item(histlen-2,
                                            newhist.encode(self.stdin_encoding))
                    except AttributeError:
                        pass # re{move,place}_history_item are new in 2.4.                
            else:
                self.input_hist_raw.append('%s\n' % line)                
            # only entries starting at first column go to shadow history
            if line.lstrip() == line:
                self.shadowhist.add(line.strip())
        elif not continue_prompt:
            self.input_hist_raw.append('\n')
        try:
            lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
        except:
            # blanket except, in case a user-defined prefilter crashes, so it
            # can't take all of ipython with it.
            self.showtraceback()
            return ''
        else:
            return lineout

    # TODO: The following three methods are an early attempt to refactor
    # the main code execution logic. We don't use them, but they may be
    # helpful when we refactor the code execution logic further.
    # def interact_prompt(self):
    #     """ Print the prompt (in read-eval-print loop) 
    # 
    #     Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not 
    #     used in standard IPython flow.
    #     """
    #     if self.more:
    #         try:
    #             prompt = self.hooks.generate_prompt(True)
    #         except:
    #             self.showtraceback()
    #         if self.autoindent:
    #             self.rl_do_indent = True
    # 
    #     else:
    #         try:
    #             prompt = self.hooks.generate_prompt(False)
    #         except:
    #             self.showtraceback()
    #     self.write(prompt)
    # 
    # def interact_handle_input(self,line):
    #     """ Handle the input line (in read-eval-print loop)
    #     
    #     Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not 
    #     used in standard IPython flow.        
    #     """
    #     if line.lstrip() == line:
    #         self.shadowhist.add(line.strip())
    #     lineout = self.prefilter_manager.prefilter_lines(line,self.more)
    # 
    #     if line.strip():
    #         if self.more:
    #             self.input_hist_raw[-1] += '%s\n' % line
    #         else:
    #             self.input_hist_raw.append('%s\n' % line)                
    # 
    #     
    #     self.more = self.push_line(lineout)
    #     if (self.SyntaxTB.last_syntax_error and
    #         self.autoedit_syntax):
    #         self.edit_syntax_error()
    # 
    # def interact_with_readline(self):
    #     """ Demo of using interact_handle_input, interact_prompt
    #     
    #     This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
    #     it should work like this.
    #     """ 
    #     self.readline_startup_hook(self.pre_readline)
    #     while not self.exit_now:
    #         self.interact_prompt()
    #         if self.more:
    #             self.rl_do_indent = True
    #         else:
    #             self.rl_do_indent = False
    #         line = raw_input_original().decode(self.stdin_encoding)
    #         self.interact_handle_input(line)

    #-------------------------------------------------------------------------
    # Methods to support auto-editing of SyntaxErrors.
    #-------------------------------------------------------------------------

    def edit_syntax_error(self):
        """The bottom half of the syntax error handler called in the main loop.

        Loop until syntax error is fixed or user cancels.
        """

        while self.SyntaxTB.last_syntax_error:
            # copy and clear last_syntax_error
            err = self.SyntaxTB.clear_err_state()
            if not self._should_recompile(err):
                return
            try:
                # may set last_syntax_error again if a SyntaxError is raised
                self.safe_execfile(err.filename,self.user_ns)
            except:
                self.showtraceback()
            else:
                try:
                    f = file(err.filename)
                    try:
                        # This should be inside a display_trap block and I 
                        # think it is.
                        sys.displayhook(f.read())
                    finally:
                        f.close()
                except:
                    self.showtraceback()

    def _should_recompile(self,e):
        """Utility routine for edit_syntax_error"""

        if e.filename in ('<ipython console>','<input>','<string>',
                          '<console>','<BackgroundJob compilation>',
                          None):
                              
            return False
        try:
            if (self.autoedit_syntax and 
                not self.ask_yes_no('Return to editor to correct syntax error? '
                              '[Y/n] ','y')):
                return False
        except EOFError:
            return False

        def int0(x):
            try:
                return int(x)
            except TypeError:
                return 0
        # always pass integer line and offset values to editor hook
        try:
            self.hooks.fix_error_editor(e.filename,
                int0(e.lineno),int0(e.offset),e.msg)
        except TryNext:
            warn('Could not open editor')
            return False
        return True

    #-------------------------------------------------------------------------
    # Things related to GUI support and pylab
    #-------------------------------------------------------------------------

    def enable_pylab(self, gui=None):
        """Activate pylab support at runtime.

        This turns on support for matplotlib, preloads into the interactive
        namespace all of numpy and pylab, and configures IPython to correcdtly
        interact with the GUI event loop.  The GUI backend to be used can be
        optionally selected with the optional :param:`gui` argument.

        Parameters
        ----------
        gui : optional, string

          If given, dictates the choice of matplotlib GUI backend to use
          (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
          'gtk'), otherwise we use the default chosen by matplotlib (as
          dictated by the matplotlib build-time options plus the user's
          matplotlibrc configuration file).
        """
        # We want to prevent the loading of pylab to pollute the user's
        # namespace as shown by the %who* magics, so we execute the activation
        # code in an empty namespace, and we update *both* user_ns and
        # user_ns_hidden with this information.
        ns = {}
        gui = pylab_activate(ns, gui)
        self.user_ns.update(ns)
        self.user_ns_hidden.update(ns)
        # Now we must activate the gui pylab wants to use, and fix %run to take
        # plot updates into account
        enable_gui(gui)
        self.magic_run = self._pylab_magic_run

    #-------------------------------------------------------------------------
    # Things related to exiting
    #-------------------------------------------------------------------------

    def ask_exit(self):
        """ Ask the shell to exit. Can be overiden and used as a callback. """
        self.exit_now = True

    def exit(self):
        """Handle interactive exit.

        This method calls the ask_exit callback."""
        if self.confirm_exit:
            if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
                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)