]> code.delx.au - gnu-emacs/blobdiff - lisp/kmacro.el
(normal-splash-screen, fancy-splash-screens-1): Add a reference to the Lisp
[gnu-emacs] / lisp / kmacro.el
index 054fbbdb678b6df7f27f6db7a715201140f8f999..4566d4c32c32c4cb0c7db36d8e315a73bca1f542 100644 (file)
@@ -1,6 +1,6 @@
 ;;; kmacro.el --- enhanced keyboard macros
 
-;; Copyright (C) 2002  Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Kim F. Storm <storm@cua.dk>
 ;; Keywords: keyboard convenience
@@ -19,8 +19,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
   "Simplified keyboard macro user interface."
   :group 'keyboard
   :group 'convenience
+  :version "22.1"
   :link '(emacs-commentary-link :tag "Commentary" "kmacro.el")
   :link '(emacs-library-link :tag "Lisp File" "kmacro.el"))
 
@@ -204,7 +205,7 @@ macro to be executed before appending to it."
 
     ;; naming and binding
     (define-key map "b"    'kmacro-bind-to-key)
-    (define-key map "n"    'name-last-kbd-macro)
+    (define-key map "n"    'kmacro-name-last-macro)
     map)
   "Keymap for keyboard macro commands.")
 (defalias 'kmacro-keymap kmacro-keymap)
@@ -222,12 +223,22 @@ macro to be executed before appending to it."
   (global-set-key (vector kmacro-call-mouse-event) 'kmacro-end-call-mouse))
 
 
+;;; Called from keyboard-quit
+
+(defun kmacro-keyboard-quit ()
+  (or (not defining-kbd-macro)
+      (eq defining-kbd-macro 'append)
+      (kmacro-ring-empty-p)
+      (kmacro-pop-ring)))
+
 
 ;;; Keyboard macro counter
 
 (defvar kmacro-counter 0
   "*Current keyboard macro counter.")
 
+(defvar kmacro-default-counter-format "%d")
+
 (defvar kmacro-counter-format "%d"
   "*Current keyboard macro counter format.")
 
@@ -248,7 +259,9 @@ macro to be executed before appending to it."
   "Insert macro counter and increment with ARG or 1 if missing.
 With \\[universal-argument], insert previous kmacro-counter (but do not modify counter)."
   (interactive "P")
-  (setq kmacro-initial-counter-value nil)
+  (if kmacro-initial-counter-value
+      (setq kmacro-counter kmacro-initial-counter-value
+           kmacro-initial-counter-value nil))
   (if (and arg (listp arg))
       (insert (format kmacro-counter-format kmacro-last-counter))
     (insert (format kmacro-counter-format kmacro-counter))
@@ -257,12 +270,12 @@ With \\[universal-argument], insert previous kmacro-counter (but do not modify c
 
 (defun kmacro-set-format (format)
   "Set macro counter FORMAT."
-  (interactive "sMacro Counter Format (printf format): ")
+  (interactive "sMacro Counter Format: ")
   (setq kmacro-counter-format
        (if (equal format "") "%d" format))
   ;; redefine initial macro counter if we are not executing a macro.
   (if (not (or defining-kbd-macro executing-kbd-macro))
-      (setq kmacro-counter-format-start kmacro-counter-format)))
+      (setq kmacro-default-counter-format kmacro-counter-format)))
 
 
 (defun kmacro-display-counter (&optional value)
@@ -275,23 +288,23 @@ With \\[universal-argument], insert previous kmacro-counter (but do not modify c
   "Set kmacro-counter to ARG or prompt if missing.
 With \\[universal-argument] prefix, reset counter to its value prior to this iteration of the macro."
   (interactive "NMacro counter value: ")
-  (setq kmacro-last-counter kmacro-counter
-       kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
-                          kmacro-counter-value-start
-                        arg))
-  ;; setup initial macro counter value if we are not executing a macro.
-  (setq kmacro-initial-counter-value
-       (and (not (or defining-kbd-macro executing-kbd-macro))
-            kmacro-counter))
-  (unless executing-kbd-macro
-    (kmacro-display-counter)))
+  (if (not (or defining-kbd-macro executing-kbd-macro))
+      (kmacro-display-counter (setq kmacro-initial-counter-value arg))
+    (setq kmacro-last-counter kmacro-counter
+         kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
+                            kmacro-counter-value-start
+                          arg))
+    (unless executing-kbd-macro
+      (kmacro-display-counter))))
 
 
 (defun kmacro-add-counter (arg)
   "Add numeric prefix arg (prompt if missing) to macro counter.
 With \\[universal-argument], restore previous counter value."
   (interactive "NAdd to macro counter: ")
-  (setq kmacro-initial-counter-value nil)
+  (if kmacro-initial-counter-value
+      (setq kmacro-counter kmacro-initial-counter-value
+           kmacro-initial-counter-value nil))
   (let ((last kmacro-last-counter))
     (setq kmacro-last-counter kmacro-counter
          kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
@@ -393,9 +406,12 @@ Optional arg EMPTY is message to print if no macros are defined."
       (let* ((x 60)
             (m (format-kbd-macro macro))
             (l (length m))
-            (z (and nil trunc (> l x))))
-       (message (format "%s: %s%s" (or descr "Macro")
-                        (if z (substring m 0 (1- x)) m) (if z "..." ""))))
+            (z (and trunc (> l x))))
+       (message "%s%s: %s%s" (or descr "Macro")
+                (if (= kmacro-counter 0) ""
+                  (format " [%s]"
+                          (format kmacro-counter-format-start kmacro-counter)))
+                (if z (substring m 0 (1- x)) m) (if z "..." "")))
     (message (or empty "No keyboard macros defined"))))
 
 
@@ -539,8 +555,8 @@ Displays the selected macro in the echo area."
 The commands are recorded even as they are executed.
 Use \\[kmacro-end-macro] to finish recording and make the macro available.
 Use \\[kmacro-end-and-call-macro] to execute the macro.
-Use \\[name-last-kbd-macro] to give it a permanent name.
-Non-nil arg (prefix arg) means append to last macro defined;
+
+Non-nil arg (prefix arg) means append to last macro defined.
 
 With \\[universal-argument] prefix, append to last keyboard macro
 defined.  Depending on `kmacro-execute-before-append', this may begin
@@ -551,7 +567,10 @@ defining the macro.
 
 Use \\[kmacro-insert-counter] to insert (and increment) the macro counter.
 The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter].
-The format of the counter can be modified via \\[kmacro-set-format]."
+The format of the counter can be modified via \\[kmacro-set-format].
+
+Use \\[kmacro-name-last-macro] to give it a permanent name.
+Use \\[kmacro-bind-to-key] to bind it to a key sequence."
   (interactive "P")
   (if (or defining-kbd-macro executing-kbd-macro)
       (message "Already defining keyboard macro.")
@@ -571,13 +590,16 @@ The format of the counter can be modified via \\[kmacro-set-format]."
              kmacro-initial-counter-value nil
              kmacro-counter-value-start kmacro-counter
              kmacro-last-counter kmacro-counter
-             kmacro-counter-format-start kmacro-counter-format))
+             kmacro-counter-format kmacro-default-counter-format
+             kmacro-counter-format-start kmacro-default-counter-format))
 
       (start-kbd-macro append
                       (and append
                            (if kmacro-execute-before-append
                                (> (car arg) 4)
-                             (= (car arg) 4)))))))
+                             (= (car arg) 4))))
+      (if (and defining-kbd-macro append)
+         (setq defining-kbd-macro 'append)))))
 
 
 ;;;###autoload
@@ -585,17 +607,20 @@ The format of the counter can be modified via \\[kmacro-set-format]."
   "Finish defining a keyboard macro.
 The definition was started by \\[kmacro-start-macro].
 The macro is now available for use via \\[kmacro-call-macro],
-or it can be given a name with \\[name-last-kbd-macro] and then invoked
+or it can be given a name with \\[kmacro-name-last-macro] and then invoked
 under that name.
 
 With numeric arg, repeat macro now that many times,
 counting the definition just completed as the first repetition.
 An argument of zero means repeat until error."
   (interactive "P")
-  (end-kbd-macro arg #'kmacro-loop-setup-function)
-  (when (and last-kbd-macro (= (length last-kbd-macro) 0))
-    (message "Ignore empty macro")
-    (kmacro-pop-ring)))
+   ;; Isearch may push the kmacro-end-macro key sequence onto the macro.
+   ;; Just ignore it when executing the macro.
+  (unless executing-kbd-macro
+    (end-kbd-macro arg #'kmacro-loop-setup-function)
+    (when (and last-kbd-macro (= (length last-kbd-macro) 0))
+      (message "Ignore empty macro")
+      (kmacro-pop-ring))))
 
 
 ;;;###autoload
@@ -606,10 +631,10 @@ A prefix argument serves as a repeat count.  Zero means repeat until error.
 When you call the macro, you can call the macro again by repeating
 just the last key in the key sequence that you used to call this
 command.  See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg'
-for details on how to adjust or disable this behaviour.
+for details on how to adjust or disable this behavior.
 
 To make a macro permanent so you can call it even after defining
-others, use M-x name-last-kbd-macro."
+others, use \\[kmacro-name-last-macro]."
   (interactive "p")
   (let ((repeat-key (and (null no-repeat)
                         (> (length (this-single-command-keys)) 1)
@@ -707,7 +732,7 @@ With numeric prefix ARG, repeat macro that many times.
 Zero argument means repeat until there is an error.
 
 To give a macro a permanent name, so you can call it
-even after defining other macros, use \\[name-last-kbd-macro]."
+even after defining other macros, use \\[kmacro-name-last-macro]."
   (interactive "P")
   (if defining-kbd-macro
       (kmacro-end-macro nil))
@@ -737,6 +762,30 @@ If kbd macro currently being defined end it before activating it."
 ;; letters and digits, provided that we inhibit the keymap while
 ;; executing the macro later on (but that's controversial...)
 
+(defun kmacro-lambda-form (mac &optional counter format)
+  "Create lambda form for macro bound to symbol or key."
+  (if counter
+      (setq mac (list mac counter format)))
+  `(lambda (&optional arg)
+     "Keyboard macro."
+     (interactive "p")
+     (kmacro-exec-ring-item ',mac arg)))
+
+(defun kmacro-extract-lambda (mac)
+  "Extract kmacro from a kmacro lambda form."
+  (and (consp mac)
+       (eq (car mac) 'lambda)
+       (setq mac (assoc 'kmacro-exec-ring-item mac))
+       (consp (cdr mac))
+       (consp (car (cdr mac)))
+       (consp (cdr (car (cdr mac))))
+       (setq mac (car (cdr (car (cdr mac)))))
+       (listp mac)
+       (= (length mac) 3)
+       (arrayp (car mac))
+       mac))
+
+
 (defun kmacro-bind-to-key (arg)
   "When not defining or executing a macro, offer to bind last macro to a key.
 The key sequences [C-x C-k 0] through [C-x C-k 9] and [C-x C-k A]
@@ -771,10 +820,31 @@ may be shaded by a local key binding."
                     (yes-or-no-p (format "%s runs command %S.  Bind anyway? "
                                          (format-kbd-macro key-seq)
                                          cmd))))
-       (define-key global-map key-seq last-kbd-macro)
+       (define-key global-map key-seq
+         (kmacro-lambda-form (kmacro-ring-head)))
        (message "Keyboard macro bound to %s" (format-kbd-macro key-seq))))))
 
 
+(defun kmacro-name-last-macro (symbol)
+  "Assign a name to the last keyboard macro defined.
+Argument SYMBOL is the name to define.
+The symbol's function definition becomes the keyboard macro string.
+Such a \"function\" cannot be called from Lisp, but it is a valid editor command."
+  (interactive "SName for last kbd macro: ")
+  (or last-kbd-macro
+      (error "No keyboard macro defined"))
+  (and (fboundp symbol)
+       (not (get symbol 'kmacro))
+       (not (stringp (symbol-function symbol)))
+       (not (vectorp (symbol-function symbol)))
+       (error "Function %s is already defined and not a keyboard macro"
+             symbol))
+  (if (string-equal symbol "")
+      (error "No command name given"))
+  (fset symbol (kmacro-lambda-form (kmacro-ring-head)))
+  (put symbol 'kmacro t))
+
+
 (defun kmacro-view-macro (&optional arg)
   "Display the last keyboard macro.
 If repeated, it shows previous elements in the macro ring."
@@ -890,14 +960,15 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
 (defun kmacro-step-edit-prompt (macro index)
   ;; Show step-edit prompt
   (let ((keys (and (not kmacro-step-edit-appending)
-                  index (substring macro index executing-macro-index)))
+                  index (substring macro index executing-kbd-macro-index)))
        (future (and (not kmacro-step-edit-appending)
-                    (substring macro executing-macro-index)))
+                    (substring macro executing-kbd-macro-index)))
        (message-log-max nil)
        (curmsg (current-message)))
 
     ;; TODO: Scroll macro if max-mini-window-height is too small.
-    (message (concat
+    (message "%s"
+            (concat
              (format "Macro: %s%s%s%s%s\n"
                      (format-kbd-macro kmacro-step-edit-new-macro 1)
                      (if (and kmacro-step-edit-new-macro (> (length kmacro-step-edit-new-macro) 0)) " " "")
@@ -949,12 +1020,12 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
           (not (eq kmacro-step-edit-action t)))
       ;; Find the actual end of this key sequence.
       ;; Must be able to backtrack in case we actually execute it.
-      (setq restore-index executing-macro-index)
+      (setq restore-index executing-kbd-macro-index)
       (let (unread-command-events)
        (quoted-insert 0)
        (when unread-command-events
-         (setq executing-macro-index (- executing-macro-index (length unread-command-events))
-               next-index executing-macro-index)))))
+         (setq executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events))
+               next-index executing-kbd-macro-index)))))
 
     ;; Query the user; stop macro exection temporarily
     (let ((macro executing-kbd-macro)
@@ -974,7 +1045,7 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
            (when unread-command-events
              (setq kmacro-step-edit-new-macro
                    (substring kmacro-step-edit-new-macro 0 (- (length unread-command-events)))
-                   executing-macro-index (- executing-macro-index (length unread-command-events)))))
+                   executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events)))))
          (setq current-prefix-arg nil
                prefix-arg nil)
          (setq act 'ignore))
@@ -1028,24 +1099,24 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
        (setq act t)
        t)
        ((member act '(insert-1 insert))
-       (setq executing-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+       (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
        (setq kmacro-step-edit-inserting (if (eq act 'insert-1) 1 t))
        nil)
        ((member act '(replace-1 replace))
        (setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t))
        (setq kmacro-step-edit-prefix-index nil)
-       (if (= executing-macro-index (length executing-kbd-macro))
+       (if (= executing-kbd-macro-index (length executing-kbd-macro))
            (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
                  kmacro-step-edit-appending t))
        nil)
        ((eq act 'append)
        (setq kmacro-step-edit-inserting t)
-       (if (= executing-macro-index (length executing-kbd-macro))
+       (if (= executing-kbd-macro-index (length executing-kbd-macro))
            (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
                  kmacro-step-edit-appending t))
        t)
        ((eq act 'append-end)
-       (if (= executing-macro-index (length executing-kbd-macro))
+       (if (= executing-kbd-macro-index (length executing-kbd-macro))
            (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
                  kmacro-step-edit-inserting t
                  kmacro-step-edit-appending t)
@@ -1053,21 +1124,21 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
        (setq act t)
        t)
        ((eq act 'help)
-       (setq executing-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+       (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
        (setq kmacro-step-edit-help (not kmacro-step-edit-help))
        nil)
        (t ;; Ignore unknown responses
-       (setq executing-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+       (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
        nil))
-      (if (> executing-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+      (if (> executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
          (setq kmacro-step-edit-new-macro
                (vconcat kmacro-step-edit-new-macro
                         (substring executing-kbd-macro
                                    (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)
-                                   (if (eq act t) nil executing-macro-index)))
+                                   (if (eq act t) nil executing-kbd-macro-index)))
                kmacro-step-edit-prefix-index nil))
       (if restore-index
-         (setq executing-macro-index restore-index)))
+         (setq executing-kbd-macro-index restore-index)))
      (t
       (setq this-command 'ignore)))
     (setq kmacro-step-edit-key-index next-index)))
@@ -1080,7 +1151,7 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
        (executing-kbd-macro nil)
        (defining-kbd-macro nil)
        cmd keys next-index)
-    (setq executing-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)
+    (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)
          kmacro-step-edit-prefix-index nil)
     (kmacro-step-edit-prompt macro nil)
     ;; Now, we have read a key sequence from the macro, but we don't want
@@ -1101,8 +1172,8 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
            (setq kmacro-step-edit-inserting nil)
            (when unread-command-events
              (setq keys (substring keys 0 (- (length unread-command-events)))
-                   executing-macro-index (- executing-macro-index (length unread-command-events))
-                   next-index executing-macro-index
+                   executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events))
+                   next-index executing-kbd-macro-index
                    unread-command-events nil)))
          (setq cmd 'ignore)
          nil)
@@ -1146,7 +1217,7 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
      ((eq kmacro-step-edit-active 'ignore)
       (setq this-command 'ignore))
      ((eq kmacro-step-edit-active 'append-end)
-      (if (= executing-macro-index (length executing-kbd-macro))
+      (if (= executing-kbd-macro-index (length executing-kbd-macro))
          (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
                kmacro-step-edit-inserting t
                kmacro-step-edit-appending t
@@ -1172,8 +1243,8 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
   (when kmacro-step-edit-active
     (add-hook 'pre-command-hook 'kmacro-step-edit-pre-command nil nil)
     (if kmacro-step-edit-key-index
-       (setq executing-macro-index kmacro-step-edit-key-index)
-      (setq kmacro-step-edit-key-index executing-macro-index))))
+       (setq executing-kbd-macro-index kmacro-step-edit-key-index)
+      (setq kmacro-step-edit-key-index executing-kbd-macro-index))))
 
 
 (defun kmacro-step-edit-macro ()
@@ -1205,4 +1276,6 @@ To customize possible responses, change the \"bindings\" in `kmacro-step-edit-ma
       (setq last-kbd-macro kmacro-step-edit-new-macro))))
 
 (provide 'kmacro)
+
+;;; arch-tag: d3fe0b24-ae41-47de-a4d6-41a77d5559f0
 ;;; kmacro.el ends here