|
|
1.1 root 1: /* Keyboard macros.
2: Copyright (C) 1985, 1986 Free Software Foundation, Inc.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU Emacs General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU Emacs, but only under the conditions described in the
15: GNU Emacs General Public License. A copy of this license is
16: supposed to have been given to you along with GNU Emacs so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include "lisp.h"
24: #include "macros.h"
25: #include "commands.h"
26: #include "buffer.h"
27: #include "window.h"
28:
29: int defining_kbd_macro;
30:
31: char *kbd_macro_buffer;
32: char *kbd_macro_ptr;
33: char *kbd_macro_end;
34: int kbd_macro_bufsize;
35: Lisp_Object Vlast_kbd_macro;
36:
37: Lisp_Object Vexecuting_macro;
38: int executing_macro_index;
39:
40: Lisp_Object Fexecute_kbd_macro ();
41:
42: DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P",
43: "Record subsequent keyboard input, defining a keyboard macro.\n\
44: The commands are recorded even as they are executed.\n\
45: Use \\[end-kbd-macro] to finish recording and make the macro available.\n\
46: Use \\[name-last-kbd-macro] to give it a permanent name.\n\
47: Non-nil arg (prefix arg) means append to last macro defined;\n\
48: This begins by re-executing that macro as if you typed it again.")
49: (append)
50: Lisp_Object append;
51: {
52: if (defining_kbd_macro)
53: error ("Already defining kbd macro!");
54: else
55: {
56: defining_kbd_macro++;
57: RedoModes++;
58: if (NULL (append))
59: {
60: kbd_macro_ptr = kbd_macro_buffer;
61: kbd_macro_end = kbd_macro_buffer;
62: message("Defining kbd macro...");
63: }
64: else
65: {
66: message("Appending to kbd macro...");
67: kbd_macro_ptr = kbd_macro_end;
68: Fexecute_kbd_macro (Vlast_kbd_macro, make_number (1));
69: }
70: }
71: return Qnil;
72: }
73:
74: DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p",
75: "Finish defining a keyboard macro.\n\
76: The definition was started by \\[start-kbd-macro].\n\
77: The macro is now available for use via \\[call-last-kbd-macro],\n\
78: or it can be given a name with \\[name-last-kbd-macro] and then invoked\n\
79: under that name.\n\
80: With numeric arg, repeat macro now that many times,\n\
81: counting the definition just completed as the first repetition.")
82: (arg)
83: Lisp_Object arg;
84: {
85: if (!defining_kbd_macro)
86: error ("Not defining kbd macro.");
87:
88: if (NULL (arg))
89: XFASTINT (arg) = 1;
90: else
91: CHECK_NUMBER (arg, 0);
92:
93: if (defining_kbd_macro)
94: {
95: defining_kbd_macro = 0;
96: RedoModes++;
97: Vlast_kbd_macro = make_string (kbd_macro_buffer,
98: kbd_macro_end - kbd_macro_buffer);
99: message("Keyboard macro defined");
100: }
101:
102: if (XFASTINT (arg) == 0)
103: Fexecute_kbd_macro (Vlast_kbd_macro, arg);
104: else
105: {
106: XFASTINT (arg)--;
107: if (XFASTINT (arg) > 0)
108: Fexecute_kbd_macro (Vlast_kbd_macro, arg);
109: }
110: return Qnil;
111: }
112:
113: /* Store character c into kbd macro being defined */
114:
115: store_kbd_macro_char (c)
116: unsigned char c;
117: {
118: if (defining_kbd_macro)
119: {
120: if (kbd_macro_ptr - kbd_macro_buffer == kbd_macro_bufsize)
121: {
122: register char *new = (char *) xrealloc (kbd_macro_buffer, kbd_macro_bufsize *= 2);
123: kbd_macro_ptr += new - kbd_macro_buffer;
124: kbd_macro_end = new + kbd_macro_bufsize;
125: kbd_macro_buffer = new;
126: }
127: *kbd_macro_ptr++ = c;
128: }
129: }
130:
131: /* Declare that all chars stored so far in the kbd macro being defined
132: really belong to it. This is done in between editor commands. */
133:
134: finalize_kbd_macro_chars ()
135: {
136: kbd_macro_end = kbd_macro_ptr;
137: }
138:
139: DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
140: 0, 1, "p",
141: "Call the last keyboard macro that you defined with \\[start-kbd-macro].\n\
142: To make a macro permanent so you can call it even after\n\
143: defining others, use \\[name-last-kbd-macro].")
144: (prefix)
145: Lisp_Object prefix;
146: {
147: if (defining_kbd_macro)
148: error ("Can't execute anonymous macro while defining one");
149: else if (NULL (Vlast_kbd_macro))
150: error ("No kbd macro has been defined");
151: else
152: Fexecute_kbd_macro (Vlast_kbd_macro, prefix);
153: return Qnil;
154: }
155:
156: static Lisp_Object
157: pop_kbd_macro (info)
158: Lisp_Object info;
159: {
160: Lisp_Object tem;
161: Vexecuting_macro = Fcar (info);
162: tem = Fcdr (info);
163: executing_macro_index = XINT (tem);
164: return Qnil;
165: }
166:
167: DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0,
168: "Execute MACRO as string of editor command characters.\n\
169: If MACRO is a symbol, its function definition is used.\n\
170: COUNT is a repeat count, or nil for once, or 0 for infinite loop.")
171: (macro, prefixarg)
172: Lisp_Object macro, prefixarg;
173: {
174: Lisp_Object final;
175: Lisp_Object tem;
176: int count = specpdl_ptr - specpdl;
177: int repeat = 1;
178: struct gcpro gcpro1;
179:
180: if (!NULL (prefixarg))
181: prefixarg = Fprefix_numeric_value (prefixarg),
182: repeat = XINT (prefixarg);
183:
184: final = macro;
185: while (XTYPE (final) == Lisp_Symbol && !EQ (final, Qunbound))
186: final = XSYMBOL (final)->function;
187: CHECK_STRING (final, 0);
188:
189: XFASTINT (tem) = executing_macro_index;
190: tem = Fcons (Vexecuting_macro, tem);
191: record_unwind_protect (pop_kbd_macro, tem);
192:
193: GCPRO1 (final);
194: do
195: {
196: Vexecuting_macro = final;
197: executing_macro_index = 0;
198:
199: command_loop_1 ();
200: }
201: while (--repeat && XTYPE (Vexecuting_macro) == Lisp_String);
202:
203: UNGCPRO;
204: unbind_to (count);
205:
206: return Qnil;
207: }
208:
209: init_macros ()
210: {
211: Vlast_kbd_macro = Qnil;
212: defining_kbd_macro = 0;
213:
214: Vexecuting_macro = Qnil;
215: }
216:
217: syms_of_macros ()
218: {
219: kbd_macro_bufsize = 100;
220: kbd_macro_buffer = (char *) malloc (kbd_macro_bufsize);
221:
222: defsubr (&Sstart_kbd_macro);
223: defsubr (&Send_kbd_macro);
224: defsubr (&Scall_last_kbd_macro);
225: defsubr (&Sexecute_kbd_macro);
226:
227: DEFVAR_BOOL ("defining-kbd-macro", &defining_kbd_macro,
228: "Non-nil means store keyboard input into kbd macro being defined.");
229:
230: DEFVAR_LISP ("executing-macro", &Vexecuting_macro,
231: "Currently executing keyboard macro (a string); nil if none executing.");
232:
233: DEFVAR_LISP ("executing-kbd-macro", &Vexecuting_macro,
234: "Currently executing keyboard macro (a string); nil if none executing.");
235:
236: DEFVAR_LISP ("last-kbd-macro", &Vlast_kbd_macro,
237: "Last kbd macro defined, as a string; nil if none defined.");
238: }
239:
240: keys_of_macros ()
241: {
242: defkey (CtlXmap, ('e'), "call-last-kbd-macro");
243: defkey (CtlXmap, ('('), "start-kbd-macro");
244: defkey (CtlXmap, (')'), "end-kbd-macro");
245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.