Mercurial > hg > xemacs-beta
comparison src/macros.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
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 | |
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 | |
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, prefixarg)) | |
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 (prefixarg)) | |
271 { | |
272 prefixarg = Fprefix_numeric_value (prefixarg); | |
273 repeat = XINT (prefixarg); | |
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 | |
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 |