Function: execute-kbd-macro

execute-kbd-macro is a function defined in macros.c.

Signature

(execute-kbd-macro MACRO &optional COUNT LOOPFUNC)

Documentation

Execute MACRO as a sequence of events.

If MACRO is a string or vector, then the events in it are executed exactly as if they had been input by the user.

If MACRO is a symbol, its function definition is used. If that is another symbol, this process repeats. Eventually the result should be a string or vector. If the result is not a symbol, string, or vector, an error is signaled.

COUNT is a repeat count, or nil for once, or 0 for infinite loop.

Optional third arg LOOPFUNC may be a function that is called prior to each iteration of the macro. Iteration stops if LOOPFUNC returns nil.

The buffer shown in the currently selected window will be made the current buffer before the macro is executed.

View in manual

Probably introduced at or before Emacs version 21.1.

Source Code

// Defined in /usr/src/emacs/src/macros.c
{
  Lisp_Object final;
  Lisp_Object tem;
  specpdl_ref pdlcount = SPECPDL_INDEX ();
  EMACS_INT repeat = 1;
  EMACS_INT success_count = 0;

  executing_kbd_macro_iterations = 0;

  if (!NILP (count))
    {
      count = Fprefix_numeric_value (count);
      repeat = XFIXNUM (count);
    }

  final = indirect_function (macro);
  if (!STRINGP (final) && !VECTORP (final))
    error ("Keyboard macros must be strings or vectors");

  tem = Fcons (Vexecuting_kbd_macro,
	       Fcons (make_int (executing_kbd_macro_index),
		      Vreal_this_command));
  record_unwind_protect (pop_kbd_macro, tem);

  do
    {
      Vexecuting_kbd_macro = final;
      executing_kbd_macro = final;
      executing_kbd_macro_index = 0;

      kset_prefix_arg (current_kboard, Qnil);

      if (!NILP (loopfunc))
	{
	  Lisp_Object cont;
	  cont = call0 (loopfunc);
	  if (NILP (cont))
	    break;
	}

      command_loop_2 (list1 (Qminibuffer_quit));

      executing_kbd_macro_iterations = ++success_count;

      maybe_quit ();
    }
  while (--repeat
	 && (STRINGP (Vexecuting_kbd_macro) || VECTORP (Vexecuting_kbd_macro)));

  executing_kbd_macro = Qnil;

  Vreal_this_command = Vexecuting_kbd_macro;

  return unbind_to (pdlcount, Qnil);
}