Annotation of 43BSD/contrib/emacs/src/macros.c, revision 1.1

1.1     ! root        1: /* Keyboard macros.
        !             2:    Copyright (C) 1985 Richard M. Stallman.
        !             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: DEFUN ("name-last-kbd-macro", Fname_last_kbd_macro, Sname_last_kbd_macro, 1, 1, "SName last kbd macro: ",
        !           210:   "Assign a name to the last keyboard macro defined.\n\
        !           211: One arg, a symbol, which is the name to define.\n\
        !           212: The symbol's function definition becomes the keyboard macro string.\n\
        !           213: Such a \"function\" cannot be called from Lisp, but it is a valid command\n\
        !           214: definition for the editor command loop.")
        !           215:   (sym)
        !           216:      Lisp_Object sym;
        !           217: {
        !           218:   CHECK_SYMBOL (sym, 0);
        !           219: 
        !           220:   if (defining_kbd_macro)
        !           221:     error ("Not allowed to name a keyboard macro while defining one");
        !           222: 
        !           223:   if (NULL (Vlast_kbd_macro))
        !           224:     error ("No keyboard macro defined");
        !           225: 
        !           226:   Ffset (sym, Vlast_kbd_macro);
        !           227:   return sym;
        !           228: }
        !           229: 
        !           230: init_macros ()
        !           231: {
        !           232:   Vlast_kbd_macro = Qnil;
        !           233:   defining_kbd_macro = 0;
        !           234: 
        !           235:   Vexecuting_macro = Qnil;
        !           236: }
        !           237: 
        !           238: syms_of_macros ()
        !           239: {
        !           240:   kbd_macro_bufsize = 100;
        !           241:   kbd_macro_buffer = (char *) malloc (kbd_macro_bufsize);
        !           242: 
        !           243:   defsubr (&Sstart_kbd_macro);
        !           244:   defsubr (&Send_kbd_macro);
        !           245:   defsubr (&Scall_last_kbd_macro);
        !           246:   defsubr (&Sexecute_kbd_macro);
        !           247:   defsubr (&Sname_last_kbd_macro);
        !           248: 
        !           249:   DefBoolVar ("defining-kbd-macro", &defining_kbd_macro,
        !           250:     "Non-nil means store keyboard input into kbd macro being defined.");
        !           251: 
        !           252:   DefLispVar ("executing-macro", &Vexecuting_macro,
        !           253:     "Currently executing keyboard macro (a string); nil if none executing.");
        !           254: 
        !           255:   DefLispVar ("executing-kbd-macro", &Vexecuting_macro,
        !           256:     "Currently executing keyboard macro (a string); nil if none executing.");
        !           257: 
        !           258:   DefLispVar ("last-kbd-macro", &Vlast_kbd_macro,
        !           259:     "Last kbd macro defined, as a string; nil if none defined.");
        !           260: }
        !           261: 
        !           262: keys_of_macros ()
        !           263: {
        !           264:   defkey (CtlXmap, ('e'), "call-last-kbd-macro");
        !           265:   defkey (CtlXmap, ('('), "start-kbd-macro");
        !           266:   defkey (CtlXmap, (')'), "end-kbd-macro");
        !           267: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.