Function: interactive-form

interactive-form is a function defined in data.c.

Signature

(interactive-form CMD)

Documentation

Return the interactive form of CMD or nil if none.

If CMD is not a command, the return value is nil. Value, if non-nil, is a list (interactive SPEC).

View in manual

Probably introduced at or before Emacs version 21.1.

Source Code

// Defined in /usr/src/emacs/src/data.c
{
  Lisp_Object fun = indirect_function (cmd); /* Check cycles.  */
  bool genfun = false;

  if (NILP (fun))
    return Qnil;

  /* Use an `interactive-form' property if present, analogous to the
     function-documentation property.  */
  fun = cmd;
  while (SYMBOLP (fun))
    {
      Lisp_Object tmp = Fget (fun, Qinteractive_form);
      if (!NILP (tmp))
	return tmp;
      else
	fun = Fsymbol_function (fun);
    }

  if (SUBRP (fun))
    {
      if (SUBR_NATIVE_COMPILEDP (fun) && !NILP (XSUBR (fun)->intspec.native))
	return XSUBR (fun)->intspec.native;

      const char *spec = XSUBR (fun)->intspec.string;
      if (spec)
	return list2 (Qinteractive,
		      (*spec != '(') ? build_string (spec) :
		      Fcar (Fread_from_string (build_string (spec), Qnil, Qnil)));
    }
  else if (COMPILEDP (fun))
    {
      if (PVSIZE (fun) > COMPILED_INTERACTIVE)
	{
	  Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE);
	  /* The vector form is the new form, where the first
	     element is the interactive spec, and the second is the
	     command modes. */
	  return list2 (Qinteractive, VECTORP (form) ? AREF (form, 0) : form);
	}
      else if (PVSIZE (fun) > COMPILED_DOC_STRING)
        {
          Lisp_Object doc = AREF (fun, COMPILED_DOC_STRING);
          /* An invalid "docstring" is a sign that we have an OClosure.  */
          genfun = !(NILP (doc) || VALID_DOCSTRING_P (doc));
        }
    }
#ifdef HAVE_MODULES
  else if (MODULE_FUNCTIONP (fun))
    {
      Lisp_Object form
        = module_function_interactive_form (XMODULE_FUNCTION (fun));
      if (! NILP (form))
        return form;
    }
#endif
  else if (AUTOLOADP (fun))
    return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil));
  else if (CONSP (fun))
    {
      Lisp_Object funcar = XCAR (fun);
      if (EQ (funcar, Qclosure)
	  || EQ (funcar, Qlambda))
	{
	  Lisp_Object form = Fcdr (XCDR (fun));
	  if (EQ (funcar, Qclosure))
	    form = Fcdr (form);
	  Lisp_Object spec = Fassq (Qinteractive, form);
	  if (NILP (spec) && VALID_DOCSTRING_P (CAR_SAFE (form)))
            /* A "docstring" is a sign that we may have an OClosure.  */
	    genfun = true;
	  else if (NILP (Fcdr (Fcdr (spec))))
	    return spec;
	  else
	    return list2 (Qinteractive, Fcar (Fcdr (spec)));
	}
    }
  if (genfun
      /* Avoid burping during bootstrap.  */
      && !NILP (Fsymbol_function (Qoclosure_interactive_form)))
    return call1 (Qoclosure_interactive_form, fun);
  else
    return Qnil;
}