elisp: Using Interactive

 
 20.2.1 Using ‘interactive’
 --------------------------
 
 This section describes how to write the ‘interactive’ form that makes a
 Lisp function an interactively-callable command, and how to examine a
 command’s ‘interactive’ form.
 
  -- Special Form: interactive arg-descriptor
      This special form declares that a function is a command, and that
      it may therefore be called interactively (via ‘M-x’ or by entering
      a key sequence bound to it).  The argument ARG-DESCRIPTOR declares
      how to compute the arguments to the command when the command is
      called interactively.
 
      A command may be called from Lisp programs like any other function,
      but then the caller supplies the arguments and ARG-DESCRIPTOR has
      no effect.
 
      The ‘interactive’ form must be located at top-level in the function
      body, or in the function symbol’s ‘interactive-form’ property
      (SeeSymbol Properties).  It has its effect because the command
      loop looks for it before calling the function (SeeInteractive
      Call).  Once the function is called, all its body forms are
      executed; at this time, if the ‘interactive’ form occurs within the
      body, the form simply returns ‘nil’ without even evaluating its
      argument.
 
      By convention, you should put the ‘interactive’ form in the
      function body, as the first top-level form.  If there is an
      ‘interactive’ form in both the ‘interactive-form’ symbol property
      and the function body, the former takes precedence.  The
      ‘interactive-form’ symbol property can be used to add an
      interactive form to an existing function, or change how its
      arguments are processed interactively, without redefining the
      function.
 
    There are three possibilities for the argument ARG-DESCRIPTOR:
 
    • It may be omitted or ‘nil’; then the command is called with no
      arguments.  This leads quickly to an error if the command requires
      one or more arguments.
 
    • It may be a string; its contents are a sequence of elements
      separated by newlines, one for each argument(1).  Each element
      consists of a code character (SeeInteractive Codes) optionally
      followed by a prompt (which some code characters use and some
      ignore).  Here is an example:
 
           (interactive "P\nbFrobnicate buffer: ")
 
      The code letter ‘P’ sets the command’s first argument to the raw
      command prefix (SeePrefix Command Arguments).  ‘bFrobnicate
      buffer: ’ prompts the user with ‘Frobnicate buffer: ’ to enter the
      name of an existing buffer, which becomes the second and final
      argument.
 
      The prompt string can use ‘%’ to include previous argument values
      (starting with the first argument) in the prompt.  This is done
      using ‘format-message’ (SeeFormatting Strings).  For example,
      here is how you could read the name of an existing buffer followed
      by a new name to give to that buffer:
 
           (interactive "bBuffer to rename: \nsRename buffer %s to: ")
 
      If ‘*’ appears at the beginning of the string, then an error is
      signaled if the buffer is read-only.
 
      If ‘@’ appears at the beginning of the string, and if the key
      sequence used to invoke the command includes any mouse events, then
      the window associated with the first of those events is selected
      before the command is run.
 
      If ‘^’ appears at the beginning of the string, and if the command
      was invoked through “shift-translation”, set the mark and activate
      the region temporarily, or extend an already active region, before
      the command is run.  If the command was invoked without
      shift-translation, and the region is temporarily active, deactivate
      the region before the command is run.  Shift-translation is
      controlled on the user level by ‘shift-select-mode’; see See
      (emacs)Shift Selection.
 
      You can use ‘*’, ‘@’, and ‘^’ together; the order does not matter.
      Actual reading of arguments is controlled by the rest of the prompt
      string (starting with the first character that is not ‘*’, ‘@’, or
      ‘^’).
 
    • It may be a Lisp expression that is not a string; then it should be
      a form that is evaluated to get a list of arguments to pass to the
      command.  Usually this form will call various functions to read
      Minibuffers::) or directly from the keyboard (SeeReading
      Input).
 
      Providing point or the mark as an argument value is also common,
      but if you do this _and_ read input (whether using the minibuffer
      or not), be sure to get the integer values of point or the mark
      after reading.  The current buffer may be receiving subprocess
      output; if subprocess output arrives while the command is waiting
      for input, it could relocate point and the mark.
 
      Here’s an example of what _not_ to do:
 
           (interactive
            (list (region-beginning) (region-end)
                  (read-string "Foo: " nil 'my-history)))
 
      Here’s how to avoid the problem, by examining point and the mark
      after reading the keyboard input:
 
           (interactive
            (let ((string (read-string "Foo: " nil 'my-history)))
              (list (region-beginning) (region-end) string)))
 
      *Warning:* the argument values should not include any data types
      that can’t be printed and then read.  Some facilities save
      ‘command-history’ in a file to be read in the subsequent sessions;
      if a command’s arguments contain a data type that prints using
      ‘#<...>’ syntax, those facilities won’t work.
 
      There are, however, a few exceptions: it is ok to use a limited set
      of expressions such as ‘(point)’, ‘(mark)’, ‘(region-beginning)’,
      and ‘(region-end)’, because Emacs recognizes them specially and
      puts the expression (rather than its value) into the command
      history.  To see whether the expression you wrote is one of these
      exceptions, run the command, then examine ‘(car command-history)’.
 
  -- Function: interactive-form function
      This function returns the ‘interactive’ form of FUNCTION.  If
      FUNCTION is an interactively callable function (SeeInteractive
      Call), the value is the command’s ‘interactive’ form
      ‘(interactive SPEC)’, which specifies how to compute its arguments.
      Otherwise, the value is ‘nil’.  If FUNCTION is a symbol, its
      function definition is used.
 
    ---------- Footnotes ----------
 
    (1) Some elements actually supply two arguments.