(Fkeymapp, Fdefine_prefix_command, Faccessible_keymaps,
[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
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
18160b98 21#include <config.h>
5a7f5d07
JB
22#include "lisp.h"
23#include "macros.h"
24#include "commands.h"
25#include "buffer.h"
26#include "window.h"
077d751f 27#include "keyboard.h"
5a7f5d07
JB
28
29Lisp_Object Qexecute_kbd_macro;
30
5a7f5d07
JB
31Lisp_Object Vexecuting_macro;
32int executing_macro_index;
33
34Lisp_Object Fexecute_kbd_macro ();
35\f
36DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P",
37 "Record subsequent keyboard input, defining a keyboard macro.\n\
38The commands are recorded even as they are executed.\n\
39Use \\[end-kbd-macro] to finish recording and make the macro available.\n\
40Use \\[name-last-kbd-macro] to give it a permanent name.\n\
41Non-nil arg (prefix arg) means append to last macro defined;\n\
42 This begins by re-executing that macro as if you typed it again.")
43 (append)
44 Lisp_Object append;
45{
cd8b5aa3 46 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07
JB
47 error ("Already defining kbd macro");
48
cd8b5aa3 49 if (!current_kboard->kbd_macro_buffer)
8b97da83 50 {
cd8b5aa3
KH
51 current_kboard->kbd_macro_bufsize = 30;
52 current_kboard->kbd_macro_buffer
8b97da83
KH
53 = (Lisp_Object *)malloc (30 * sizeof (Lisp_Object));
54 }
5a7f5d07 55 update_mode_lines++;
265a9e55 56 if (NILP (append))
5a7f5d07 57 {
cd8b5aa3
KH
58 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
59 current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
5a7f5d07
JB
60 message("Defining kbd macro...");
61 }
62 else
63 {
64 message("Appending to kbd macro...");
cd8b5aa3
KH
65 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
66 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro,
9e1ffae2 67 make_number (1));
5a7f5d07 68 }
cd8b5aa3 69 current_kboard->defining_kbd_macro = Qt;
5a7f5d07
JB
70
71 return Qnil;
72}
73
74DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p",
75 "Finish defining a keyboard macro.\n\
76The definition was started by \\[start-kbd-macro].\n\
77The macro is now available for use via \\[call-last-kbd-macro],\n\
78or it can be given a name with \\[name-last-kbd-macro] and then invoked\n\
79under that name.\n\
80\n\
81With numeric arg, repeat macro now that many times,\n\
82counting the definition just completed as the first repetition.\n\
83An argument of zero means repeat until error.")
84 (arg)
85 Lisp_Object arg;
86{
cd8b5aa3
KH
87 if (NILP (current_kboard->defining_kbd_macro))
88 error ("Not defining kbd macro.");
5a7f5d07 89
265a9e55 90 if (NILP (arg))
a4773b43 91 XSETFASTINT (arg, 1);
5a7f5d07
JB
92 else
93 CHECK_NUMBER (arg, 0);
94
cd8b5aa3 95 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07 96 {
cd8b5aa3 97 current_kboard->defining_kbd_macro = Qnil;
5a7f5d07 98 update_mode_lines++;
cd8b5aa3
KH
99 current_kboard->Vlast_kbd_macro
100 = make_event_array ((current_kboard->kbd_macro_end
101 - current_kboard->kbd_macro_buffer),
102 current_kboard->kbd_macro_buffer);
5a7f5d07
JB
103 message("Keyboard macro defined");
104 }
105
106 if (XFASTINT (arg) == 0)
cd8b5aa3 107 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, arg);
5a7f5d07
JB
108 else
109 {
e86f81cc
JB
110 XSETINT (arg, XINT (arg)-1);
111 if (XINT (arg) > 0)
cd8b5aa3 112 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, arg);
5a7f5d07
JB
113 }
114 return Qnil;
115}
116
117/* Store character c into kbd macro being defined */
118
119store_kbd_macro_char (c)
120 Lisp_Object c;
121{
cd8b5aa3 122 if (!NILP (current_kboard->defining_kbd_macro))
5a7f5d07 123 {
cd8b5aa3
KH
124 if ((current_kboard->kbd_macro_ptr
125 - current_kboard->kbd_macro_buffer)
126 == current_kboard->kbd_macro_bufsize)
5a7f5d07 127 {
8b97da83 128 register Lisp_Object *new;
cd8b5aa3
KH
129 current_kboard->kbd_macro_bufsize *= 2;
130 new = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
131 (current_kboard->kbd_macro_bufsize
8b97da83 132 * sizeof (Lisp_Object)));
cd8b5aa3
KH
133 current_kboard->kbd_macro_ptr
134 += new - current_kboard->kbd_macro_buffer;
135 current_kboard->kbd_macro_end
136 += new - current_kboard->kbd_macro_buffer;
137 current_kboard->kbd_macro_buffer = new;
5a7f5d07 138 }
cd8b5aa3 139 *current_kboard->kbd_macro_ptr++ = c;
5a7f5d07
JB
140 }
141}
142
143/* Declare that all chars stored so far in the kbd macro being defined
144 really belong to it. This is done in between editor commands. */
145
146finalize_kbd_macro_chars ()
147{
cd8b5aa3 148 current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
5a7f5d07 149}
199afd29
RS
150
151DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events,
152 Scancel_kbd_macro_events, 0, 0, 0,
153 "Cancel the events added to a keyboard macro for this command.")
154 ()
155{
156 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
157}
2d5f65a9
KH
158
159DEFUN ("store-kbd-macro-event", Fstore_kbd_macro_event,
160 Sstore_kbd_macro_event, 1, 1, 0,
161 "Store EVENT into the keyboard macro being defined.")
162 (event)
163 Lisp_Object event;
164{
165 store_kbd_macro_char (event);
166 return Qnil;
167}
5a7f5d07
JB
168\f
169DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
170 0, 1, "p",
171 "Call the last keyboard macro that you defined with \\[start-kbd-macro].\n\
172\n\
173A prefix argument serves as a repeat count. Zero means repeat until error.\n\
174\n\
175To make a macro permanent so you can call it even after\n\
176defining others, use \\[name-last-kbd-macro].")
177 (prefix)
178 Lisp_Object prefix;
179{
cd8b5aa3 180 if (! NILP (current_kboard->defining_kbd_macro))
5a7f5d07 181 error ("Can't execute anonymous macro while defining one");
cd8b5aa3 182 else if (NILP (current_kboard->Vlast_kbd_macro))
5a7f5d07
JB
183 error ("No kbd macro has been defined");
184 else
cd8b5aa3 185 Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, prefix);
5a7f5d07
JB
186 return Qnil;
187}
188
189/* Restore Vexecuting_macro and executing_macro_index - called when
190 the unwind-protect in Fexecute_kbd_macro gets invoked. */
191static Lisp_Object
192pop_kbd_macro (info)
193 Lisp_Object info;
194{
195 Lisp_Object tem;
196 Vexecuting_macro = Fcar (info);
197 tem = Fcdr (info);
198 executing_macro_index = XINT (tem);
199 return Qnil;
200}
201
202DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0,
203 "Execute MACRO as string of editor command characters.\n\
204If MACRO is a symbol, its function definition is used.\n\
205COUNT is a repeat count, or nil for once, or 0 for infinite loop.")
206 (macro, prefixarg)
207 Lisp_Object macro, prefixarg;
208{
209 Lisp_Object final;
210 Lisp_Object tem;
211 int count = specpdl_ptr - specpdl;
212 int repeat = 1;
213 struct gcpro gcpro1;
214
265a9e55 215 if (!NILP (prefixarg))
5a7f5d07
JB
216 prefixarg = Fprefix_numeric_value (prefixarg),
217 repeat = XINT (prefixarg);
218
502ddf23 219 final = indirect_function (macro);
65346ae6 220 if (!STRINGP (final) && !VECTORP (final))
5a7f5d07
JB
221 error ("Keyboard macros must be strings or vectors.");
222
a4773b43 223 XSETFASTINT (tem, executing_macro_index);
5a7f5d07
JB
224 tem = Fcons (Vexecuting_macro, tem);
225 record_unwind_protect (pop_kbd_macro, tem);
226
227 GCPRO1 (final);
228 do
229 {
230 Vexecuting_macro = final;
231 executing_macro_index = 0;
232
04609ce4 233 current_kboard->Vprefix_arg = Qnil;
5a7f5d07 234 command_loop_1 ();
e86f81cc
JB
235
236 QUIT;
5a7f5d07 237 }
65346ae6
KH
238 while (--repeat
239 && (STRINGP (Vexecuting_macro) || VECTORP (Vexecuting_macro)));
5a7f5d07
JB
240
241 UNGCPRO;
242 return unbind_to (count, Qnil);
243}
244\f
245init_macros ()
246{
5a7f5d07
JB
247 Vexecuting_macro = Qnil;
248}
249
250syms_of_macros ()
251{
5a7f5d07
JB
252 Qexecute_kbd_macro = intern ("execute-kbd-macro");
253 staticpro (&Qexecute_kbd_macro);
254
255 defsubr (&Sstart_kbd_macro);
256 defsubr (&Send_kbd_macro);
257 defsubr (&Scall_last_kbd_macro);
258 defsubr (&Sexecute_kbd_macro);
199afd29 259 defsubr (&Scancel_kbd_macro_events);
2d5f65a9 260 defsubr (&Sstore_kbd_macro_event);
5a7f5d07 261
cd8b5aa3 262 DEFVAR_KBOARD ("defining-kbd-macro", defining_kbd_macro,
5a7f5d07
JB
263 "Non-nil while a keyboard macro is being defined. Don't set this!");
264
265 DEFVAR_LISP ("executing-macro", &Vexecuting_macro,
9e1ffae2 266 "Currently executing keyboard macro (string or vector); nil if none executing.");
5a7f5d07
JB
267
268 DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro,
9e1ffae2 269 "Currently executing keyboard macro (string or vector); nil if none executing.");
5a7f5d07 270
cd8b5aa3 271 DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
9e1ffae2 272 "Last kbd macro defined, as a string or vector; nil if none defined.");
5a7f5d07
JB
273}
274
275keys_of_macros ()
276{
277 initial_define_key (control_x_map, ('e'), "call-last-kbd-macro");
278 initial_define_key (control_x_map, ('('), "start-kbd-macro");
279 initial_define_key (control_x_map, (')'), "end-kbd-macro");
280}