macros.c 12 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Keyboard macros.
2

Paul Eggert's avatar
Paul Eggert committed
3
Copyright (C) 1985-1986, 1993, 2000-2019 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
4 5 6

This file is part of GNU Emacs.

7
GNU Emacs is free software: you can redistribute it and/or modify
Jim Blandy's avatar
Jim Blandy committed
8
it under the terms of the GNU General Public License as published by
9 10
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
Jim Blandy's avatar
Jim Blandy committed
11 12 13 14 15 16 17

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
18
along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
Jim Blandy's avatar
Jim Blandy committed
19 20


21
#include <config.h>
22

Jim Blandy's avatar
Jim Blandy committed
23 24 25
#include "lisp.h"
#include "macros.h"
#include "window.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
26
#include "keyboard.h"
Jim Blandy's avatar
Jim Blandy committed
27

28 29 30 31 32
/* Number of successful iterations so far
   for innermost keyboard macro.
   This is not bound at each level,
   so after an error, it describes the innermost interrupted macro.  */

33
EMACS_INT executing_kbd_macro_iterations;
34 35 36 37 38 39

/* This is the macro that was executing.
   This is not bound at each level,
   so after an error, it describes the innermost interrupted macro.
   We use it only as a kind of flag, so no need to protect it.  */

40
Lisp_Object executing_kbd_macro;
41

42
DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 2, "P",
43 44 45 46 47
       doc: /* Record subsequent keyboard input, defining a keyboard macro.
The commands are recorded even as they are executed.
Use \\[end-kbd-macro] to finish recording and make the macro available.
Use \\[name-last-kbd-macro] to give it a permanent name.
Non-nil arg (prefix arg) means append to last macro defined;
48
this begins by re-executing that macro as if you typed it again.
49
If optional second arg, NO-EXEC, is non-nil, do not re-execute last
50
macro before appending to it.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
51
  (Lisp_Object append, Lisp_Object no_exec)
Jim Blandy's avatar
Jim Blandy committed
52
{
53
  if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
Jim Blandy's avatar
Jim Blandy committed
54 55
    error ("Already defining kbd macro");

Karl Heuer's avatar
Karl Heuer committed
56
  if (!current_kboard->kbd_macro_buffer)
57
    {
58
      current_kboard->kbd_macro_buffer = xmalloc (30 * word_size);
59
      current_kboard->kbd_macro_bufsize = 30;
Andreas Schwab's avatar
Andreas Schwab committed
60 61
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
62
    }
63
  update_mode_lines = 19;
Jim Blandy's avatar
Jim Blandy committed
64
  if (NILP (append))
Jim Blandy's avatar
Jim Blandy committed
65
    {
66 67 68
      if (current_kboard->kbd_macro_bufsize > 200)
	{
	  current_kboard->kbd_macro_buffer
69
	    = xrealloc (current_kboard->kbd_macro_buffer,
70
			30 * word_size);
71
	  current_kboard->kbd_macro_bufsize = 30;
72
	}
Karl Heuer's avatar
Karl Heuer committed
73 74
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
75
      message1 ("Defining kbd macro...");
Jim Blandy's avatar
Jim Blandy committed
76 77 78
    }
  else
    {
79
      int incr = 30;
80
      ptrdiff_t i, len;
81
      bool cvt;
82 83

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

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

      /* Must convert meta modifier when copying string to vector.  */
96
      cvt = STRINGP (KVAR (current_kboard, Vlast_kbd_macro));
97
      for (i = 0; i < len; i++)
98 99
	{
	  Lisp_Object c;
100
	  c = Faref (KVAR (current_kboard, Vlast_kbd_macro), make_number (i));
101 102
	  if (cvt && NATNUMP (c) && (XFASTINT (c) & 0x80))
	    XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
103 104
	  current_kboard->kbd_macro_buffer[i] = c;
	}
105 106 107 108 109 110

      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.  */
111
      if (NILP (no_exec))
112
	Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
113
			    make_number (1), Qnil);
114

115
      message1 ("Appending to kbd macro...");
Jim Blandy's avatar
Jim Blandy committed
116
    }
Paul Eggert's avatar
Paul Eggert committed
117
  kset_defining_kbd_macro (current_kboard, Qt);
118

Jim Blandy's avatar
Jim Blandy committed
119 120 121
  return Qnil;
}

Kim F. Storm's avatar
Kim F. Storm committed
122 123 124
/* Finish defining the current keyboard macro.  */

void
125
end_kbd_macro (void)
Kim F. Storm's avatar
Kim F. Storm committed
126
{
Paul Eggert's avatar
Paul Eggert committed
127
  kset_defining_kbd_macro (current_kboard, Qnil);
128
  update_mode_lines = 20;
Paul Eggert's avatar
Paul Eggert committed
129 130 131 132 133
  kset_last_kbd_macro
    (current_kboard,
     make_event_array ((current_kboard->kbd_macro_end
			- current_kboard->kbd_macro_buffer),
		       current_kboard->kbd_macro_buffer));
Kim F. Storm's avatar
Kim F. Storm committed
134 135
}

136
DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 2, "p",
137 138 139 140 141 142 143 144
       doc: /* Finish defining a keyboard macro.
The definition was started by \\[start-kbd-macro].
The macro is now available for use via \\[call-last-kbd-macro],
or it can be given a name with \\[name-last-kbd-macro] and then invoked
under that name.

With numeric arg, repeat macro now that many times,
counting the definition just completed as the first repetition.
145 146
An argument of zero means repeat until error.

147
In Lisp, optional second arg LOOPFUNC may be a function that is called prior to
148
each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
149
  (Lisp_Object repeat, Lisp_Object loopfunc)
Jim Blandy's avatar
Jim Blandy committed
150
{
151
  if (NILP (KVAR (current_kboard, defining_kbd_macro)))
152
    error ("Not defining kbd macro");
Jim Blandy's avatar
Jim Blandy committed
153

154 155
  if (NILP (repeat))
    XSETFASTINT (repeat, 1);
Jim Blandy's avatar
Jim Blandy committed
156
  else
157
    CHECK_NUMBER (repeat);
Jim Blandy's avatar
Jim Blandy committed
158

159
  if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
Jim Blandy's avatar
Jim Blandy committed
160
    {
Kim F. Storm's avatar
Kim F. Storm committed
161
      end_kbd_macro ();
162
      message1 ("Keyboard macro defined");
Jim Blandy's avatar
Jim Blandy committed
163 164
    }

165
  if (XFASTINT (repeat) == 0)
166
    Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc);
167
  else if (XINT (repeat) > 1)
Jim Blandy's avatar
Jim Blandy committed
168
    {
169
      XSETINT (repeat, XINT (repeat) - 1);
170 171
      Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
			  repeat, loopfunc);
Jim Blandy's avatar
Jim Blandy committed
172 173 174 175
    }
  return Qnil;
}

176
/* Store character c into kbd macro being defined.  */
Jim Blandy's avatar
Jim Blandy committed
177

178
void
179
store_kbd_macro_char (Lisp_Object c)
Jim Blandy's avatar
Jim Blandy committed
180
{
181 182
  struct kboard *kb = current_kboard;

183
  if (!NILP (KVAR (kb, defining_kbd_macro)))
Jim Blandy's avatar
Jim Blandy committed
184
    {
185
      if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
Jim Blandy's avatar
Jim Blandy committed
186
	{
187 188 189 190 191
	  ptrdiff_t ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
	  ptrdiff_t end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
	  kb->kbd_macro_buffer = xpalloc (kb->kbd_macro_buffer,
					  &kb->kbd_macro_bufsize,
					  1, -1, sizeof *kb->kbd_macro_buffer);
192 193
	  kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
	  kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
Jim Blandy's avatar
Jim Blandy committed
194
	}
195

196
      *kb->kbd_macro_ptr++ = c;
Jim Blandy's avatar
Jim Blandy committed
197 198 199 200 201 202
    }
}

/* Declare that all chars stored so far in the kbd macro being defined
 really belong to it.  This is done in between editor commands.  */

203
void
204
finalize_kbd_macro_chars (void)
Jim Blandy's avatar
Jim Blandy committed
205
{
Karl Heuer's avatar
Karl Heuer committed
206
  current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
Jim Blandy's avatar
Jim Blandy committed
207
}
208

Paul Eggert's avatar
Paul Eggert committed
209
DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events,
210
       Scancel_kbd_macro_events, 0, 0, 0,
211
       doc: /* Cancel the events added to a keyboard macro for this command.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
212
  (void)
213 214
{
  current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
215
  return Qnil;
216
}
217 218 219

DEFUN ("store-kbd-macro-event", Fstore_kbd_macro_event,
       Sstore_kbd_macro_event, 1, 1, 0,
220
       doc: /* Store EVENT into the keyboard macro being defined.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
221
  (Lisp_Object event)
222 223 224 225
{
  store_kbd_macro_char (event);
  return Qnil;
}
Jim Blandy's avatar
Jim Blandy committed
226 227

DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
228
       0, 2, "p",
229 230 231 232 233
       doc: /* Call the last keyboard macro that you defined with \\[start-kbd-macro].

A prefix argument serves as a repeat count.  Zero means repeat until error.

To make a macro permanent so you can call it even after
234
defining others, use \\[name-last-kbd-macro].
235

236
In Lisp, optional second arg LOOPFUNC may be a function that is called prior to
237
each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
238
  (Lisp_Object prefix, Lisp_Object loopfunc)
Jim Blandy's avatar
Jim Blandy committed
239
{
240 241
  /* Don't interfere with recognition of the previous command
     from before this macro started.  */
242
  Vthis_command = KVAR (current_kboard, Vlast_command);
243
  /* C-x z after the macro should repeat the macro.  */
244
  Vreal_this_command = KVAR (current_kboard, Vlast_kbd_macro);
245

246
  if (! NILP (KVAR (current_kboard, defining_kbd_macro)))
Jim Blandy's avatar
Jim Blandy committed
247
    error ("Can't execute anonymous macro while defining one");
248
  else if (NILP (KVAR (current_kboard, Vlast_kbd_macro)))
Jim Blandy's avatar
Jim Blandy committed
249 250
    error ("No kbd macro has been defined");
  else
251
    Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), prefix, loopfunc);
252 253 254 255

  /* command_loop_1 sets this to nil before it returns;
     get back the last command within the macro
     so that it can be last, again, after we return.  */
256
  Vthis_command = KVAR (current_kboard, Vlast_command);
257

Jim Blandy's avatar
Jim Blandy committed
258 259 260
  return Qnil;
}

261 262
/* Restore Vexecuting_kbd_macro and executing_kbd_macro_index.
   Called when the unwind-protect in Fexecute_kbd_macro gets invoked.  */
263

264
static void
265
pop_kbd_macro (Lisp_Object info)
Jim Blandy's avatar
Jim Blandy committed
266 267
{
  Lisp_Object tem;
268
  Vexecuting_kbd_macro = XCAR (info);
269
  tem = XCDR (info);
270
  executing_kbd_macro_index = XINT (XCAR (tem));
271
  Vreal_this_command = XCDR (tem);
272
  run_hook (Qkbd_macro_termination_hook);
Jim Blandy's avatar
Jim Blandy committed
273 274
}

Paul Eggert's avatar
Paul Eggert committed
275
DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0,
276
       doc: /* Execute MACRO as string of editor command characters.
277 278
MACRO can also be a vector of keyboard events.  If MACRO is a symbol,
its function definition is used.
279
COUNT is a repeat count, or nil for once, or 0 for infinite loop.
280

281
Optional third arg LOOPFUNC may be a function that is called prior to
282
each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
283
  (Lisp_Object macro, Lisp_Object count, Lisp_Object loopfunc)
Jim Blandy's avatar
Jim Blandy committed
284 285 286
{
  Lisp_Object final;
  Lisp_Object tem;
287
  ptrdiff_t pdlcount = SPECPDL_INDEX ();
288 289
  EMACS_INT repeat = 1;
  EMACS_INT success_count = 0;
Jim Blandy's avatar
Jim Blandy committed
290

291
  executing_kbd_macro_iterations = 0;
292

293 294 295 296 297
  if (!NILP (count))
    {
      count = Fprefix_numeric_value (count);
      repeat = XINT (count);
    }
Jim Blandy's avatar
Jim Blandy committed
298

Jim Blandy's avatar
Jim Blandy committed
299
  final = indirect_function (macro);
300
  if (!STRINGP (final) && !VECTORP (final))
301
    error ("Keyboard macros must be strings or vectors");
Jim Blandy's avatar
Jim Blandy committed
302

303
  tem = Fcons (Vexecuting_kbd_macro,
304
	       Fcons (make_number (executing_kbd_macro_index),
305
		      Vreal_this_command));
Jim Blandy's avatar
Jim Blandy committed
306 307 308 309
  record_unwind_protect (pop_kbd_macro, tem);

  do
    {
310
      Vexecuting_kbd_macro = final;
311 312
      executing_kbd_macro = final;
      executing_kbd_macro_index = 0;
Jim Blandy's avatar
Jim Blandy committed
313

Paul Eggert's avatar
Paul Eggert committed
314
      kset_prefix_arg (current_kboard, Qnil);
315 316 317 318 319 320 321 322 323

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

Jim Blandy's avatar
Jim Blandy committed
324
      command_loop_1 ();
325

326
      executing_kbd_macro_iterations = ++success_count;
327

Paul Eggert's avatar
Paul Eggert committed
328
      maybe_quit ();
Jim Blandy's avatar
Jim Blandy committed
329
    }
330
  while (--repeat
331
	 && (STRINGP (Vexecuting_kbd_macro) || VECTORP (Vexecuting_kbd_macro)));
Jim Blandy's avatar
Jim Blandy committed
332

333
  executing_kbd_macro = Qnil;
334

335
  Vreal_this_command = Vexecuting_kbd_macro;
336

337
  return unbind_to (pdlcount, Qnil);
Jim Blandy's avatar
Jim Blandy committed
338 339
}

340
void
341
init_macros (void)
Jim Blandy's avatar
Jim Blandy committed
342
{
343
  Vexecuting_kbd_macro = Qnil;
344
  executing_kbd_macro = Qnil;
Jim Blandy's avatar
Jim Blandy committed
345 346
}

347
void
348
syms_of_macros (void)
Jim Blandy's avatar
Jim Blandy committed
349
{
350 351 352 353
  DEFVAR_LISP ("kbd-macro-termination-hook", Vkbd_macro_termination_hook,
               doc: /* Normal hook run whenever a keyboard macro terminates.
This is run whether the macro ends normally or prematurely due to an error.  */);
  Vkbd_macro_termination_hook = Qnil;
354
  DEFSYM (Qkbd_macro_termination_hook, "kbd-macro-termination-hook");
Jim Blandy's avatar
Jim Blandy committed
355 356 357 358 359

  defsubr (&Sstart_kbd_macro);
  defsubr (&Send_kbd_macro);
  defsubr (&Scall_last_kbd_macro);
  defsubr (&Sexecute_kbd_macro);
360
  defsubr (&Scancel_kbd_macro_events);
361
  defsubr (&Sstore_kbd_macro_event);
Jim Blandy's avatar
Jim Blandy committed
362

Karl Heuer's avatar
Karl Heuer committed
363
  DEFVAR_KBOARD ("defining-kbd-macro", defining_kbd_macro,
364 365 366
		 doc: /* Non-nil while a keyboard macro is being defined.  Don't set this!
The value is the symbol `append' while appending to the definition of
an existing macro.  */);
Jim Blandy's avatar
Jim Blandy committed
367

368
  DEFVAR_LISP ("executing-kbd-macro", Vexecuting_kbd_macro,
369 370
	       doc: /* Currently executing keyboard macro (string or vector).
This is nil when not executing a keyboard macro.  */);
Jim Blandy's avatar
Jim Blandy committed
371

372
  DEFVAR_INT ("executing-kbd-macro-index", executing_kbd_macro_index,
373 374
	      doc: /* Index in currently executing keyboard macro; undefined if none executing.  */);

Karl Heuer's avatar
Karl Heuer committed
375
  DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
376
		 doc: /* Last kbd macro defined, as a string or vector; nil if none defined.  */);
Jim Blandy's avatar
Jim Blandy committed
377
}