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.
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);
/* The following loop starts the execution of possibly multiple
iterations of the macro.
The state variables that control the execution of a single
iteration are Vexecuting_kbd_macro and executing_kbd_macro_index,
which can be accessed from lisp. The purpose of the variables
executing_kbd_macro and executing_kbd_macro_iteration is to
remember the most recently started macro and its iteration count.
This makes it possible to produce a meaningful message in case of
errors during the execution of the macro.
In a single iteration, individual characters from the macro are
read by read_char, which takes care of incrementing
executing_kbd_macro_index after each character.
The end of a macro iteration is handled as follows:
- read_key_sequence asks at_end_of_macro_p whether the end of the
iteration has been reached. If so, it returns the magic value 0
to command_loop_1.
- command_loop_1 returns Qnil to command_loop_2.
- command_loop_2 returns Qnil to this function
(but only the returning is relevant, not the actual value).
Macro executions form a stack. After the last iteration of the
execution of one stack item, or in case of an error during one of
the iterations, pop_kbd_macro (invoked via unwind-protect) will
restore Vexecuting_kbd_macro and executing_kbd_macro_index, and
run 'kbd-macro-termination-hook'.
If read_char happens to be called at the end of a macro iteration,
but before read_key_sequence could handle the end (e.g., when lisp
code calls 'read-event', 'read-char', or 'read-char-exclusive'),
read_char will simply continue reading other available input
(Bug#68272). Vexecuting_kbd_macro and executing_kbd_macro remain
untouched until the end of the iteration is handled.
This is similar (in observable behavior) to a possibly simpler
implementation of keyboard macros in which this function pushed all
characters of the macro into the incoming event queue and returned
immediately. Maybe this is the implementation that we ideally
would like to have, but switching to it will require a larger code
change. */
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);
}