Function: start-kbd-macro

start-kbd-macro is an interactive function defined in macros.c.

Signature

(start-kbd-macro APPEND &optional NO-EXEC)

Documentation

Record subsequent keyboard input, defining a keyboard macro.

The commands are recorded even as they are executed. Use M-x end-kbd-macro (end-kbd-macro) to finish recording and make the macro available. Use M-x name-last-kbd-macro (name-last-kbd-macro) to give it a permanent name. Non-nil arg (prefix arg) means append to last macro defined; this begins by re-executing that macro as if you typed it again. If optional second arg, NO-EXEC, is non-nil, do not re-execute last macro before appending to it.

Key Bindings

Aliases

defining-kbd-macro(var)/defining-kbd-macro(fun)

Source Code

// Defined in /usr/src/emacs/src/macros.c
{
  if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
    error ("Already defining kbd macro");

  if (!current_kboard->kbd_macro_buffer)
    {
      current_kboard->kbd_macro_buffer = xmalloc (30 * word_size);
      current_kboard->kbd_macro_bufsize = 30;
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
    }
  update_mode_lines = 19;
  if (NILP (append))
    {
      if (current_kboard->kbd_macro_bufsize > 200)
	{
	  current_kboard->kbd_macro_buffer
	    = xrealloc (current_kboard->kbd_macro_buffer,
			30 * word_size);
	  current_kboard->kbd_macro_bufsize = 30;
	}
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
      message1 ("Defining kbd macro...");
    }
  else
    {
      int incr = 30;
      ptrdiff_t i, len;
      bool cvt;

      /* Check the type of last-kbd-macro in case Lisp code changed it.  */
      len = CHECK_VECTOR_OR_STRING (KVAR (current_kboard, Vlast_kbd_macro));

      /* Copy last-kbd-macro into the buffer, in case the Lisp code
	 has put another macro there.  */
      if (current_kboard->kbd_macro_bufsize - incr < len)
	current_kboard->kbd_macro_buffer =
	  xpalloc (current_kboard->kbd_macro_buffer,
		   &current_kboard->kbd_macro_bufsize,
		   len - current_kboard->kbd_macro_bufsize + incr, -1,
		   sizeof *current_kboard->kbd_macro_buffer);

      /* Must convert meta modifier when copying string to vector.  */
      cvt = STRINGP (KVAR (current_kboard, Vlast_kbd_macro));
      for (i = 0; i < len; i++)
	{
	  Lisp_Object c;
	  c = Faref (KVAR (current_kboard, Vlast_kbd_macro), make_fixnum (i));
	  if (cvt && FIXNATP (c) && (XFIXNAT (c) & 0x80))
	    XSETFASTINT (c, CHAR_META | (XFIXNAT (c) & ~0x80));
	  current_kboard->kbd_macro_buffer[i] = c;
	}

      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer + len;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;

      /* Re-execute the macro we are appending to,
	 for consistency of behavior.  */
      if (NILP (no_exec))
	Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
			    make_fixnum (1), Qnil);

      message1 ("Appending to kbd macro...");
    }
  kset_defining_kbd_macro (current_kboard, Qt);

  return Qnil;
}