elisp: Quitting

 
 20.11 Quitting
 ==============
 
 Typing ‘C-g’ while a Lisp function is running causes Emacs to “quit”
 whatever it is doing.  This means that control returns to the innermost
 active command loop.
 
    Typing ‘C-g’ while the command loop is waiting for keyboard input
 does not cause a quit; it acts as an ordinary input character.  In the
 simplest case, you cannot tell the difference, because ‘C-g’ normally
 runs the command ‘keyboard-quit’, whose effect is to quit.  However,
 when ‘C-g’ follows a prefix key, they combine to form an undefined key.
 The effect is to cancel the prefix key as well as any prefix argument.
 
    In the minibuffer, ‘C-g’ has a different definition: it aborts out of
 the minibuffer.  This means, in effect, that it exits the minibuffer and
 then quits.  (Simply quitting would return to the command loop _within_
 the minibuffer.)  The reason why ‘C-g’ does not quit directly when the
 command reader is reading input is so that its meaning can be redefined
 in the minibuffer in this way.  ‘C-g’ following a prefix key is not
 redefined in the minibuffer, and it has its normal effect of canceling
 the prefix key and prefix argument.  This too would not be possible if
 ‘C-g’ always quit directly.
 
    When ‘C-g’ does directly quit, it does so by setting the variable
 ‘quit-flag’ to ‘t’.  Emacs checks this variable at appropriate times and
 quits if it is not ‘nil’.  Setting ‘quit-flag’ non-‘nil’ in any way thus
 causes a quit.
 
    At the level of C code, quitting cannot happen just anywhere; only at
 the special places that check ‘quit-flag’.  The reason for this is that
 quitting at other places might leave an inconsistency in Emacs’s
 internal state.  Because quitting is delayed until a safe place,
 quitting cannot make Emacs crash.
 
    Certain functions such as ‘read-key-sequence’ or ‘read-quoted-char’
 prevent quitting entirely even though they wait for input.  Instead of
 quitting, ‘C-g’ serves as the requested input.  In the case of
 ‘read-key-sequence’, this serves to bring about the special behavior of
 ‘C-g’ in the command loop.  In the case of ‘read-quoted-char’, this is
 so that ‘C-q’ can be used to quote a ‘C-g’.
 
    You can prevent quitting for a portion of a Lisp function by binding
 the variable ‘inhibit-quit’ to a non-‘nil’ value.  Then, although ‘C-g’
 still sets ‘quit-flag’ to ‘t’ as usual, the usual result of this—a
 quit—is prevented.  Eventually, ‘inhibit-quit’ will become ‘nil’ again,
 such as when its binding is unwound at the end of a ‘let’ form.  At that
 time, if ‘quit-flag’ is still non-‘nil’, the requested quit happens
 immediately.  This behavior is ideal when you wish to make sure that
 quitting does not happen within a critical section of the program.
 
    In some functions (such as ‘read-quoted-char’), ‘C-g’ is handled in a
 special way that does not involve quitting.  This is done by reading the
 input with ‘inhibit-quit’ bound to ‘t’, and setting ‘quit-flag’ to ‘nil’
 before ‘inhibit-quit’ becomes ‘nil’ again.  This excerpt from the
 definition of ‘read-quoted-char’ shows how this is done; it also shows
 that normal quitting is permitted after the first character of input.
 
      (defun read-quoted-char (&optional prompt)
        "...DOCUMENTATION..."
        (let ((message-log-max nil) done (first t) (code 0) char)
          (while (not done)
            (let ((inhibit-quit first)
                  ...)
              (and prompt (message "%s-" prompt))
              (setq char (read-event))
              (if inhibit-quit (setq quit-flag nil)))
            ...set the variable ‘code’...)
          code))
 
  -- Variable: quit-flag
      If this variable is non-‘nil’, then Emacs quits immediately, unless
      ‘inhibit-quit’ is non-‘nil’.  Typing ‘C-g’ ordinarily sets
      ‘quit-flag’ non-‘nil’, regardless of ‘inhibit-quit’.
 
  -- Variable: inhibit-quit
      This variable determines whether Emacs should quit when ‘quit-flag’
      is set to a value other than ‘nil’.  If ‘inhibit-quit’ is
      non-‘nil’, then ‘quit-flag’ has no special effect.
 
  -- Macro: with-local-quit body...
      This macro executes BODY forms in sequence, but allows quitting, at
      least locally, within BODY even if ‘inhibit-quit’ was non-‘nil’
      outside this construct.  It returns the value of the last form in
      BODY, unless exited by quitting, in which case it returns ‘nil’.
 
      If ‘inhibit-quit’ is ‘nil’ on entry to ‘with-local-quit’, it only
      executes the BODY, and setting ‘quit-flag’ causes a normal quit.
      However, if ‘inhibit-quit’ is non-‘nil’ so that ordinary quitting
      is delayed, a non-‘nil’ ‘quit-flag’ triggers a special kind of
      local quit.  This ends the execution of BODY and exits the
      ‘with-local-quit’ body with ‘quit-flag’ still non-‘nil’, so that
      another (ordinary) quit will happen as soon as that is allowed.  If
      ‘quit-flag’ is already non-‘nil’ at the beginning of BODY, the
      local quit happens immediately and the body doesn’t execute at all.
 
      This macro is mainly useful in functions that can be called from
      timers, process filters, process sentinels, ‘pre-command-hook’,
      ‘post-command-hook’, and other places where ‘inhibit-quit’ is
      normally bound to ‘t’.
 
  -- Command: keyboard-quit
      This function signals the ‘quit’ condition with ‘(signal 'quit
      nil)’.  This is the same thing that quitting does.  (See ‘signal’
      in SeeErrors.)
 
    You can specify a character other than ‘C-g’ to use for quitting.
 See the function ‘set-input-mode’ in SeeInput Modes.