Fix openssl support
[sxemacs] / 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 SXEmacs
5
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.
10
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.
15
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/>. */
18
19
20 /* Synched up with: FSF 19.30. */
21
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.
25
26    When interactively defining a keyboard macro, it will always be a vector
27    of events; strings may be executed for backwards compatibility.
28  */
29
30 #include <config.h>
31 #include "lisp.h"
32 #include "events/events.h"
33 #include "macros.h"
34 #include "commands.h"
35 #include "ui/console.h"
36 #include "buffer.h"
37 #include "ui/window.h"
38 #include "ui/frame.h"
39 #include "ui/keymap.h"
40
41 Lisp_Object Qexecute_kbd_macro;
42
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
45    with unwind-protect.
46  */
47 Lisp_Object Vexecuting_macro;
48 int executing_macro_index;
49 \f
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.
57 */
58       (append))
59 {
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");
64
65         if (NILP(con->kbd_macro_builder))
66                 con->kbd_macro_builder = make_vector(30, Qnil);
67
68         zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
69                                    so that functions there can override */
70         MARK_MODELINE_CHANGED;
71         if (NILP(append)) {
72                 con->kbd_macro_ptr = 0;
73                 con->kbd_macro_end = 0;
74                 message("Defining kbd macro...");
75         } else {
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));
79         }
80         con->defining_kbd_macro = Qt;
81
82         return Qnil;
83 }
84
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
90 under that name.
91
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.
95 */
96       (arg))
97 {
98         /* This function can GC */
99         struct console *con = XCONSOLE(Vselected_console);
100         int repeat;
101
102         if (NILP(con->defining_kbd_macro))
103                 error("Not defining kbd macro");
104
105         if (NILP(arg))
106                 repeat = -1;
107         else
108                 repeat = XINT(Fprefix_numeric_value(arg));
109
110         if (!NILP(con->defining_kbd_macro)) {
111                 int i;
112                 int size = con->kbd_macro_end;
113
114                 if (size < 0)
115                         size = 0;
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");
123         }
124
125         zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
126                                    so that functions there can override */
127         if (repeat < 0)
128                 return Qnil;
129         else if (repeat == 0)
130                 return Fexecute_kbd_macro(con->last_kbd_macro, Qzero);
131         else
132                 return Fexecute_kbd_macro(con->last_kbd_macro,
133                                           make_int(repeat - 1));
134 }
135
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.
140 */
141       ())
142 {
143         struct console *con = XCONSOLE(Vselected_console);
144         if (con->kbd_macro_end)
145                 --con->kbd_macro_end;
146         return Qnil;
147 }
148
149 /* Store event into kbd macro being defined
150  */
151 void store_kbd_macro_event(Lisp_Object event)
152 {
153         struct console *con = event_console_or_selected(event);
154
155         if (con->kbd_macro_ptr == XVECTOR_LENGTH(con->kbd_macro_builder)) {
156                 int i;
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;
164         }
165         XVECTOR_DATA(con->kbd_macro_builder)[con->kbd_macro_ptr++] =
166             Fcopy_event(event, Qnil);
167 }
168
169 /* Extract the next kbd-macro element into the given event.
170    If we're done, throws to the catch in Fexecute_kbd_macro().
171  */
172 void pop_kbd_macro_event(Lisp_Object event)
173 {
174         if (NILP(Vexecuting_macro))
175                 abort();
176
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++,
181                                                      event);
182                         return;
183                 }
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");
187
188         Fthrow(Qexecute_kbd_macro, Qt);
189 }
190
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. */
193
194 void finalize_kbd_macro_chars(struct console *con)
195 {
196         con->kbd_macro_end = con->kbd_macro_ptr;
197 }
198
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.
201 */
202       ())
203 {
204         struct console *con = XCONSOLE(Vselected_console);
205
206         con->kbd_macro_ptr = con->kbd_macro_end;
207
208         return Qnil;
209 }
210 \f
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].
213
214 A prefix argument serves as a repeat count.  Zero means repeat until error.
215
216 To make a macro permanent so you can call it even after
217 defining others, use \\[name-last-kbd-macro].
218 */
219       (prefix))
220 {
221         /* This function can GC */
222         struct console *con = XCONSOLE(Vselected_console);
223
224         if (NILP(con->last_kbd_macro)) {
225                 error("No kbd macro has been defined");
226                 return Qnil;
227         }
228         Fexecute_kbd_macro(con->last_kbd_macro, prefix);
229         if (!NILP(con->defining_kbd_macro)) {
230                 int i;
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]);
234         }
235         return Qnil;
236 }
237
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)
241 {
242         Vexecuting_macro = Fcar(info);
243         executing_macro_index = XINT(Fcdr(info));
244         return Qnil;
245 }
246
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.
251 */
252       (macro, count))
253 {
254         /* This function can GC */
255         Lisp_Object final;
256         Lisp_Object tem;
257         int speccount = specpdl_depth();
258         int repeat = 1;
259         struct gcpro gcpro1;
260         struct console *con = XCONSOLE(Vselected_console);
261
262         if (!NILP(count)) {
263                 count = Fprefix_numeric_value(count);
264                 repeat = XINT(count);
265         }
266
267         final = indirect_function(macro, 1);
268         if (!STRINGP(final) && !VECTORP(final))
269                 error("Keyboard macros must be strings or vectors");
270
271         tem = Fcons(Vexecuting_macro, make_int(executing_macro_index));
272         record_unwind_protect(pop_kbd_macro, tem);
273
274         GCPRO1(final);
275         do {
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);
280         }
281         while (--repeat != 0
282                && (STRINGP(Vexecuting_macro) || VECTORP(Vexecuting_macro)));
283
284         UNGCPRO;
285         return unbind_to(speccount, Qnil);
286 }
287 \f
288 void syms_of_macros(void)
289 {
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");
297 }
298
299 void vars_of_macros(void)
300 {
301         DEFVAR_LISP("executing-macro", &Vexecuting_macro        /*
302 Currently executing keyboard macro (a vector of events or string);
303 nil if none executing.
304                                                                  */ );
305
306         DEFVAR_LISP("executing-kbd-macro", &Vexecuting_macro    /*
307 Currently executing keyboard macro (a vector of events or string);
308 nil if none executing.
309                                                                  */ );
310 }
311
312 void init_macros(void)
313 {
314         Vexecuting_macro = Qnil;
315 }