macros.c 9.6 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Keyboard macros.
Jim Blandy's avatar
Jim Blandy committed
2
   Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
3 4 5 6 7

This file is part of GNU Emacs.

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

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
along with GNU Emacs; see the file COPYING.  If not, write to
18 19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */
Jim Blandy's avatar
Jim Blandy committed
20 21


22
#include <config.h>
Jim Blandy's avatar
Jim Blandy committed
23 24 25 26 27
#include "lisp.h"
#include "macros.h"
#include "commands.h"
#include "buffer.h"
#include "window.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
28
#include "keyboard.h"
Jim Blandy's avatar
Jim Blandy committed
29 30 31

Lisp_Object Qexecute_kbd_macro;

32 33
/* Kbd macro currently being executed (a string or vector).  */

Jim Blandy's avatar
Jim Blandy committed
34
Lisp_Object Vexecuting_macro;
35 36 37

/* Index of next character to fetch from that macro.  */

Jim Blandy's avatar
Jim Blandy committed
38 39
int executing_macro_index;

40 41 42 43 44 45 46 47 48 49 50 51 52 53
/* 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.  */

int executing_macro_iterations;

/* 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.  */

Lisp_Object executing_macro;

Jim Blandy's avatar
Jim Blandy committed
54 55 56 57 58 59 60 61 62 63 64 65
Lisp_Object Fexecute_kbd_macro ();

DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P",
  "Record subsequent keyboard input, defining a keyboard macro.\n\
The commands are recorded even as they are executed.\n\
Use \\[end-kbd-macro] to finish recording and make the macro available.\n\
Use \\[name-last-kbd-macro] to give it a permanent name.\n\
Non-nil arg (prefix arg) means append to last macro defined;\n\
 This begins by re-executing that macro as if you typed it again.")
  (append)
     Lisp_Object append;
{
Karl Heuer's avatar
Karl Heuer committed
66
  if (!NILP (current_kboard->defining_kbd_macro))
Jim Blandy's avatar
Jim Blandy committed
67 68
    error ("Already defining kbd macro");

Karl Heuer's avatar
Karl Heuer committed
69
  if (!current_kboard->kbd_macro_buffer)
70
    {
Karl Heuer's avatar
Karl Heuer committed
71 72
      current_kboard->kbd_macro_bufsize = 30;
      current_kboard->kbd_macro_buffer
73
	= (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object));
74
    }
Jim Blandy's avatar
Jim Blandy committed
75
  update_mode_lines++;
Jim Blandy's avatar
Jim Blandy committed
76
  if (NILP (append))
Jim Blandy's avatar
Jim Blandy committed
77
    {
78 79 80 81
      if (current_kboard->kbd_macro_bufsize > 200)
	{
	  current_kboard->kbd_macro_bufsize = 30;
	  current_kboard->kbd_macro_buffer
82 83
	    = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
				       30 * sizeof (Lisp_Object));
84
	}
Karl Heuer's avatar
Karl Heuer committed
85 86
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
      current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
87
      message ("Defining kbd macro...");
Jim Blandy's avatar
Jim Blandy committed
88 89 90
    }
  else
    {
91
      message ("Appending to kbd macro...");
Karl Heuer's avatar
Karl Heuer committed
92 93
      current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
      Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro,
94
			  make_number (1));
Jim Blandy's avatar
Jim Blandy committed
95
    }
Karl Heuer's avatar
Karl Heuer committed
96
  current_kboard->defining_kbd_macro = Qt;
Jim Blandy's avatar
Jim Blandy committed
97 98 99 100 101 102 103 104 105 106 107 108 109 110
  
  return Qnil;
}

DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p",
  "Finish defining a keyboard macro.\n\
The definition was started by \\[start-kbd-macro].\n\
The macro is now available for use via \\[call-last-kbd-macro],\n\
or it can be given a name with \\[name-last-kbd-macro] and then invoked\n\
under that name.\n\
\n\
With numeric arg, repeat macro now that many times,\n\
counting the definition just completed as the first repetition.\n\
An argument of zero means repeat until error.")
111 112
  (repeat)
     Lisp_Object repeat;
Jim Blandy's avatar
Jim Blandy committed
113
{
Karl Heuer's avatar
Karl Heuer committed
114 115
  if (NILP (current_kboard->defining_kbd_macro))
    error ("Not defining kbd macro.");
Jim Blandy's avatar
Jim Blandy committed
116

117 118
  if (NILP (repeat))
    XSETFASTINT (repeat, 1);
Jim Blandy's avatar
Jim Blandy committed
119
  else
120
    CHECK_NUMBER (repeat, 0);
Jim Blandy's avatar
Jim Blandy committed
121

Karl Heuer's avatar
Karl Heuer committed
122
  if (!NILP (current_kboard->defining_kbd_macro))
Jim Blandy's avatar
Jim Blandy committed
123
    {
Karl Heuer's avatar
Karl Heuer committed
124
      current_kboard->defining_kbd_macro = Qnil;
Jim Blandy's avatar
Jim Blandy committed
125
      update_mode_lines++;
Karl Heuer's avatar
Karl Heuer committed
126 127 128 129
      current_kboard->Vlast_kbd_macro
	= make_event_array ((current_kboard->kbd_macro_end
			     - current_kboard->kbd_macro_buffer),
			    current_kboard->kbd_macro_buffer);
130
      message ("Keyboard macro defined");
Jim Blandy's avatar
Jim Blandy committed
131 132
    }

133 134
  if (XFASTINT (repeat) == 0)
    Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat);
Jim Blandy's avatar
Jim Blandy committed
135 136
  else
    {
137 138 139
      XSETINT (repeat, XINT (repeat)-1);
      if (XINT (repeat) > 0)
	Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat);
Jim Blandy's avatar
Jim Blandy committed
140 141 142 143 144 145 146 147 148
    }
  return Qnil;
}

/* Store character c into kbd macro being defined */

store_kbd_macro_char (c)
     Lisp_Object c;
{
Karl Heuer's avatar
Karl Heuer committed
149
  if (!NILP (current_kboard->defining_kbd_macro))
Jim Blandy's avatar
Jim Blandy committed
150
    {
Karl Heuer's avatar
Karl Heuer committed
151 152 153
      if ((current_kboard->kbd_macro_ptr
	   - current_kboard->kbd_macro_buffer)
	  == current_kboard->kbd_macro_bufsize)
Jim Blandy's avatar
Jim Blandy committed
154
	{
155
	  register Lisp_Object *new;
Karl Heuer's avatar
Karl Heuer committed
156 157 158
	  current_kboard->kbd_macro_bufsize *= 2;
	  new = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
					 (current_kboard->kbd_macro_bufsize
159
					  * sizeof (Lisp_Object)));
Karl Heuer's avatar
Karl Heuer committed
160 161 162 163 164
	  current_kboard->kbd_macro_ptr
	    += new - current_kboard->kbd_macro_buffer;
	  current_kboard->kbd_macro_end
	    += new - current_kboard->kbd_macro_buffer;
	  current_kboard->kbd_macro_buffer = new;
Jim Blandy's avatar
Jim Blandy committed
165
	}
Karl Heuer's avatar
Karl Heuer committed
166
      *current_kboard->kbd_macro_ptr++ = c;
Jim Blandy's avatar
Jim Blandy committed
167 168 169 170 171 172 173 174
    }
}

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

finalize_kbd_macro_chars ()
{
Karl Heuer's avatar
Karl Heuer committed
175
  current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
Jim Blandy's avatar
Jim Blandy committed
176
}
177 178 179 180 181 182 183 184

DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events,
       Scancel_kbd_macro_events, 0, 0, 0,
  "Cancel the events added to a keyboard macro for this command.")
  ()
{
  current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
}
185 186 187 188 189 190 191 192 193 194

DEFUN ("store-kbd-macro-event", Fstore_kbd_macro_event,
       Sstore_kbd_macro_event, 1, 1, 0,
  "Store EVENT into the keyboard macro being defined.")
  (event)
     Lisp_Object event;
{
  store_kbd_macro_char (event);
  return Qnil;
}
Jim Blandy's avatar
Jim Blandy committed
195 196 197 198 199 200 201 202 203 204 205 206

DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
  0, 1, "p",
  "Call the last keyboard macro that you defined with \\[start-kbd-macro].\n\
\n\
A prefix argument serves as a repeat count.  Zero means repeat until error.\n\
\n\
To make a macro permanent so you can call it even after\n\
defining others, use \\[name-last-kbd-macro].")
  (prefix)
     Lisp_Object prefix;
{
207 208 209 210
  /* Don't interfere with recognition of the previous command
     from before this macro started.  */
  this_command = current_kboard->Vlast_command;

Karl Heuer's avatar
Karl Heuer committed
211
  if (! NILP (current_kboard->defining_kbd_macro))
Jim Blandy's avatar
Jim Blandy committed
212
    error ("Can't execute anonymous macro while defining one");
Karl Heuer's avatar
Karl Heuer committed
213
  else if (NILP (current_kboard->Vlast_kbd_macro))
Jim Blandy's avatar
Jim Blandy committed
214 215
    error ("No kbd macro has been defined");
  else
Karl Heuer's avatar
Karl Heuer committed
216
    Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, prefix);
217 218 219 220 221 222

  /* 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.  */
  this_command = current_kboard->Vlast_command;

Jim Blandy's avatar
Jim Blandy committed
223 224 225 226 227
  return Qnil;
}

/* Restore Vexecuting_macro and executing_macro_index - called when
   the unwind-protect in Fexecute_kbd_macro gets invoked.  */
228

Jim Blandy's avatar
Jim Blandy committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
static Lisp_Object
pop_kbd_macro (info)
     Lisp_Object info;
{
  Lisp_Object tem;
  Vexecuting_macro = Fcar (info);
  tem = Fcdr (info);
  executing_macro_index = XINT (tem);
  return Qnil;
}

DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0,
  "Execute MACRO as string of editor command characters.\n\
If MACRO is a symbol, its function definition is used.\n\
COUNT is a repeat count, or nil for once, or 0 for infinite loop.")
244 245
  (macro, count)
     Lisp_Object macro, count;
Jim Blandy's avatar
Jim Blandy committed
246 247 248
{
  Lisp_Object final;
  Lisp_Object tem;
249
  int pdlcount = specpdl_ptr - specpdl;
Jim Blandy's avatar
Jim Blandy committed
250 251
  int repeat = 1;
  struct gcpro gcpro1;
252
  int success_count = 0;
Jim Blandy's avatar
Jim Blandy committed
253

254 255 256 257 258
  if (!NILP (count))
    {
      count = Fprefix_numeric_value (count);
      repeat = XINT (count);
    }
Jim Blandy's avatar
Jim Blandy committed
259

Jim Blandy's avatar
Jim Blandy committed
260
  final = indirect_function (macro);
261
  if (!STRINGP (final) && !VECTORP (final))
Jim Blandy's avatar
Jim Blandy committed
262 263
    error ("Keyboard macros must be strings or vectors.");

264
  XSETFASTINT (tem, executing_macro_index);
Jim Blandy's avatar
Jim Blandy committed
265 266 267 268 269 270 271
  tem = Fcons (Vexecuting_macro, tem);
  record_unwind_protect (pop_kbd_macro, tem);

  GCPRO1 (final);
  do
    {
      Vexecuting_macro = final;
272
      executing_macro = final;
Jim Blandy's avatar
Jim Blandy committed
273 274
      executing_macro_index = 0;

275
      current_kboard->Vprefix_arg = Qnil;
Jim Blandy's avatar
Jim Blandy committed
276
      command_loop_1 ();
277

278 279
      executing_macro_iterations = ++success_count;

280
      QUIT;
Jim Blandy's avatar
Jim Blandy committed
281
    }
282 283
  while (--repeat
	 && (STRINGP (Vexecuting_macro) || VECTORP (Vexecuting_macro)));
Jim Blandy's avatar
Jim Blandy committed
284

285 286
  executing_macro = Qnil;

Jim Blandy's avatar
Jim Blandy committed
287
  UNGCPRO;
288
  return unbind_to (pdlcount, Qnil);
Jim Blandy's avatar
Jim Blandy committed
289 290 291 292 293
}

init_macros ()
{
  Vexecuting_macro = Qnil;
294
  executing_macro = Qnil;
Jim Blandy's avatar
Jim Blandy committed
295 296 297 298 299 300 301 302 303 304 305
}

syms_of_macros ()
{
  Qexecute_kbd_macro = intern ("execute-kbd-macro");
  staticpro (&Qexecute_kbd_macro);

  defsubr (&Sstart_kbd_macro);
  defsubr (&Send_kbd_macro);
  defsubr (&Scall_last_kbd_macro);
  defsubr (&Sexecute_kbd_macro);
306
  defsubr (&Scancel_kbd_macro_events);
307
  defsubr (&Sstore_kbd_macro_event);
Jim Blandy's avatar
Jim Blandy committed
308

Karl Heuer's avatar
Karl Heuer committed
309
  DEFVAR_KBOARD ("defining-kbd-macro", defining_kbd_macro,
Jim Blandy's avatar
Jim Blandy committed
310 311 312
    "Non-nil while a keyboard macro is being defined.  Don't set this!");

  DEFVAR_LISP ("executing-macro", &Vexecuting_macro,
313
    "Currently executing keyboard macro (string or vector); nil if none executing.");
Jim Blandy's avatar
Jim Blandy committed
314 315

  DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro,
316
    "Currently executing keyboard macro (string or vector); nil if none executing.");
Jim Blandy's avatar
Jim Blandy committed
317

Karl Heuer's avatar
Karl Heuer committed
318
  DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
319
    "Last kbd macro defined, as a string or vector; nil if none defined.");
Jim Blandy's avatar
Jim Blandy committed
320 321 322 323 324 325 326 327
}

keys_of_macros ()
{
  initial_define_key (control_x_map, ('e'), "call-last-kbd-macro");
  initial_define_key (control_x_map, ('('), "start-kbd-macro");
  initial_define_key (control_x_map, (')'), "end-kbd-macro");
}