(JC3-68CC): Map to U+9686 instead of U+F9DC.
[chise/xemacs-chise.git.1] / src / macros.c
1 /* Keyboard macros.
2    Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: FSF 19.30. */
22
23 /* A keyboard macro is a string of ASCII characters, or a vector of event
24    objects.  Only key-press, mouse-press, mouse-release, and menu-selection
25    events ever get into a keyboard macro.
26
27    When interactively defining a keyboard macro, it will always be a vector
28    of events; strings may be executed for backwards compatibility.
29  */
30
31 #include <config.h>
32 #include "lisp.h"
33 #include "events.h"
34 #include "macros.h"
35 #include "commands.h"
36 #include "console.h"
37 #include "buffer.h"
38 #include "window.h"
39 #include "frame.h"
40 #include "keymap.h"
41
42 Lisp_Object Qexecute_kbd_macro;
43
44 /* The current macro and our position in it.  When executing nested kbd
45    macros, previous values for these are wound through the execution stack
46    with unwind-protect.
47  */
48 Lisp_Object Vexecuting_macro;
49 int executing_macro_index;
50
51 \f
52 DEFUN ("start-kbd-macro", Fstart_kbd_macro, 1, 1, "P", /*
53 Record subsequent keyboard and menu input, defining a keyboard macro.
54 The commands are recorded even as they are executed.
55 Use \\[end-kbd-macro] to finish recording and make the macro available.
56 Use \\[name-last-kbd-macro] to give it a permanent name.
57 Non-nil arg (prefix arg) means append to last macro defined;
58  This begins by re-executing that macro as if you typed it again.
59 */
60        (append))
61 {
62   /* This function can GC */
63   struct console *con = XCONSOLE (Vselected_console);
64   if (!NILP (con->defining_kbd_macro))
65       error ("Already defining kbd macro");
66
67   if (NILP (con->kbd_macro_builder))
68     con->kbd_macro_builder = make_vector (30, Qnil);
69
70   zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
71                              so that functions there can override */
72   MARK_MODELINE_CHANGED;
73   if (NILP (append))
74     {
75       con->kbd_macro_ptr = 0;
76       con->kbd_macro_end = 0;
77       message ("Defining kbd macro...");
78     }
79   else
80     {
81       message ("Appending to kbd macro...");
82       con->kbd_macro_ptr = con->kbd_macro_end;
83       Fexecute_kbd_macro (con->last_kbd_macro, make_int (1));
84     }
85   con->defining_kbd_macro = Qt;
86
87   return Qnil;
88 }
89
90 DEFUN ("end-kbd-macro", Fend_kbd_macro, 0, 1, "P", /*
91 Finish defining a keyboard macro.
92 The definition was started by \\[start-kbd-macro].
93 The macro is now available for use via \\[call-last-kbd-macro],
94 or it can be given a name with \\[name-last-kbd-macro] and then invoked
95 under that name.
96
97 With numeric arg, repeat macro now that many times,
98 counting the definition just completed as the first repetition.
99 An argument of zero means repeat until error.
100 */
101        (arg))
102 {
103   /* This function can GC */
104   struct console *con = XCONSOLE (Vselected_console);
105   int repeat;
106
107   if (NILP (con->defining_kbd_macro))
108     error ("Not defining kbd macro");
109
110   if (NILP (arg))
111     repeat = -1;
112   else
113     repeat = XINT (Fprefix_numeric_value (arg));
114
115   if (!NILP (con->defining_kbd_macro))
116     {
117       int i;
118       int size = con->kbd_macro_end;
119
120       if (size < 0)
121         size = 0;
122       con->last_kbd_macro = make_vector (size, Qnil);
123       for (i = 0; i < size; i++)
124         XVECTOR_DATA (con->last_kbd_macro) [i] =
125           XVECTOR_DATA (con->kbd_macro_builder) [i];
126       con->defining_kbd_macro = Qnil;
127       MARK_MODELINE_CHANGED;
128       message ("Keyboard macro defined");
129     }
130
131   zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
132                              so that functions there can override */
133   if (repeat < 0)
134     return Qnil;
135   else if (repeat == 0)
136     return Fexecute_kbd_macro (con->last_kbd_macro, Qzero);
137   else
138     return Fexecute_kbd_macro (con->last_kbd_macro,
139                                make_int (repeat - 1));
140 }
141
142 /* #### Read the comment in modeline.el to see why this ugliness is
143    needed.  #### Try to avoid it, somehow!  */
144 DEFUN ("zap-last-kbd-macro-event", Fzap_last_kbd_macro_event, 0, 0, 0, /*
145 Don't look at this lest you vomit or spontaneously combust.
146 */
147        ())
148 {
149   struct console *con = XCONSOLE (Vselected_console);
150   if (con->kbd_macro_end)
151     --con->kbd_macro_end;
152   return Qnil;
153 }
154
155 /* Store event into kbd macro being defined
156  */
157 void
158 store_kbd_macro_event (Lisp_Object event)
159 {
160   struct console *con = event_console_or_selected (event);
161
162   if (con->kbd_macro_ptr == XVECTOR_LENGTH (con->kbd_macro_builder))
163     {
164       int i;
165       int old_size = XVECTOR_LENGTH (con->kbd_macro_builder);
166       int new_size = old_size * 2;
167       Lisp_Object new = make_vector (new_size, Qnil);
168       for (i = 0; i < old_size; i++)
169         XVECTOR_DATA (new) [i] = XVECTOR_DATA (con->kbd_macro_builder) [i];
170       con->kbd_macro_builder = new;
171     }
172   XVECTOR_DATA (con->kbd_macro_builder) [con->kbd_macro_ptr++] =
173     Fcopy_event (event, Qnil);
174 }
175
176 /* Extract the next kbd-macro element into the given event.
177    If we're done, throws to the catch in Fexecute_kbd_macro().
178  */
179 void
180 pop_kbd_macro_event (Lisp_Object event)
181 {
182   if (NILP (Vexecuting_macro)) ABORT ();
183
184   if (STRINGP (Vexecuting_macro) || VECTORP (Vexecuting_macro))
185     {
186       if (executing_macro_index < XINT (Flength (Vexecuting_macro)))
187         {
188           nth_of_key_sequence_as_event (Vexecuting_macro,
189                                         executing_macro_index++,
190                                         event);
191           return;
192         }
193     }
194   else if (!EQ (Vexecuting_macro, Qt)) /* Some things replace the macro
195                                           with Qt to force an early exit. */
196     error ("junk in executing-macro");
197
198   Fthrow (Qexecute_kbd_macro, Qt);
199 }
200
201
202 /* Declare that all chars stored so far in the kbd macro being defined
203    really belong to it.  This is done in between editor commands. */
204
205 void
206 finalize_kbd_macro_chars (struct console *con)
207 {
208   con->kbd_macro_end = con->kbd_macro_ptr;
209 }
210
211 DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events, 0, 0, 0, /*
212 Cancel the events added to a keyboard macro for this command.
213 */
214        ())
215 {
216   struct console *con = XCONSOLE (Vselected_console);
217
218   con->kbd_macro_ptr = con->kbd_macro_end;
219
220   return Qnil;
221 }
222 \f
223 DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, 0, 1, "p", /*
224 Call the last keyboard macro that you defined with \\[start-kbd-macro].
225
226 A prefix argument serves as a repeat count.  Zero means repeat until error.
227
228 To make a macro permanent so you can call it even after
229 defining others, use \\[name-last-kbd-macro].
230 */
231        (prefix))
232 {
233   /* This function can GC */
234   struct console *con = XCONSOLE (Vselected_console);
235
236   if (!NILP (con->defining_kbd_macro))
237     error ("Can't execute anonymous macro while defining one");
238   else if (NILP (con->last_kbd_macro))
239     error ("No kbd macro has been defined");
240   else
241     Fexecute_kbd_macro (con->last_kbd_macro, prefix);
242   return Qnil;
243 }
244
245 /* Restore Vexecuting_macro and executing_macro_index - called when
246    the unwind-protect in Fexecute_kbd_macro gets invoked.  */
247 static Lisp_Object
248 pop_kbd_macro (Lisp_Object info)
249 {
250   Vexecuting_macro = Fcar (info);
251   executing_macro_index = XINT (Fcdr (info));
252   return Qnil;
253 }
254
255 DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, 1, 2, 0, /*
256 Execute MACRO as string of editor command characters.
257 If MACRO is a symbol, its function definition is used.
258 COUNT is a repeat count, or nil for once, or 0 for infinite loop.
259 */
260        (macro, count))
261 {
262   /* This function can GC */
263   Lisp_Object final;
264   Lisp_Object tem;
265   int speccount = specpdl_depth ();
266   int repeat = 1;
267   struct gcpro gcpro1;
268   struct console *con = XCONSOLE (Vselected_console);
269
270   if (!NILP (count))
271     {
272       count = Fprefix_numeric_value (count);
273       repeat = XINT (count);
274     }
275
276   final = indirect_function (macro, 1);
277   if (!STRINGP (final) && !VECTORP (final))
278     error ("Keyboard macros must be strings or vectors");
279
280   tem = Fcons (Vexecuting_macro, make_int (executing_macro_index));
281   record_unwind_protect (pop_kbd_macro, tem);
282
283   GCPRO1 (final);
284   do
285     {
286       Vexecuting_macro = final;
287       executing_macro_index = 0;
288       con->prefix_arg = Qnil;
289       internal_catch (Qexecute_kbd_macro, call_command_loop,
290                       Qnil, 0);
291     }
292   while (--repeat != 0
293          && (STRINGP (Vexecuting_macro) ||
294              VECTORP (Vexecuting_macro)));
295
296   UNGCPRO;
297   return unbind_to (speccount, Qnil);
298 }
299
300 \f
301 void
302 syms_of_macros (void)
303 {
304   DEFSUBR (Fstart_kbd_macro);
305   DEFSUBR (Fend_kbd_macro);
306   DEFSUBR (Fzap_last_kbd_macro_event);
307   DEFSUBR (Fcall_last_kbd_macro);
308   DEFSUBR (Fexecute_kbd_macro);
309   DEFSUBR (Fcancel_kbd_macro_events);
310   defsymbol (&Qexecute_kbd_macro, "execute-kbd-macro");
311 }
312
313 void
314 vars_of_macros (void)
315 {
316   DEFVAR_LISP ("executing-macro", &Vexecuting_macro /*
317 Currently executing keyboard macro (a vector of events or string);
318 nil if none executing.
319 */ );
320
321   DEFVAR_LISP ("executing-kbd-macro", &Vexecuting_macro /*
322 Currently executing keyboard macro (a vector of events or string);
323 nil if none executing.
324 */ );
325 }
326
327 void
328 init_macros (void)
329 {
330   Vexecuting_macro = Qnil;
331 }
332