428
+ − 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"
800
+ − 33
+ − 34 #include "buffer.h"
428
+ − 35 #include "commands.h"
872
+ − 36 #include "console-impl.h"
800
+ − 37 #include "device.h"
+ − 38 #include "events.h"
428
+ − 39 #include "frame.h"
+ − 40 #include "keymap.h"
800
+ − 41 #include "macros.h"
+ − 42 #include "window.h"
428
+ − 43
+ − 44 Lisp_Object Qexecute_kbd_macro;
+ − 45
+ − 46 /* The current macro and our position in it. When executing nested kbd
+ − 47 macros, previous values for these are wound through the execution stack
+ − 48 with unwind-protect.
+ − 49 */
+ − 50 Lisp_Object Vexecuting_macro;
+ − 51 int executing_macro_index;
+ − 52
+ − 53
+ − 54 DEFUN ("start-kbd-macro", Fstart_kbd_macro, 1, 1, "P", /*
+ − 55 Record subsequent keyboard and menu input, defining a keyboard macro.
+ − 56 The commands are recorded even as they are executed.
+ − 57 Use \\[end-kbd-macro] to finish recording and make the macro available.
+ − 58 Use \\[name-last-kbd-macro] to give it a permanent name.
+ − 59 Non-nil arg (prefix arg) means append to last macro defined;
+ − 60 This begins by re-executing that macro as if you typed it again.
+ − 61 */
+ − 62 (append))
+ − 63 {
+ − 64 /* This function can GC */
+ − 65 struct console *con = XCONSOLE (Vselected_console);
+ − 66 if (!NILP (con->defining_kbd_macro))
563
+ − 67 invalid_operation ("Already defining kbd macro", Qunbound);
428
+ − 68
+ − 69 if (NILP (con->kbd_macro_builder))
+ − 70 con->kbd_macro_builder = make_vector (30, Qnil);
+ − 71
+ − 72 zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
+ − 73 so that functions there can override */
+ − 74 MARK_MODELINE_CHANGED;
+ − 75 if (NILP (append))
+ − 76 {
+ − 77 con->kbd_macro_ptr = 0;
+ − 78 con->kbd_macro_end = 0;
+ − 79 message ("Defining kbd macro...");
+ − 80 }
+ − 81 else
+ − 82 {
+ − 83 message ("Appending to kbd macro...");
+ − 84 con->kbd_macro_ptr = con->kbd_macro_end;
+ − 85 Fexecute_kbd_macro (con->last_kbd_macro, make_int (1));
+ − 86 }
+ − 87 con->defining_kbd_macro = Qt;
+ − 88
+ − 89 return Qnil;
+ − 90 }
+ − 91
+ − 92 DEFUN ("end-kbd-macro", Fend_kbd_macro, 0, 1, "P", /*
+ − 93 Finish defining a keyboard macro.
+ − 94 The definition was started by \\[start-kbd-macro].
+ − 95 The macro is now available for use via \\[call-last-kbd-macro],
+ − 96 or it can be given a name with \\[name-last-kbd-macro] and then invoked
+ − 97 under that name.
+ − 98
+ − 99 With numeric arg, repeat macro now that many times,
+ − 100 counting the definition just completed as the first repetition.
+ − 101 An argument of zero means repeat until error.
+ − 102 */
+ − 103 (arg))
+ − 104 {
+ − 105 /* This function can GC */
+ − 106 struct console *con = XCONSOLE (Vselected_console);
+ − 107 int repeat;
+ − 108
+ − 109 if (NILP (con->defining_kbd_macro))
563
+ − 110 invalid_operation ("Not defining kbd macro", Qunbound);
428
+ − 111
+ − 112 if (NILP (arg))
+ − 113 repeat = -1;
+ − 114 else
+ − 115 repeat = XINT (Fprefix_numeric_value (arg));
+ − 116
+ − 117 if (!NILP (con->defining_kbd_macro))
+ − 118 {
+ − 119 int i;
+ − 120 int size = con->kbd_macro_end;
+ − 121
+ − 122 if (size < 0)
+ − 123 size = 0;
+ − 124 con->last_kbd_macro = make_vector (size, Qnil);
+ − 125 for (i = 0; i < size; i++)
+ − 126 XVECTOR_DATA (con->last_kbd_macro) [i] =
+ − 127 XVECTOR_DATA (con->kbd_macro_builder) [i];
+ − 128 con->defining_kbd_macro = Qnil;
+ − 129 MARK_MODELINE_CHANGED;
+ − 130 message ("Keyboard macro defined");
+ − 131 }
+ − 132
+ − 133 zmacs_region_stays = 1; /* set this before calling Fexecute_kbd_macro()
+ − 134 so that functions there can override */
+ − 135 if (repeat < 0)
+ − 136 return Qnil;
+ − 137 else if (repeat == 0)
+ − 138 return Fexecute_kbd_macro (con->last_kbd_macro, Qzero);
+ − 139 else
+ − 140 return Fexecute_kbd_macro (con->last_kbd_macro,
+ − 141 make_int (repeat - 1));
+ − 142 }
+ − 143
+ − 144 /* #### Read the comment in modeline.el to see why this ugliness is
+ − 145 needed. #### Try to avoid it, somehow! */
+ − 146 DEFUN ("zap-last-kbd-macro-event", Fzap_last_kbd_macro_event, 0, 0, 0, /*
+ − 147 Don't look at this lest you vomit or spontaneously combust.
+ − 148 */
+ − 149 ())
+ − 150 {
+ − 151 struct console *con = XCONSOLE (Vselected_console);
+ − 152 if (con->kbd_macro_end)
+ − 153 --con->kbd_macro_end;
+ − 154 return Qnil;
+ − 155 }
+ − 156
+ − 157 /* Store event into kbd macro being defined
+ − 158 */
+ − 159 void
+ − 160 store_kbd_macro_event (Lisp_Object event)
+ − 161 {
+ − 162 struct console *con = event_console_or_selected (event);
+ − 163
+ − 164 if (con->kbd_macro_ptr == XVECTOR_LENGTH (con->kbd_macro_builder))
+ − 165 {
+ − 166 int i;
+ − 167 int old_size = XVECTOR_LENGTH (con->kbd_macro_builder);
+ − 168 int new_size = old_size * 2;
3025
+ − 169 Lisp_Object new_ = make_vector (new_size, Qnil);
428
+ − 170 for (i = 0; i < old_size; i++)
3025
+ − 171 XVECTOR_DATA (new_) [i] = XVECTOR_DATA (con->kbd_macro_builder) [i];
+ − 172 con->kbd_macro_builder = new_;
428
+ − 173 }
+ − 174 XVECTOR_DATA (con->kbd_macro_builder) [con->kbd_macro_ptr++] =
+ − 175 Fcopy_event (event, Qnil);
+ − 176 }
+ − 177
+ − 178 /* Extract the next kbd-macro element into the given event.
+ − 179 If we're done, throws to the catch in Fexecute_kbd_macro().
+ − 180 */
+ − 181 void
+ − 182 pop_kbd_macro_event (Lisp_Object event)
+ − 183 {
2500
+ − 184 if (NILP (Vexecuting_macro)) ABORT ();
428
+ − 185
+ − 186 if (STRINGP (Vexecuting_macro) || VECTORP (Vexecuting_macro))
+ − 187 {
+ − 188 if (executing_macro_index < XINT (Flength (Vexecuting_macro)))
+ − 189 {
+ − 190 nth_of_key_sequence_as_event (Vexecuting_macro,
+ − 191 executing_macro_index++,
+ − 192 event);
+ − 193 return;
+ − 194 }
+ − 195 }
+ − 196 else if (!EQ (Vexecuting_macro, Qt)) /* Some things replace the macro
+ − 197 with Qt to force an early exit. */
563
+ − 198 signal_error (Qinvalid_state, "junk in executing-macro", Qunbound);
428
+ − 199
+ − 200 Fthrow (Qexecute_kbd_macro, Qt);
+ − 201 }
+ − 202
+ − 203
+ − 204 /* Declare that all chars stored so far in the kbd macro being defined
+ − 205 really belong to it. This is done in between editor commands. */
+ − 206
+ − 207 void
+ − 208 finalize_kbd_macro_chars (struct console *con)
+ − 209 {
+ − 210 con->kbd_macro_end = con->kbd_macro_ptr;
+ − 211 }
+ − 212
+ − 213 DEFUN ("cancel-kbd-macro-events", Fcancel_kbd_macro_events, 0, 0, 0, /*
+ − 214 Cancel the events added to a keyboard macro for this command.
+ − 215 */
+ − 216 ())
+ − 217 {
+ − 218 struct console *con = XCONSOLE (Vselected_console);
+ − 219
+ − 220 con->kbd_macro_ptr = con->kbd_macro_end;
+ − 221
+ − 222 return Qnil;
+ − 223 }
+ − 224
+ − 225 DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, 0, 1, "p", /*
+ − 226 Call the last keyboard macro that you defined with \\[start-kbd-macro].
+ − 227
+ − 228 A prefix argument serves as a repeat count. Zero means repeat until error.
+ − 229
+ − 230 To make a macro permanent so you can call it even after
+ − 231 defining others, use \\[name-last-kbd-macro].
+ − 232 */
+ − 233 (prefix))
+ − 234 {
+ − 235 /* This function can GC */
+ − 236 struct console *con = XCONSOLE (Vselected_console);
+ − 237
+ − 238 if (!NILP (con->defining_kbd_macro))
563
+ − 239 invalid_operation ("Can't execute anonymous macro while defining one", Qunbound);
428
+ − 240 else if (NILP (con->last_kbd_macro))
563
+ − 241 invalid_operation ("No kbd macro has been defined", Qunbound);
428
+ − 242 else
+ − 243 Fexecute_kbd_macro (con->last_kbd_macro, prefix);
+ − 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 */
444
+ − 252 (macro, count))
428
+ − 253 {
+ − 254 /* This function can GC */
+ − 255 Lisp_Object final;
+ − 256 int speccount = specpdl_depth ();
+ − 257 int repeat = 1;
+ − 258 struct gcpro gcpro1;
+ − 259 struct console *con = XCONSOLE (Vselected_console);
+ − 260
444
+ − 261 if (!NILP (count))
428
+ − 262 {
444
+ − 263 count = Fprefix_numeric_value (count);
+ − 264 repeat = XINT (count);
428
+ − 265 }
+ − 266
+ − 267 final = indirect_function (macro, 1);
+ − 268 if (!STRINGP (final) && !VECTORP (final))
563
+ − 269 invalid_argument ("Keyboard macros must be strings or vectors", Qunbound);
428
+ − 270
853
+ − 271 internal_bind_lisp_object (&Vexecuting_macro, Vexecuting_macro);
+ − 272 internal_bind_int (&executing_macro_index, executing_macro_index);
428
+ − 273
+ − 274 GCPRO1 (final);
+ − 275 do
+ − 276 {
+ − 277 Vexecuting_macro = final;
+ − 278 executing_macro_index = 0;
+ − 279 con->prefix_arg = Qnil;
+ − 280 internal_catch (Qexecute_kbd_macro, call_command_loop,
2532
+ − 281 Qnil, 0, 0, 0);
428
+ − 282 }
+ − 283 while (--repeat != 0
+ − 284 && (STRINGP (Vexecuting_macro) ||
+ − 285 VECTORP (Vexecuting_macro)));
+ − 286
+ − 287 UNGCPRO;
771
+ − 288 return unbind_to (speccount);
428
+ − 289 }
+ − 290
+ − 291
+ − 292 void
+ − 293 syms_of_macros (void)
+ − 294 {
+ − 295 DEFSUBR (Fstart_kbd_macro);
+ − 296 DEFSUBR (Fend_kbd_macro);
+ − 297 DEFSUBR (Fzap_last_kbd_macro_event);
+ − 298 DEFSUBR (Fcall_last_kbd_macro);
+ − 299 DEFSUBR (Fexecute_kbd_macro);
+ − 300 DEFSUBR (Fcancel_kbd_macro_events);
563
+ − 301 DEFSYMBOL (Qexecute_kbd_macro);
428
+ − 302 }
+ − 303
+ − 304 void
+ − 305 vars_of_macros (void)
+ − 306 {
+ − 307 DEFVAR_LISP ("executing-macro", &Vexecuting_macro /*
+ − 308 Currently executing keyboard macro (a vector of events or string);
+ − 309 nil if none executing.
+ − 310 */ );
+ − 311
+ − 312 DEFVAR_LISP ("executing-kbd-macro", &Vexecuting_macro /*
+ − 313 Currently executing keyboard macro (a vector of events or string);
+ − 314 nil if none executing.
+ − 315 */ );
+ − 316 }
+ − 317
+ − 318 void
+ − 319 init_macros (void)
+ − 320 {
+ − 321 Vexecuting_macro = Qnil;
+ − 322 }
+ − 323