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