35 |
|
|
36 |
/* Index of next character to fetch from that macro. */ |
/* Index of next character to fetch from that macro. */ |
37 |
|
|
38 |
int executing_macro_index; |
EMACS_INT executing_macro_index; |
39 |
|
|
40 |
/* Number of successful iterations so far |
/* Number of successful iterations so far |
41 |
for innermost keyboard macro. |
for innermost keyboard macro. |
55 |
|
|
56 |
Lisp_Object Fexecute_kbd_macro (); |
Lisp_Object Fexecute_kbd_macro (); |
57 |
|
|
58 |
DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P", |
DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 2, "P", |
59 |
doc: /* Record subsequent keyboard input, defining a keyboard macro. |
doc: /* Record subsequent keyboard input, defining a keyboard macro. |
60 |
The commands are recorded even as they are executed. |
The commands are recorded even as they are executed. |
61 |
Use \\[end-kbd-macro] to finish recording and make the macro available. |
Use \\[end-kbd-macro] to finish recording and make the macro available. |
62 |
Use \\[name-last-kbd-macro] to give it a permanent name. |
Use \\[name-last-kbd-macro] to give it a permanent name. |
63 |
Non-nil arg (prefix arg) means append to last macro defined; |
Non-nil arg (prefix arg) means append to last macro defined; |
64 |
this begins by re-executing that macro as if you typed it again. */) |
this begins by re-executing that macro as if you typed it again. |
65 |
(append) |
If optional second arg, NO-EXEC, is non-nil, do not re-execute last |
66 |
Lisp_Object append; |
macro before appending to it. */) |
67 |
|
(append, no_exec) |
68 |
|
Lisp_Object append, no_exec; |
69 |
{ |
{ |
70 |
if (!NILP (current_kboard->defining_kbd_macro)) |
if (!NILP (current_kboard->defining_kbd_macro)) |
71 |
error ("Already defining kbd macro"); |
error ("Already defining kbd macro"); |
93 |
else |
else |
94 |
{ |
{ |
95 |
int i, len; |
int i, len; |
96 |
|
int cvt; |
97 |
|
|
98 |
/* Check the type of last-kbd-macro in case Lisp code changed it. */ |
/* Check the type of last-kbd-macro in case Lisp code changed it. */ |
99 |
if (!STRINGP (current_kboard->Vlast_kbd_macro) |
if (!STRINGP (current_kboard->Vlast_kbd_macro) |
112 |
= (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer, |
= (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer, |
113 |
(len + 30) * sizeof (Lisp_Object)); |
(len + 30) * sizeof (Lisp_Object)); |
114 |
} |
} |
115 |
|
|
116 |
|
/* Must convert meta modifier when copying string to vector. */ |
117 |
|
cvt = STRINGP (current_kboard->Vlast_kbd_macro); |
118 |
for (i = 0; i < len; i++) |
for (i = 0; i < len; i++) |
119 |
current_kboard->kbd_macro_buffer[i] |
{ |
120 |
= Faref (current_kboard->Vlast_kbd_macro, make_number (i)); |
Lisp_Object c; |
121 |
|
c = Faref (current_kboard->Vlast_kbd_macro, make_number (i)); |
122 |
|
if (cvt && NATNUMP (c) && (XFASTINT (c) & 0x80)) |
123 |
|
XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80)); |
124 |
|
current_kboard->kbd_macro_buffer[i] = c; |
125 |
|
} |
126 |
|
|
127 |
current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer + len; |
current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer + len; |
128 |
current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr; |
current_kboard->kbd_macro_end = current_kboard->kbd_macro_ptr; |
129 |
|
|
130 |
/* Re-execute the macro we are appending to, |
/* Re-execute the macro we are appending to, |
131 |
for consistency of behavior. */ |
for consistency of behavior. */ |
132 |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, |
if (NILP (no_exec)) |
133 |
make_number (1)); |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, |
134 |
|
make_number (1), Qnil); |
135 |
|
|
136 |
message ("Appending to kbd macro..."); |
message ("Appending to kbd macro..."); |
137 |
} |
} |
138 |
current_kboard->defining_kbd_macro = Qt; |
current_kboard->defining_kbd_macro = Qt; |
139 |
|
|
140 |
return Qnil; |
return Qnil; |
141 |
} |
} |
142 |
|
|
143 |
DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p", |
/* Finish defining the current keyboard macro. */ |
144 |
|
|
145 |
|
void |
146 |
|
end_kbd_macro () |
147 |
|
{ |
148 |
|
current_kboard->defining_kbd_macro = Qnil; |
149 |
|
update_mode_lines++; |
150 |
|
current_kboard->Vlast_kbd_macro |
151 |
|
= make_event_array ((current_kboard->kbd_macro_end |
152 |
|
- current_kboard->kbd_macro_buffer), |
153 |
|
current_kboard->kbd_macro_buffer); |
154 |
|
} |
155 |
|
|
156 |
|
DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 2, "p", |
157 |
doc: /* Finish defining a keyboard macro. |
doc: /* Finish defining a keyboard macro. |
158 |
The definition was started by \\[start-kbd-macro]. |
The definition was started by \\[start-kbd-macro]. |
159 |
The macro is now available for use via \\[call-last-kbd-macro], |
The macro is now available for use via \\[call-last-kbd-macro], |
162 |
|
|
163 |
With numeric arg, repeat macro now that many times, |
With numeric arg, repeat macro now that many times, |
164 |
counting the definition just completed as the first repetition. |
counting the definition just completed as the first repetition. |
165 |
An argument of zero means repeat until error. */) |
An argument of zero means repeat until error. |
166 |
(repeat) |
|
167 |
Lisp_Object repeat; |
In Lisp, optional second arg LOOPFUNC may be a function that is called prior to |
168 |
|
each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) |
169 |
|
(repeat, loopfunc) |
170 |
|
Lisp_Object repeat, loopfunc; |
171 |
{ |
{ |
172 |
if (NILP (current_kboard->defining_kbd_macro)) |
if (NILP (current_kboard->defining_kbd_macro)) |
173 |
error ("Not defining kbd macro"); |
error ("Not defining kbd macro"); |
179 |
|
|
180 |
if (!NILP (current_kboard->defining_kbd_macro)) |
if (!NILP (current_kboard->defining_kbd_macro)) |
181 |
{ |
{ |
182 |
current_kboard->defining_kbd_macro = Qnil; |
end_kbd_macro (); |
|
update_mode_lines++; |
|
|
current_kboard->Vlast_kbd_macro |
|
|
= make_event_array ((current_kboard->kbd_macro_end |
|
|
- current_kboard->kbd_macro_buffer), |
|
|
current_kboard->kbd_macro_buffer); |
|
183 |
message ("Keyboard macro defined"); |
message ("Keyboard macro defined"); |
184 |
} |
} |
185 |
|
|
186 |
if (XFASTINT (repeat) == 0) |
if (XFASTINT (repeat) == 0) |
187 |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat); |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat, loopfunc); |
188 |
else |
else |
189 |
{ |
{ |
190 |
XSETINT (repeat, XINT (repeat)-1); |
XSETINT (repeat, XINT (repeat)-1); |
191 |
if (XINT (repeat) > 0) |
if (XINT (repeat) > 0) |
192 |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat); |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, repeat, loopfunc); |
193 |
} |
} |
194 |
return Qnil; |
return Qnil; |
195 |
} |
} |
207 |
if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize) |
if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize) |
208 |
{ |
{ |
209 |
int ptr_offset, end_offset, nbytes; |
int ptr_offset, end_offset, nbytes; |
210 |
|
|
211 |
ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer; |
ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer; |
212 |
end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer; |
end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer; |
213 |
kb->kbd_macro_bufsize *= 2; |
kb->kbd_macro_bufsize *= 2; |
217 |
kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset; |
kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset; |
218 |
kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset; |
kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset; |
219 |
} |
} |
220 |
|
|
221 |
*kb->kbd_macro_ptr++ = c; |
*kb->kbd_macro_ptr++ = c; |
222 |
} |
} |
223 |
} |
} |
251 |
} |
} |
252 |
|
|
253 |
DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro, |
DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro, |
254 |
0, 1, "p", |
0, 2, "p", |
255 |
doc: /* Call the last keyboard macro that you defined with \\[start-kbd-macro]. |
doc: /* Call the last keyboard macro that you defined with \\[start-kbd-macro]. |
256 |
|
|
257 |
A prefix argument serves as a repeat count. Zero means repeat until error. |
A prefix argument serves as a repeat count. Zero means repeat until error. |
258 |
|
|
259 |
To make a macro permanent so you can call it even after |
To make a macro permanent so you can call it even after |
260 |
defining others, use \\[name-last-kbd-macro]. */) |
defining others, use \\[name-last-kbd-macro]. |
261 |
(prefix) |
|
262 |
Lisp_Object prefix; |
In Lisp, optional second arg LOOPFUNC may be a function that is called prior to |
263 |
|
each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) |
264 |
|
(prefix, loopfunc) |
265 |
|
Lisp_Object prefix, loopfunc; |
266 |
{ |
{ |
267 |
/* Don't interfere with recognition of the previous command |
/* Don't interfere with recognition of the previous command |
268 |
from before this macro started. */ |
from before this macro started. */ |
275 |
else if (NILP (current_kboard->Vlast_kbd_macro)) |
else if (NILP (current_kboard->Vlast_kbd_macro)) |
276 |
error ("No kbd macro has been defined"); |
error ("No kbd macro has been defined"); |
277 |
else |
else |
278 |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, prefix); |
Fexecute_kbd_macro (current_kboard->Vlast_kbd_macro, prefix, loopfunc); |
279 |
|
|
280 |
/* command_loop_1 sets this to nil before it returns; |
/* command_loop_1 sets this to nil before it returns; |
281 |
get back the last command within the macro |
get back the last command within the macro |
301 |
return Qnil; |
return Qnil; |
302 |
} |
} |
303 |
|
|
304 |
DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0, |
DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0, |
305 |
doc: /* Execute MACRO as string of editor command characters. |
doc: /* Execute MACRO as string of editor command characters. |
306 |
If MACRO is a symbol, its function definition is used. |
If MACRO is a symbol, its function definition is used. |
307 |
COUNT is a repeat count, or nil for once, or 0 for infinite loop. */) |
COUNT is a repeat count, or nil for once, or 0 for infinite loop. |
308 |
(macro, count) |
|
309 |
Lisp_Object macro, count; |
Optional third arg LOOPFUNC may be a function that is called prior to |
310 |
|
each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) |
311 |
|
(macro, count, loopfunc) |
312 |
|
Lisp_Object macro, count, loopfunc; |
313 |
{ |
{ |
314 |
Lisp_Object final; |
Lisp_Object final; |
315 |
Lisp_Object tem; |
Lisp_Object tem; |
316 |
int pdlcount = specpdl_ptr - specpdl; |
int pdlcount = SPECPDL_INDEX (); |
317 |
int repeat = 1; |
int repeat = 1; |
318 |
struct gcpro gcpro1; |
struct gcpro gcpro1, gcpro2; |
319 |
int success_count = 0; |
int success_count = 0; |
320 |
|
|
321 |
executing_macro_iterations = 0; |
executing_macro_iterations = 0; |
335 |
real_this_command)); |
real_this_command)); |
336 |
record_unwind_protect (pop_kbd_macro, tem); |
record_unwind_protect (pop_kbd_macro, tem); |
337 |
|
|
338 |
GCPRO1 (final); |
GCPRO2 (final, loopfunc); |
339 |
do |
do |
340 |
{ |
{ |
341 |
Vexecuting_macro = final; |
Vexecuting_macro = final; |
343 |
executing_macro_index = 0; |
executing_macro_index = 0; |
344 |
|
|
345 |
current_kboard->Vprefix_arg = Qnil; |
current_kboard->Vprefix_arg = Qnil; |
346 |
|
|
347 |
|
if (!NILP (loopfunc)) |
348 |
|
{ |
349 |
|
Lisp_Object cont; |
350 |
|
cont = call0 (loopfunc); |
351 |
|
if (NILP (cont)) |
352 |
|
break; |
353 |
|
} |
354 |
|
|
355 |
command_loop_1 (); |
command_loop_1 (); |
356 |
|
|
357 |
executing_macro_iterations = ++success_count; |
executing_macro_iterations = ++success_count; |
397 |
DEFVAR_LISP ("executing-macro", &Vexecuting_macro, |
DEFVAR_LISP ("executing-macro", &Vexecuting_macro, |
398 |
doc: /* Currently executing keyboard macro (string or vector); nil if none executing. */); |
doc: /* Currently executing keyboard macro (string or vector); nil if none executing. */); |
399 |
|
|
400 |
|
DEFVAR_INT ("executing-macro-index", &executing_macro_index, |
401 |
|
doc: /* Index in currently executing keyboard macro; undefined if none executing. */); |
402 |
|
|
403 |
DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro, |
DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro, |
404 |
doc: /* Currently executing keyboard macro (string or vector); nil if none executing. */); |
doc: /* Currently executing keyboard macro (string or vector); nil if none executing. */); |
405 |
|
|