This source file includes following definitions.
- end_kbd_macro
- store_kbd_macro_char
- finalize_kbd_macro_chars
- DEFUN
- DEFUN
- pop_kbd_macro
- init_macros
- syms_of_macros
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include "lisp.h"
24 #include "macros.h"
25 #include "window.h"
26 #include "keyboard.h"
27
28
29
30
31
32
33 EMACS_INT executing_kbd_macro_iterations;
34
35
36
37
38
39
40 Lisp_Object executing_kbd_macro;
41
42 DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 2, "P",
43 doc:
44
45
46
47
48
49
50 )
51 (Lisp_Object append, Lisp_Object no_exec)
52 {
53 if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
54 error ("Already defining kbd macro");
55
56 if (!current_kboard->kbd_macro_buffer)
57 {
58 current_kboard->kbd_macro_buffer = xmalloc (30 * word_size);
59 current_kboard->kbd_macro_bufsize = 30;
60 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
61 current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
62 }
63 update_mode_lines = 19;
64 if (NILP (append))
65 {
66 if (current_kboard->kbd_macro_bufsize > 200)
67 {
68 current_kboard->kbd_macro_buffer
69 = xrealloc (current_kboard->kbd_macro_buffer,
70 30 * word_size);
71 current_kboard->kbd_macro_bufsize = 30;
72 }
73 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
74 current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
75 message1 ("Defining kbd macro...");
76 }
77 else
78 {
79 int incr = 30;
80 ptrdiff_t i, len;
81 bool cvt;
82
83
84 len = CHECK_VECTOR_OR_STRING (KVAR (current_kboard, Vlast_kbd_macro));
85
86
87
88 if (current_kboard->kbd_macro_bufsize - incr < len)
89 current_kboard->kbd_macro_buffer =
90 xpalloc (current_kboard->kbd_macro_buffer,
91 ¤t_kboard->kbd_macro_bufsize,
92 len - current_kboard->kbd_macro_bufsize + incr, -1,
93 sizeof *current_kboard->kbd_macro_buffer);
94
95
96 cvt = STRINGP (KVAR (current_kboard, Vlast_kbd_macro));
97 for (i = 0; i < len; i++)
98 {
99 Lisp_Object c;
100 c = Faref (KVAR (current_kboard, Vlast_kbd_macro), make_fixnum (i));
101 if (cvt && FIXNATP (c) && (XFIXNAT (c) & 0x80))
102 XSETFASTINT (c, CHAR_META | (XFIXNAT (c) & ~0x80));
103 current_kboard->kbd_macro_buffer[i] = c;
104 }
105
106 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer + len;
107 current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
108
109
110
111 if (NILP (no_exec))
112 Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
113 make_fixnum (1), Qnil);
114
115 message1 ("Appending to kbd macro...");
116 }
117 kset_defining_kbd_macro (current_kboard, Qt);
118
119 return Qnil;
120 }
121
122
123
124 void
125 end_kbd_macro (void)
126 {
127 kset_defining_kbd_macro (current_kboard, Qnil);
128 update_mode_lines = 20;
129 kset_last_kbd_macro
130 (current_kboard,
131 Fvector ((current_kboard->kbd_macro_end
132 - current_kboard->kbd_macro_buffer),
133 current_kboard->kbd_macro_buffer));
134 }
135
136 DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 2, "p",
137 doc:
138
139
140
141
142
143
144
145
146
147
148 )
149 (Lisp_Object repeat, Lisp_Object loopfunc)
150 {
151 if (NILP (KVAR (current_kboard, defining_kbd_macro)))
152 error ("Not defining kbd macro");
153
154 if (NILP (repeat))
155 XSETFASTINT (repeat, 1);
156 else
157 CHECK_FIXNUM (repeat);
158
159 if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
160 {
161 end_kbd_macro ();
162 message1 ("Keyboard macro defined");
163 }
164
165 if (XFIXNAT (repeat) == 0)
166 Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc);
167 else if (XFIXNUM (repeat) > 1)
168 {
169 XSETINT (repeat, XFIXNUM (repeat) - 1);
170 Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
171 repeat, loopfunc);
172 }
173 return Qnil;
174 }
175
176
177
178 void
179 store_kbd_macro_char (Lisp_Object c)
180 {
181 struct kboard *kb = current_kboard;
182
183 if (!NILP (KVAR (kb, defining_kbd_macro)))
184 {
185 if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
186 {
187 ptrdiff_t ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
188 ptrdiff_t end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
189 kb->kbd_macro_buffer = xpalloc (kb->kbd_macro_buffer,
190 &kb->kbd_macro_bufsize,
191 1, -1, sizeof *kb->kbd_macro_buffer);
192 kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
193 kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
194 }
195
196 *kb->kbd_macro_ptr++ = c;
197 }
198 }
199
200
201
202
203 void
204 finalize_kbd_macro_chars (void)
205 {
206 current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr;
207 }
208
209 DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events,
210 Scancel_kbd_macro_events, 0, 0, 0,
211 doc: )
212 (void)
213 {
214 current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_end;
215 return Qnil;
216 }
217
218 DEFUN ("store-kbd-macro-event", Fstore_kbd_macro_event,
219 Sstore_kbd_macro_event, 1, 1, 0,
220 doc: )
221 (Lisp_Object event)
222 {
223 store_kbd_macro_char (event);
224 return Qnil;
225 }
226
227 DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
228 0, 2, "p",
229 doc:
230
231
232
233
234
235
236
237 )
238 (Lisp_Object prefix, Lisp_Object loopfunc)
239 {
240
241
242 Vthis_command = KVAR (current_kboard, Vlast_command);
243
244 Vreal_this_command = KVAR (current_kboard, Vlast_kbd_macro);
245
246 if (! NILP (KVAR (current_kboard, defining_kbd_macro)))
247 error ("Can't execute anonymous macro while defining one");
248 else if (NILP (KVAR (current_kboard, Vlast_kbd_macro)))
249 error ("No kbd macro has been defined");
250 else
251 Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), prefix, loopfunc);
252
253
254
255
256 Vthis_command = KVAR (current_kboard, Vlast_command);
257
258 return Qnil;
259 }
260
261
262
263
264 static void
265 pop_kbd_macro (Lisp_Object info)
266 {
267 Lisp_Object tem;
268 Vexecuting_kbd_macro = XCAR (info);
269 tem = XCDR (info);
270 integer_to_intmax (XCAR (tem), &executing_kbd_macro_index);
271 Vreal_this_command = XCDR (tem);
272 run_hook (Qkbd_macro_termination_hook);
273 }
274
275 DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0,
276 doc:
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 )
292 (Lisp_Object macro, Lisp_Object count, Lisp_Object loopfunc)
293 {
294 Lisp_Object final;
295 Lisp_Object tem;
296 specpdl_ref pdlcount = SPECPDL_INDEX ();
297 EMACS_INT repeat = 1;
298 EMACS_INT success_count = 0;
299
300 executing_kbd_macro_iterations = 0;
301
302 if (!NILP (count))
303 {
304 count = Fprefix_numeric_value (count);
305 repeat = XFIXNUM (count);
306 }
307
308 final = indirect_function (macro);
309 if (!STRINGP (final) && !VECTORP (final))
310 error ("Keyboard macros must be strings or vectors");
311
312 tem = Fcons (Vexecuting_kbd_macro,
313 Fcons (make_int (executing_kbd_macro_index),
314 Vreal_this_command));
315 record_unwind_protect (pop_kbd_macro, tem);
316
317 do
318 {
319 Vexecuting_kbd_macro = final;
320 executing_kbd_macro = final;
321 executing_kbd_macro_index = 0;
322
323 kset_prefix_arg (current_kboard, Qnil);
324
325 if (!NILP (loopfunc))
326 {
327 Lisp_Object cont;
328 cont = call0 (loopfunc);
329 if (NILP (cont))
330 break;
331 }
332
333 command_loop_2 (list1 (Qminibuffer_quit));
334
335 executing_kbd_macro_iterations = ++success_count;
336
337 maybe_quit ();
338 }
339 while (--repeat
340 && (STRINGP (Vexecuting_kbd_macro) || VECTORP (Vexecuting_kbd_macro)));
341
342 executing_kbd_macro = Qnil;
343
344 Vreal_this_command = Vexecuting_kbd_macro;
345
346 return unbind_to (pdlcount, Qnil);
347 }
348
349 void
350 init_macros (void)
351 {
352 Vexecuting_kbd_macro = Qnil;
353 executing_kbd_macro = Qnil;
354 }
355
356 void
357 syms_of_macros (void)
358 {
359 DEFVAR_LISP ("kbd-macro-termination-hook", Vkbd_macro_termination_hook,
360 doc:
361 );
362 Vkbd_macro_termination_hook = Qnil;
363 DEFSYM (Qkbd_macro_termination_hook, "kbd-macro-termination-hook");
364
365 defsubr (&Sstart_kbd_macro);
366 defsubr (&Send_kbd_macro);
367 defsubr (&Scall_last_kbd_macro);
368 defsubr (&Sexecute_kbd_macro);
369 defsubr (&Scancel_kbd_macro_events);
370 defsubr (&Sstore_kbd_macro_event);
371
372 DEFVAR_KBOARD ("defining-kbd-macro", defining_kbd_macro,
373 doc:
374
375 );
376
377 DEFVAR_LISP ("executing-kbd-macro", Vexecuting_kbd_macro,
378 doc:
379 );
380
381 DEFVAR_INT ("executing-kbd-macro-index", executing_kbd_macro_index,
382 doc: );
383
384 DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
385 doc: );
386 }