elisp: Recursive Editing

 
 20.13 Recursive Editing
 =======================
 
 The Emacs command loop is entered automatically when Emacs starts up.
 This top-level invocation of the command loop never exits; it keeps
 running as long as Emacs does.  Lisp programs can also invoke the
 command loop.  Since this makes more than one activation of the command
 loop, we call it “recursive editing”.  A recursive editing level has the
 effect of suspending whatever command invoked it and permitting the user
 to do arbitrary editing before resuming that command.
 
    The commands available during recursive editing are the same ones
 available in the top-level editing loop and defined in the keymaps.
 Only a few special commands exit the recursive editing level; the others
 return to the recursive editing level when they finish.  (The special
 commands for exiting are always available, but they do nothing when
 recursive editing is not in progress.)
 
    All command loops, including recursive ones, set up all-purpose error
 handlers so that an error in a command run from the command loop will
 not exit the loop.
 
    Minibuffer input is a special kind of recursive editing.  It has a
 few special wrinkles, such as enabling display of the minibuffer and the
 minibuffer window, but fewer than you might suppose.  Certain keys
 behave differently in the minibuffer, but that is only because of the
 minibuffer’s local map; if you switch windows, you get the usual Emacs
 commands.
 
    To invoke a recursive editing level, call the function
 ‘recursive-edit’.  This function contains the command loop; it also
 contains a call to ‘catch’ with tag ‘exit’, which makes it possible to
 exit the recursive editing level by throwing to ‘exit’ (SeeCatch and
 Throw).  If you throw a value other than ‘t’, then ‘recursive-edit’
 returns normally to the function that called it.  The command ‘C-M-c’
 (‘exit-recursive-edit’) does this.  Throwing a ‘t’ value causes
 ‘recursive-edit’ to quit, so that control returns to the command loop
 one level up.  This is called “aborting”, and is done by ‘C-]’
 (‘abort-recursive-edit’).
 
    Most applications should not use recursive editing, except as part of
 using the minibuffer.  Usually it is more convenient for the user if you
 change the major mode of the current buffer temporarily to a special
 major mode, which should have a command to go back to the previous mode.
 (The ‘e’ command in Rmail uses this technique.)  Or, if you wish to give
 the user different text to edit recursively, create and select a new
 buffer in a special mode.  In this mode, define a command to complete
 the processing and go back to the previous buffer.  (The ‘m’ command in
 Rmail does this.)
 
    Recursive edits are useful in debugging.  You can insert a call to
 ‘debug’ into a function definition as a sort of breakpoint, so that you
 can look around when the function gets there.  ‘debug’ invokes a
 recursive edit but also provides the other features of the debugger.
 
    Recursive editing levels are also used when you type ‘C-r’ in
 ‘query-replace’ or use ‘C-x q’ (‘kbd-macro-query’).
 
  -- Command: recursive-edit
      This function invokes the editor command loop.  It is called
      automatically by the initialization of Emacs, to let the user begin
      editing.  When called from a Lisp program, it enters a recursive
      editing level.
 
      If the current buffer is not the same as the selected window’s
      buffer, ‘recursive-edit’ saves and restores the current buffer.
      Otherwise, if you switch buffers, the buffer you switched to is
      current after ‘recursive-edit’ returns.
 
      In the following example, the function ‘simple-rec’ first advances
      point one word, then enters a recursive edit, printing out a
      message in the echo area.  The user can then do any editing
      desired, and then type ‘C-M-c’ to exit and continue executing
      ‘simple-rec’.
 
           (defun simple-rec ()
             (forward-word 1)
             (message "Recursive edit in progress")
             (recursive-edit)
             (forward-word 1))
                ⇒ simple-rec
           (simple-rec)
                ⇒ nil
 
  -- Command: exit-recursive-edit
      This function exits from the innermost recursive edit (including
      minibuffer input).  Its definition is effectively ‘(throw 'exit
      nil)’.
 
  -- Command: abort-recursive-edit
      This function aborts the command that requested the innermost
      recursive edit (including minibuffer input), by signaling ‘quit’
      after exiting the recursive edit.  Its definition is effectively
      ‘(throw 'exit t)’.  SeeQuitting.
 
  -- Command: top-level
      This function exits all recursive editing levels; it does not
      return a value, as it jumps completely out of any computation
      directly back to the main command loop.
 
  -- Function: recursion-depth
      This function returns the current depth of recursive edits.  When
      no recursive edit is active, it returns 0.