2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of SXEmacs
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* Synched up with: FSF 19.30. */
22 /* A keyboard macro is a string of ASCII characters, or a vector of event
23 objects. Only key-press, mouse-press, mouse-release, and menu-selection
24 events ever get into a keyboard macro.
26 When interactively defining a keyboard macro, it will always be a vector
27 of events; strings may be executed for backwards compatibility.
32 #include "events/events.h"
35 #include "ui/console.h"
37 #include "ui/window.h"
39 #include "ui/keymap.h"
41 Lisp_Object Qexecute_kbd_macro;
43 /* The current macro and our position in it. When executing nested kbd
44 macros, previous values for these are wound through the execution stack
47 Lisp_Object Vexecuting_macro;
48 int executing_macro_index;
50 DEFUN("start-kbd-macro", Fstart_kbd_macro, 1, 1, "P", /*
51 Record subsequent keyboard and menu input, defining a keyboard macro.
52 The commands are recorded even as they are executed.
53 Use \\[end-kbd-macro] to finish recording and make the macro available.
54 Use \\[name-last-kbd-macro] to give it a permanent name.
55 Non-nil arg (prefix arg) means append to last macro defined;
56 This begins by re-executing that macro as if you typed it again.
60 /* This function can GC */
61 struct console *con = XCONSOLE(Vselected_console);
62 if (!NILP(con->defining_kbd_macro))
63 error("Already defining kbd macro");
65 if (NILP(con->kbd_macro_builder))
66 con->kbd_macro_builder = make_vector(30, Qnil);
68 zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
69 so that functions there can override */
70 MARK_MODELINE_CHANGED;
72 con->kbd_macro_ptr = 0;
73 con->kbd_macro_end = 0;
74 message("Defining kbd macro...");
76 message("Appending to kbd macro...");
77 con->kbd_macro_ptr = con->kbd_macro_end;
78 Fexecute_kbd_macro(con->last_kbd_macro, make_int(1));
80 con->defining_kbd_macro = Qt;
85 DEFUN("end-kbd-macro", Fend_kbd_macro, 0, 1, "P", /*
86 Finish defining a keyboard macro.
87 The definition was started by \\[start-kbd-macro].
88 The macro is now available for use via \\[call-last-kbd-macro],
89 or it can be given a name with \\[name-last-kbd-macro] and then invoked
92 With numeric arg, repeat macro now that many times,
93 counting the definition just completed as the first repetition.
94 An argument of zero means repeat until error.
98 /* This function can GC */
99 struct console *con = XCONSOLE(Vselected_console);
102 if (NILP(con->defining_kbd_macro))
103 error("Not defining kbd macro");
108 repeat = XINT(Fprefix_numeric_value(arg));
110 if (!NILP(con->defining_kbd_macro)) {
112 int size = con->kbd_macro_end;
116 con->last_kbd_macro = make_vector(size, Qnil);
117 for (i = 0; i < size; i++)
118 XVECTOR_DATA(con->last_kbd_macro)[i] =
119 XVECTOR_DATA(con->kbd_macro_builder)[i];
120 con->defining_kbd_macro = Qnil;
121 MARK_MODELINE_CHANGED;
122 message("Keyboard macro defined");
125 zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
126 so that functions there can override */
129 else if (repeat == 0)
130 return Fexecute_kbd_macro(con->last_kbd_macro, Qzero);
132 return Fexecute_kbd_macro(con->last_kbd_macro,
133 make_int(repeat - 1));
136 /* #### Read the comment in modeline.el to see why this ugliness is
137 needed. #### Try to avoid it, somehow! */
138 DEFUN("zap-last-kbd-macro-event", Fzap_last_kbd_macro_event, 0, 0, 0, /*
139 Don't look at this lest you vomit or spontaneously combust.
143 struct console *con = XCONSOLE(Vselected_console);
144 if (con->kbd_macro_end)
145 --con->kbd_macro_end;
149 /* Store event into kbd macro being defined
151 void store_kbd_macro_event(Lisp_Object event)
153 struct console *con = event_console_or_selected(event);
155 if (con->kbd_macro_ptr == XVECTOR_LENGTH(con->kbd_macro_builder)) {
157 int old_size = XVECTOR_LENGTH(con->kbd_macro_builder);
158 int new_size = old_size * 2;
159 Lisp_Object new = make_vector(new_size, Qnil);
160 for (i = 0; i < old_size; i++)
161 XVECTOR_DATA(new)[i] =
162 XVECTOR_DATA(con->kbd_macro_builder)[i];
163 con->kbd_macro_builder = new;
165 XVECTOR_DATA(con->kbd_macro_builder)[con->kbd_macro_ptr++] =
166 Fcopy_event(event, Qnil);
169 /* Extract the next kbd-macro element into the given event.
170 If we're done, throws to the catch in Fexecute_kbd_macro().
172 void pop_kbd_macro_event(Lisp_Object event)
174 if (NILP(Vexecuting_macro))
177 if (STRINGP(Vexecuting_macro) || VECTORP(Vexecuting_macro)) {
178 if (executing_macro_index < XINT(Flength(Vexecuting_macro))) {
179 nth_of_key_sequence_as_event(Vexecuting_macro,
180 executing_macro_index++,
184 } else if (!EQ(Vexecuting_macro, Qt)) /* Some things replace the macro
185 with Qt to force an early exit. */
186 error("junk in executing-macro");
188 Fthrow(Qexecute_kbd_macro, Qt);
191 /* Declare that all chars stored so far in the kbd macro being defined
192 really belong to it. This is done in between editor commands. */
194 void finalize_kbd_macro_chars(struct console *con)
196 con->kbd_macro_end = con->kbd_macro_ptr;
199 DEFUN("cancel-kbd-macro-events", Fcancel_kbd_macro_events, 0, 0, 0, /*
200 Cancel the events added to a keyboard macro for this command.
204 struct console *con = XCONSOLE(Vselected_console);
206 con->kbd_macro_ptr = con->kbd_macro_end;
211 DEFUN("call-last-kbd-macro", Fcall_last_kbd_macro, 0, 1, "p", /*
212 Call the last keyboard macro that you defined with \\[start-kbd-macro].
214 A prefix argument serves as a repeat count. Zero means repeat until error.
216 To make a macro permanent so you can call it even after
217 defining others, use \\[name-last-kbd-macro].
221 /* This function can GC */
222 struct console *con = XCONSOLE(Vselected_console);
224 if (NILP(con->last_kbd_macro)) {
225 error("No kbd macro has been defined");
228 Fexecute_kbd_macro(con->last_kbd_macro, prefix);
229 if (!NILP(con->defining_kbd_macro)) {
231 Fcancel_kbd_macro_events();
232 for (i = 0; i < XVECTOR_LENGTH(con->last_kbd_macro); i++)
233 store_kbd_macro_event(XVECTOR_DATA(con->last_kbd_macro)[i]);
238 /* Restore Vexecuting_macro and executing_macro_index - called when
239 the unwind-protect in Fexecute_kbd_macro gets invoked. */
240 static Lisp_Object pop_kbd_macro(Lisp_Object info)
242 Vexecuting_macro = Fcar(info);
243 executing_macro_index = XINT(Fcdr(info));
247 DEFUN("execute-kbd-macro", Fexecute_kbd_macro, 1, 2, 0, /*
248 Execute MACRO as string of editor command characters.
249 If MACRO is a symbol, its function definition is used.
250 COUNT is a repeat count, or nil for once, or 0 for infinite loop.
254 /* This function can GC */
257 int speccount = specpdl_depth();
260 struct console *con = XCONSOLE(Vselected_console);
263 count = Fprefix_numeric_value(count);
264 repeat = XINT(count);
267 final = indirect_function(macro, 1);
268 if (!STRINGP(final) && !VECTORP(final))
269 error("Keyboard macros must be strings or vectors");
271 tem = Fcons(Vexecuting_macro, make_int(executing_macro_index));
272 record_unwind_protect(pop_kbd_macro, tem);
276 Vexecuting_macro = final;
277 executing_macro_index = 0;
278 con->prefix_arg = Qnil;
279 internal_catch(Qexecute_kbd_macro, call_command_loop, Qnil, 0);
282 && (STRINGP(Vexecuting_macro) || VECTORP(Vexecuting_macro)));
285 return unbind_to(speccount, Qnil);
288 void syms_of_macros(void)
290 DEFSUBR(Fstart_kbd_macro);
291 DEFSUBR(Fend_kbd_macro);
292 DEFSUBR(Fzap_last_kbd_macro_event);
293 DEFSUBR(Fcall_last_kbd_macro);
294 DEFSUBR(Fexecute_kbd_macro);
295 DEFSUBR(Fcancel_kbd_macro_events);
296 defsymbol(&Qexecute_kbd_macro, "execute-kbd-macro");
299 void vars_of_macros(void)
301 DEFVAR_LISP("executing-macro", &Vexecuting_macro /*
302 Currently executing keyboard macro (a vector of events or string);
303 nil if none executing.
306 DEFVAR_LISP("executing-kbd-macro", &Vexecuting_macro /*
307 Currently executing keyboard macro (a vector of events or string);
308 nil if none executing.
312 void init_macros(void)
314 Vexecuting_macro = Qnil;