(Coding Conventions): Node renamed from Style Tips.
[bpt/emacs.git] / src / macros.c
CommitLineData
5a7f5d07 1/* Keyboard macros.
c6c5df7f 2 Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc.
5a7f5d07
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
502ddf23 8the Free Software Foundation; either version 2, or (at your option)
5a7f5d07
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
5a7f5d07
JB
20
21
18160b98 22#include <config.h>
5a7f5d07
JB
23#include "lisp.h"
24#include "macros.h"
25#include "commands.h"
26#include "buffer.h"
27#include "window.h"
077d751f 28#include "keyboard.h"
5a7f5d07
JB
29
30Lisp_Object Qexecute_kbd_macro;
31
d4087e06
RS
32/* Kbd macro currently being executed (a string or vector). */
33
5a7f5d07 34Lisp_Object Vexecuting_macro;
d4087e06
RS
35
36/* Index of next character to fetch from that macro. */
37
5a7f5d07
JB
38int executing_macro_index;
39
d4087e06
RS
40/* Number of successful iterations so far
41 for innermost keyboard macro.
42 This is not bound at each level,
43 so after an error, it describes the innermost interrupted macro. */
44
45int executing_macro_iterations;
46
47/* This is the macro that was executing.
48 This is not bound at each level,
49 so after an error, it describes the innermost interrupted macro.
50 We use it only as a kind of flag, so no need to protect it. */
51
52Lisp_Object executing_macro;
53
5a7f5d07
JB
54Lisp_Object Fexecute_kbd_macro ();
55\f
56DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P",
57 "Record subsequent keyboard input, defining a keyboard macro.\n\
58The commands are recorded even as they are executed.\n\
59Use \\[end-kbd-macro] to finish recording and make the macro available.\n\
60Use \\[name-last-kbd-macro] to give it a permanent name.\n\
61Non-nil arg (prefix arg) means append to last macro defined;\n\
62 This begins by re-executing that macro as if you typed it again.")
63 (append)
64 Lisp_Object append;
65{
cd8b5aa3 66 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07
JB
67 error ("Already defining kbd macro");
68
cd8b5aa3 69 if (!current_kboard->kbd_macro_buffer)
8b97da83 70 {
cd8b5aa3
KH
71 current_kboard->kbd_macro_bufsize = 30;
72 current_kboard->kbd_macro_buffer
9e7c370a 73 = (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object));
8b97da83 74 }
5a7f5d07 75 update_mode_lines++;
265a9e55 76 if (NILP (append))
5a7f5d07 77 {
9e7c370a
KH
78 if (current_kboard->kbd_macro_bufsize > 200)
79 {
80 current_kboard->kbd_macro_bufsize = 30;
81 current_kboard->kbd_macro_buffer
96a60349
KH
82 = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
83 30 * sizeof (Lisp_Object));
9e7c370a 84 }
cd8b5aa3
KH
85 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
86 current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
9e7c370a 87 message ("Defining kbd macro...");
5a7f5d07
JB
88 }
89 else
90 {
9e7c370a 91 message ("Appending to kbd macro...");
cd8b5aa3
KH
92 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
93 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro,
9e1ffae2 94 make_number (1));
5a7f5d07 95 }
cd8b5aa3 96 current_kboard->defining_kbd_macro = Qt;
5a7f5d07
JB
97
98 return Qnil;
99}
100
101DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p",
102 "Finish defining a keyboard macro.\n\
103The definition was started by \\[start-kbd-macro].\n\
104The macro is now available for use via \\[call-last-kbd-macro],\n\
105or it can be given a name with \\[name-last-kbd-macro] and then invoked\n\
106under that name.\n\
107\n\
108With numeric arg, repeat macro now that many times,\n\
109counting the definition just completed as the first repetition.\n\
110An argument of zero means repeat until error.")
86a3ca5e
EN
111 (repeat)
112 Lisp_Object repeat;
5a7f5d07 113{
cd8b5aa3
KH
114 if (NILP (current_kboard->defining_kbd_macro))
115 error ("Not defining kbd macro.");
5a7f5d07 116
86a3ca5e
EN
117 if (NILP (repeat))
118 XSETFASTINT (repeat, 1);
5a7f5d07 119 else
86a3ca5e 120 CHECK_NUMBER (repeat, 0);
5a7f5d07 121
cd8b5aa3 122 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07 123 {
cd8b5aa3 124 current_kboard->defining_kbd_macro = Qnil;
5a7f5d07 125 update_mode_lines++;
cd8b5aa3
KH
126 current_kboard->Vlast_kbd_macro
127 = make_event_array ((current_kboard->kbd_macro_end
128 - current_kboard->kbd_macro_buffer),
129 current_kboard->kbd_macro_buffer);
9e7c370a 130 message ("Keyboard macro defined");
5a7f5d07
JB
131 }
132
86a3ca5e
EN
133 if (XFASTINT (repeat) == 0)
134 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat);
5a7f5d07
JB
135 else
136 {
86a3ca5e
EN
137 XSETINT (repeat, XINT (repeat)-1);
138 if (XINT (repeat) > 0)
139 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat);
5a7f5d07
JB
140 }
141 return Qnil;
142}
143
144/* Store character c into kbd macro being defined */
145
146store_kbd_macro_char (c)
147 Lisp_Object c;
148{
cd8b5aa3 149 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07 150 {
cd8b5aa3
KH
151 if ((current_kboard->kbd_macro_ptr
152 - current_kboard->kbd_macro_buffer)
153 == current_kboard->kbd_macro_bufsize)
5a7f5d07 154 {
8b97da83 155 register Lisp_Object *new;
cd8b5aa3
KH
156 current_kboard->kbd_macro_bufsize *= 2;
157 new = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
158 (current_kboard->kbd_macro_bufsize
8b97da83 159 * sizeof (Lisp_Object)));
cd8b5aa3
KH
160 current_kboard->kbd_macro_ptr
161 += new - current_kboard->kbd_macro_buffer;
162 current_kboard->kbd_macro_end
163 += new - current_kboard->kbd_macro_buffer;
164 current_kboard->kbd_macro_buffer = new;
5a7f5d07 165 }
cd8b5aa3 166 *current_kboard->kbd_macro_ptr++ = c;
5a7f5d07
JB
167 }
168}
169
170/* Declare that all chars stored so far in the kbd macro being defined
171 really belong to it. This is done in between editor commands. */
172
173finalize_kbd_macro_chars ()
174{
cd8b5aa3 175 current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
5a7f5d07 176}
199afd29
RS
177
178DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events,
179 Scancel_kbd_macro_events, 0, 0, 0,
180 "Cancel the events added to a keyboard macro for this command.")
181 ()
182{
183 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
184}
2d5f65a9
KH
185
186DEFUN ("store-kbd-macro-event", Fstore_kbd_macro_event,
187 Sstore_kbd_macro_event, 1, 1, 0,
188 "Store EVENT into the keyboard macro being defined.")
189 (event)
190 Lisp_Object event;
191{
192 store_kbd_macro_char (event);
193 return Qnil;
194}
5a7f5d07
JB
195\f
196DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
197 0, 1, "p",
198 "Call the last keyboard macro that you defined with \\[start-kbd-macro].\n\
199\n\
200A prefix argument serves as a repeat count. Zero means repeat until error.\n\
201\n\
202To make a macro permanent so you can call it even after\n\
203defining others, use \\[name-last-kbd-macro].")
204 (prefix)
205 Lisp_Object prefix;
206{
4315204e
RS
207 /* Don't interfere with recognition of the previous command
208 from before this macro started. */
209 this_command = current_kboard->Vlast_command;
210
cd8b5aa3 211 if (! NILP (current_kboard->defining_kbd_macro))
5a7f5d07 212 error ("Can't execute anonymous macro while defining one");
cd8b5aa3 213 else if (NILP (current_kboard->Vlast_kbd_macro))
5a7f5d07
JB
214 error ("No kbd macro has been defined");
215 else
cd8b5aa3 216 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, prefix);
4315204e
RS
217
218 /* command_loop_1 sets this to nil before it returns;
219 get back the last command within the macro
220 so that it can be last, again, after we return. */
221 this_command = current_kboard->Vlast_command;
222
5a7f5d07
JB
223 return Qnil;
224}
225
226/* Restore Vexecuting_macro and executing_macro_index - called when
227 the unwind-protect in Fexecute_kbd_macro gets invoked. */
d4087e06 228
5a7f5d07
JB
229static Lisp_Object
230pop_kbd_macro (info)
231 Lisp_Object info;
232{
233 Lisp_Object tem;
234 Vexecuting_macro = Fcar (info);
235 tem = Fcdr (info);
236 executing_macro_index = XINT (tem);
237 return Qnil;
238}
239
240DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0,
241 "Execute MACRO as string of editor command characters.\n\
242If MACRO is a symbol, its function definition is used.\n\
243COUNT is a repeat count, or nil for once, or 0 for infinite loop.")
86a3ca5e
EN
244 (macro, count)
245 Lisp_Object macro, count;
5a7f5d07
JB
246{
247 Lisp_Object final;
248 Lisp_Object tem;
52d9c145 249 int pdlcount = specpdl_ptr - specpdl;
5a7f5d07
JB
250 int repeat = 1;
251 struct gcpro gcpro1;
d4087e06 252 int success_count = 0;
5a7f5d07 253
1c8c5693
EN
254 if (!NILP (count))
255 {
256 count = Fprefix_numeric_value (count);
257 repeat = XINT (count);
258 }
5a7f5d07 259
502ddf23 260 final = indirect_function (macro);
65346ae6 261 if (!STRINGP (final) && !VECTORP (final))
5a7f5d07
JB
262 error ("Keyboard macros must be strings or vectors.");
263
a4773b43 264 XSETFASTINT (tem, executing_macro_index);
5a7f5d07
JB
265 tem = Fcons (Vexecuting_macro, tem);
266 record_unwind_protect (pop_kbd_macro, tem);
267
268 GCPRO1 (final);
269 do
270 {
271 Vexecuting_macro = final;
d4087e06 272 executing_macro = final;
5a7f5d07
JB
273 executing_macro_index = 0;
274
04609ce4 275 current_kboard->Vprefix_arg = Qnil;
5a7f5d07 276 command_loop_1 ();
e86f81cc 277
d4087e06
RS
278 executing_macro_iterations = ++success_count;
279
e86f81cc 280 QUIT;
5a7f5d07 281 }
65346ae6
KH
282 while (--repeat
283 && (STRINGP (Vexecuting_macro) || VECTORP (Vexecuting_macro)));
5a7f5d07 284
d4087e06
RS
285 executing_macro = Qnil;
286
5a7f5d07 287 UNGCPRO;
52d9c145 288 return unbind_to (pdlcount, Qnil);
5a7f5d07
JB
289}
290\f
291init_macros ()
292{
5a7f5d07 293 Vexecuting_macro = Qnil;
1ab778be 294 executing_macro = Qnil;
5a7f5d07
JB
295}
296
297syms_of_macros ()
298{
5a7f5d07
JB
299 Qexecute_kbd_macro = intern ("execute-kbd-macro");
300 staticpro (&Qexecute_kbd_macro);
301
302 defsubr (&Sstart_kbd_macro);
303 defsubr (&Send_kbd_macro);
304 defsubr (&Scall_last_kbd_macro);
305 defsubr (&Sexecute_kbd_macro);
199afd29 306 defsubr (&Scancel_kbd_macro_events);
2d5f65a9 307 defsubr (&Sstore_kbd_macro_event);
5a7f5d07 308
cd8b5aa3 309 DEFVAR_KBOARD ("defining-kbd-macro", defining_kbd_macro,
5a7f5d07
JB
310 "Non-nil while a keyboard macro is being defined. Don't set this!");
311
312 DEFVAR_LISP ("executing-macro", &Vexecuting_macro,
9e1ffae2 313 "Currently executing keyboard macro (string or vector); nil if none executing.");
5a7f5d07
JB
314
315 DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro,
9e1ffae2 316 "Currently executing keyboard macro (string or vector); nil if none executing.");
5a7f5d07 317
cd8b5aa3 318 DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
9e1ffae2 319 "Last kbd macro defined, as a string or vector; nil if none defined.");
5a7f5d07
JB
320}
321
322keys_of_macros ()
323{
324 initial_define_key (control_x_map, ('e'), "call-last-kbd-macro");
325 initial_define_key (control_x_map, ('('), "start-kbd-macro");
326 initial_define_key (control_x_map, (')'), "end-kbd-macro");
327}