(pages-copy-header-and-position): Call end-of-line, not forward-line.
[bpt/emacs.git] / lisp / macros.el
index 4cd6a34..1e093a7 100644 (file)
@@ -1,12 +1,15 @@
 ;;; macros.el --- non-primitive commands for keyboard macros.
 
-;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: abbrev
 
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 1, or (at your option)
+;; the Free Software Foundation; either version 2, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; along with GNU Emacs; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
+;;; Commentary:
+
+;; Extension commands for keyboard macros.  These permit you to assign
+;; a name to the last-defined keyboard macro, expand and insert the
+;; lisp corresponding to a macro, query the user from within a macro,
+;; or apply a macro to each line in the reason.
+
+;;; Code:
 
 ;;;###autoload
 (defun name-last-kbd-macro (symbol)
@@ -30,6 +41,7 @@ Such a \"function\" cannot be called from Lisp, but it is a valid editor command
       (error "No keyboard macro defined"))
   (and (fboundp symbol)
        (not (stringp (symbol-function symbol)))
+       (not (vectorp (symbol-function symbol)))
        (error "Function %s is already defined and not a keyboard macro."
              symbol))
   (fset symbol last-kbd-macro))
@@ -38,7 +50,7 @@ Such a \"function\" cannot be called from Lisp, but it is a valid editor command
 (defun insert-kbd-macro (macroname &optional keys)
   "Insert in buffer the definition of kbd macro NAME, as Lisp code.
 Optional second arg KEYS means also record the keys it is on
-(this is the prefix argument, when calling interactively).
+\(this is the prefix argument, when calling interactively).
 
 This Lisp code will, when executed, define the kbd macro with the same
 definition it has now.  If you say to record the keys, the Lisp code
@@ -46,23 +58,51 @@ will also rebind those keys to the macro.  Only global key bindings
 are recorded since executing this Lisp code always makes global
 bindings.
 
-To save a kbd macro, visit a file of Lisp code such as your ~/.emacs,
+To save a kbd macro, visit a file of Lisp code such as your `~/.emacs',
 use this command, and then save the file."
   (interactive "CInsert kbd macro (name): \nP")
-  (insert "(fset '")
-  (prin1 macroname (current-buffer))
-  (insert "\n   ")
-  (prin1 (symbol-function macroname) (current-buffer))
-  (insert ")\n")
-  (if keys
-      (let ((keys (where-is-internal macroname nil)))
-       (while keys
-         (insert "(global-set-key ")
-         (prin1 (car keys) (current-buffer))
-         (insert " '")
-         (prin1 macroname (current-buffer))
-         (insert ")\n")
-         (setq keys (cdr keys))))))
+  (let (definition)
+    (if (string= (symbol-name macroname) "")
+       (progn
+         (setq macroname 'last-kbd-macro definition last-kbd-macro)
+         (insert "(setq "))
+      (setq definition (symbol-function macroname))
+      (insert "(fset '"))
+    (prin1 macroname (current-buffer))
+    (insert "\n   ")
+    (let ((beg (point)) end)
+      (prin1 definition (current-buffer))
+      (setq end (point-marker))
+      (goto-char beg)
+      (while (< (point) end)
+       (let ((char (following-char)))
+         (cond ((< char 32)
+                (delete-region (point) (1+ (point)))
+                (insert "\\C-" (+ 96 char)))
+               ((< char 127)
+                (forward-char 1))
+               ((= char 127)
+                (delete-region (point) (1+ (point)))
+                (insert "\\C-?"))
+               ((< char 160)
+                (delete-region (point) (1+ (point)))
+                (insert "\\M-C-" (- char 32)))
+               ((< char 255)
+                (delete-region (point) (1+ (point)))
+                (insert "\\M-" (- char 128)))
+               ((= char 255)
+                (delete-region (point) (1+ (point)))
+                (insert "\\M-C-?"))))))
+    (insert ")\n")
+    (if keys
+       (let ((keys (where-is-internal macroname nil)))
+         (while keys
+           (insert "(global-set-key ")
+           (prin1 (car keys) (current-buffer))
+           (insert " '")
+           (prin1 macroname (current-buffer))
+           (insert ")\n")
+           (setq keys (cdr keys)))))))
 
 ;;;###autoload
 (defun kbd-macro-query (flag)
@@ -70,12 +110,13 @@ use this command, and then save the file."
   With prefix argument, enters recursive edit, reading keyboard
 commands even within a kbd macro.  You can give different commands
 each time the macro executes.
-  Without prefix argument, reads a character.  Your options are:
-Space -- execute the rest of the macro.
-DEL -- skip the rest of the macro; start next repetition.
-C-d -- skip rest of the macro and don't repeat it any more.
-C-r -- enter a recursive edit, then on exit ask again for a character
-C-l -- redisplay screen and ask again."
+  Without prefix argument, asks whether to continue running the macro.
+Your options are: \\<query-replace-map>
+\\[act]        Finish this iteration normally and continue with the next.
+\\[skip]       Skip the rest of this iteration, and start the next.
+\\[exit]       Stop the macro entirely right now.
+\\[recenter]   Redisplay the screen, then ask again.
+\\[edit]       Enter recursive edit; ask again when you exit from that."
   (interactive "P")
   (or executing-macro
       defining-kbd-macro
@@ -85,25 +126,47 @@ C-l -- redisplay screen and ask again."
        (recursive-edit))
     (if (not executing-macro)
        nil
-      (let ((loop t))
+      (let ((loop t)
+           (msg (substitute-command-keys
+                 "Proceed with macro?\\<query-replace-map>\
+ (\\[act], \\[skip], \\[exit], \\[recenter], \\[edit]) ")))
        (while loop
-         (let ((char (let ((executing-macro nil)
-                           (defining-kbd-macro nil))
-                       (message "Proceed with macro? (Space, DEL, C-d, C-r or C-l) ")
-                       (read-char))))
-           (cond ((= char ? )
+         (let ((key (let ((executing-macro nil)
+                          (defining-kbd-macro nil))
+                      (message msg)
+                      (read-event)))
+               def)
+           (setq key (vector key))
+           (setq def (lookup-key query-replace-map key))
+           (cond ((eq def 'act)
                   (setq loop nil))
-                 ((= char ?\177)
+                 ((eq def 'skip)
                   (setq loop nil)
                   (setq executing-macro ""))
-                 ((= char ?\C-d)
+                 ((eq def 'exit)
                   (setq loop nil)
                   (setq executing-macro t))
-                 ((= char ?\C-l)
+                 ((eq def 'recenter)
                   (recenter nil))
-                 ((= char ?\C-r)
+                 ((eq def 'edit)
                   (let (executing-macro defining-kbd-macro)
-                    (recursive-edit))))))))))
+                    (recursive-edit)))
+                 ((eq def 'quit)
+                  (setq quit-flag t))
+                 (t
+                  (or (eq def 'help)
+                      (ding))
+                  (with-output-to-temp-buffer "*Help*"
+                    (princ
+                     (substitute-command-keys
+                      "Specify how to proceed with keyboard macro execution.
+Possibilities: \\<query-replace-map>
+\\[act]        Finish this iteration normally and continue with the next.
+\\[skip]       Skip the rest of this iteration, and start the next.
+\\[exit]       Stop the macro entirely right now.
+\\[recenter]   Redisplay the screen, then ask again.
+\\[edit]       Enter recursive edit; ask again when you exit from that."))))
+                 )))))))
 
 ;;;###autoload
 (defun apply-macro-to-region-lines (top bottom &optional macro)
@@ -172,7 +235,6 @@ and then select the region of un-tablified names and use
       (set-marker end-marker nil)
       (set-marker next-line-marker nil))))
 
-;;;###autoload
-(define-key ctl-x-map "q" 'kbd-macro-query)
+;;;###autoload (define-key ctl-x-map "q" 'kbd-macro-query)
 
 ;;; macros.el ends here