aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim F. Storm2003-08-17 22:04:44 +0000
committerKim F. Storm2003-08-17 22:04:44 +0000
commita1839f06220e09b957ff6fcbc5d5930f0e4807a5 (patch)
tree37ca69af38d7f756b388f072c99eb210f1291ca1
parent100df2143bd5ab6d23862c85e2edc089c929152a (diff)
downloademacs-a1839f06220e09b957ff6fcbc5d5930f0e4807a5.tar.gz
emacs-a1839f06220e09b957ff6fcbc5d5930f0e4807a5.zip
(kmacro-keymap): Group related bindings in
initialization for clarity. Bind C-s to start macro. Remove C-r binding. (kmacro-initial-counter-value): New defvar to hold initial counter value in case we set the value before defining a macro. (kmacro-insert-counter): Clear kmacro-initial-counter-value.. (kmacro-set-counter): Set kmacro-initial-counter-value if we are not defining or executing macro. Doc fix. (kmacro-add-counter): Clear kmacro-initial-counter-value. (kmacro-view-last-item, kmacro-view-item-no): New defvars used to temporarily view older elements on the macro ring without cycling the ring. (kmacro-display): Doc fix. (kmacro-exec-ring-item): New helper function. (kmacro-call-ring-2nd): Use it. (kmacro-call-ring-2nd-repeat): Doc fix. (kmacro-start-macro): Use (and clear) kmacro-initial-counter-value. (kmacro-end-or-call-macro): Execute last viewed macro (using kmacro-exec-ring-item) from ring if this follows kmacro-view-macro. This allows us to find a macro on the ring with C-x C-k C-v C-v ... and execute it (with C-k) without cycling the ring to bring it to the head of the ring. (kmacro-bind-to-key): Doc fix (describe reserved bindings). Allow binding to reserved keys without specifying C-x C-k prefix. Ask for confirmation if entered key sequence is already bound to a non-macro command. (kmacro-view-macro): Repeating command will show older elements on the macro ring; C-k will execute the last viewed macro. (kmacro-view-macro-repeat): Doc fix. Change its kmacro-repeat property from 'ring to 'head.
-rw-r--r--lisp/kmacro.el173
1 files changed, 137 insertions, 36 deletions
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index a4cb27f5280..054fbbdb678 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -174,29 +174,37 @@ macro to be executed before appending to it."
174 174
175(defvar kmacro-keymap 175(defvar kmacro-keymap
176 (let ((map (make-sparse-keymap))) 176 (let ((map (make-sparse-keymap)))
177 ;; Start, end, execute macros
177 (define-key map "s" 'kmacro-start-macro) 178 (define-key map "s" 'kmacro-start-macro)
179 (define-key map "\C-s" 'kmacro-start-macro)
178 (define-key map "\C-k" 'kmacro-end-or-call-macro-repeat) 180 (define-key map "\C-k" 'kmacro-end-or-call-macro-repeat)
179 (define-key map "\C-e" 'kmacro-edit-macro-repeat) 181 (define-key map "r" 'apply-macro-to-region-lines)
180 (define-key map "\r" 'kmacro-edit-macro) 182 (define-key map "q" 'kbd-macro-query) ;; Like C-x q
181 (define-key map " " 'kmacro-step-edit-macro) 183
182 (define-key map "l" 'kmacro-edit-lossage) 184 ;; macro ring
183 (define-key map "\C-i" 'kmacro-insert-counter)
184 (define-key map "\C-a" 'kmacro-add-counter)
185 (define-key map "\C-v" 'kmacro-view-macro-repeat)
186 (define-key map "\C-l" 'kmacro-call-ring-2nd-repeat)
187 (define-key map "\C-r" 'kmacro-view-ring-2nd)
188 (define-key map "\C-n" 'kmacro-cycle-ring-next) 185 (define-key map "\C-n" 'kmacro-cycle-ring-next)
189 (define-key map "\C-p" 'kmacro-cycle-ring-previous) 186 (define-key map "\C-p" 'kmacro-cycle-ring-previous)
187 (define-key map "\C-v" 'kmacro-view-macro-repeat)
188 (define-key map "\C-d" 'kmacro-delete-ring-head)
189 (define-key map "\C-t" 'kmacro-swap-ring)
190 (define-key map "\C-l" 'kmacro-call-ring-2nd-repeat)
191
192 ;; macro counter
190 (define-key map "\C-f" 'kmacro-set-format) 193 (define-key map "\C-f" 'kmacro-set-format)
191 (define-key map "\C-c" 'kmacro-set-counter) 194 (define-key map "\C-c" 'kmacro-set-counter)
192 (define-key map "\C-t" 'kmacro-swap-ring) 195 (define-key map "\C-i" 'kmacro-insert-counter)
196 (define-key map "\C-a" 'kmacro-add-counter)
197
198 ;; macro editing
199 (define-key map "\C-e" 'kmacro-edit-macro-repeat)
200 (define-key map "\r" 'kmacro-edit-macro)
201 (define-key map "e" 'edit-kbd-macro)
202 (define-key map "l" 'kmacro-edit-lossage)
203 (define-key map " " 'kmacro-step-edit-macro)
204
205 ;; naming and binding
193 (define-key map "b" 'kmacro-bind-to-key) 206 (define-key map "b" 'kmacro-bind-to-key)
194 (define-key map "\C-d" 'kmacro-delete-ring-head)
195 ;; Compatibility bindings
196 (define-key map "q" 'kbd-macro-query)
197 (define-key map "n" 'name-last-kbd-macro) 207 (define-key map "n" 'name-last-kbd-macro)
198 (define-key map "e" 'edit-kbd-macro)
199 (define-key map "r" 'apply-macro-to-region-lines)
200 map) 208 map)
201 "Keymap for keyboard macro commands.") 209 "Keymap for keyboard macro commands.")
202(defalias 'kmacro-keymap kmacro-keymap) 210(defalias 'kmacro-keymap kmacro-keymap)
@@ -229,13 +237,18 @@ macro to be executed before appending to it."
229(defvar kmacro-counter-value-start kmacro-counter 237(defvar kmacro-counter-value-start kmacro-counter
230 "Macro counter at start of macro execution.") 238 "Macro counter at start of macro execution.")
231 239
232(defvar kmacro-last-counter 0 "Last counter inserted by key macro.") 240(defvar kmacro-last-counter 0
241 "Last counter inserted by key macro.")
242
243(defvar kmacro-initial-counter-value nil
244 "Initial counter value for the next keyboard macro to be defined.")
233 245
234 246
235(defun kmacro-insert-counter (arg) 247(defun kmacro-insert-counter (arg)
236 "Insert macro counter and increment with ARG or 1 if missing. 248 "Insert macro counter and increment with ARG or 1 if missing.
237With \\[universal-argument], insert previous kmacro-counter (but do not modify counter)." 249With \\[universal-argument], insert previous kmacro-counter (but do not modify counter)."
238 (interactive "P") 250 (interactive "P")
251 (setq kmacro-initial-counter-value nil)
239 (if (and arg (listp arg)) 252 (if (and arg (listp arg))
240 (insert (format kmacro-counter-format kmacro-last-counter)) 253 (insert (format kmacro-counter-format kmacro-last-counter))
241 (insert (format kmacro-counter-format kmacro-counter)) 254 (insert (format kmacro-counter-format kmacro-counter))
@@ -260,12 +273,16 @@ With \\[universal-argument], insert previous kmacro-counter (but do not modify c
260 273
261(defun kmacro-set-counter (arg) 274(defun kmacro-set-counter (arg)
262 "Set kmacro-counter to ARG or prompt if missing. 275 "Set kmacro-counter to ARG or prompt if missing.
263With \\[universal-argument], reset counter to its value prior to this iteration of the macro." 276With \\[universal-argument] prefix, reset counter to its value prior to this iteration of the macro."
264 (interactive "NMacro counter value: ") 277 (interactive "NMacro counter value: ")
265 (setq kmacro-last-counter kmacro-counter 278 (setq kmacro-last-counter kmacro-counter
266 kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg)) 279 kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
267 kmacro-counter-value-start 280 kmacro-counter-value-start
268 arg)) 281 arg))
282 ;; setup initial macro counter value if we are not executing a macro.
283 (setq kmacro-initial-counter-value
284 (and (not (or defining-kbd-macro executing-kbd-macro))
285 kmacro-counter))
269 (unless executing-kbd-macro 286 (unless executing-kbd-macro
270 (kmacro-display-counter))) 287 (kmacro-display-counter)))
271 288
@@ -274,6 +291,7 @@ With \\[universal-argument], reset counter to its value prior to this iteration
274 "Add numeric prefix arg (prompt if missing) to macro counter. 291 "Add numeric prefix arg (prompt if missing) to macro counter.
275With \\[universal-argument], restore previous counter value." 292With \\[universal-argument], restore previous counter value."
276 (interactive "NAdd to macro counter: ") 293 (interactive "NAdd to macro counter: ")
294 (setq kmacro-initial-counter-value nil)
277 (let ((last kmacro-last-counter)) 295 (let ((last kmacro-last-counter))
278 (setq kmacro-last-counter kmacro-counter 296 (setq kmacro-last-counter kmacro-counter
279 kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg)) 297 kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
@@ -303,6 +321,11 @@ the macro ring (when defining or executing) is not stored in the ring;
303instead it is available in the variables `last-kbd-macro', `kmacro-counter', 321instead it is available in the variables `last-kbd-macro', `kmacro-counter',
304and `kmacro-counter-format'.") 322and `kmacro-counter-format'.")
305 323
324;; Remember what we are currently looking at with kmacro-view-macro.
325
326(defvar kmacro-view-last-item nil)
327(defvar kmacro-view-item-no 0)
328
306 329
307(defun kmacro-ring-head () 330(defun kmacro-ring-head ()
308 "Return pseudo head element in macro ring." 331 "Return pseudo head element in macro ring."
@@ -361,8 +384,11 @@ Check only `last-kbd-macro' if optional arg NONE is non-nil."
361 (t nil))) 384 (t nil)))
362 385
363 386
364(defun kmacro-display (macro &optional trunc descr empty ) 387(defun kmacro-display (macro &optional trunc descr empty)
365 "Display a keyboard MACRO." 388 "Display a keyboard MACRO.
389Optional arg TRUNC non-nil specifies to limit width of macro to 60 chars.
390Optional arg DESCR is descriptive text for macro; default is \"Macro:\".
391Optional arg EMPTY is message to print if no macros are defined."
366 (if macro 392 (if macro
367 (let* ((x 60) 393 (let* ((x 60)
368 (m (format-kbd-macro macro)) 394 (m (format-kbd-macro macro))
@@ -410,19 +436,26 @@ Check only `last-kbd-macro' if optional arg NONE is non-nil."
410 keys))) 436 keys)))
411 437
412 438
439(defun kmacro-exec-ring-item (item arg)
440 "Execute item ITEM from the macro ring."
441 ;; Use counter and format specific to the macro on the ring!
442 (let ((kmacro-counter (nth 1 item))
443 (kmacro-counter-format-start (nth 2 item)))
444 (execute-kbd-macro (car item) arg #'kmacro-loop-setup-function)
445 (setcar (cdr item) kmacro-counter)))
446
447
413(defun kmacro-call-ring-2nd (arg) 448(defun kmacro-call-ring-2nd (arg)
414 "Execute second keyboard macro at in macro ring." 449 "Execute second keyboard macro at in macro ring."
415 (interactive "P") 450 (interactive "P")
416 (unless (kmacro-ring-empty-p) 451 (unless (kmacro-ring-empty-p)
417 ;; should use counter format specific to the macro on the ring! 452 (kmacro-exec-ring-item (car kmacro-ring) arg)))
418 (let ((kmacro-counter (nth 1 (car kmacro-ring)))
419 (kmacro-counter-format-start (nth 2 (car kmacro-ring))))
420 (execute-kbd-macro (car (car kmacro-ring)) arg #'kmacro-loop-setup-function)
421 (setcar (cdr (car kmacro-ring)) kmacro-counter))))
422 453
423 454
424(defun kmacro-call-ring-2nd-repeat (arg) 455(defun kmacro-call-ring-2nd-repeat (arg)
425 "Like `kmacro-call-ring-2nd', but allow repeat without repeating prefix." 456 "Execute second keyboard macro at in macro ring.
457This is like `kmacro-call-ring-2nd', but allows repeating macro commands
458without repeating the prefix."
426 (interactive "P") 459 (interactive "P")
427 (let ((keys (kmacro-get-repeat-prefix))) 460 (let ((keys (kmacro-get-repeat-prefix)))
428 (kmacro-call-ring-2nd arg) 461 (kmacro-call-ring-2nd arg)
@@ -439,7 +472,6 @@ Check only `last-kbd-macro' if optional arg NONE is non-nil."
439 (kmacro-display (car (car kmacro-ring)) "2nd macro"))) 472 (kmacro-display (car (car kmacro-ring)) "2nd macro")))
440 473
441 474
442
443(defun kmacro-cycle-ring-next (&optional arg) 475(defun kmacro-cycle-ring-next (&optional arg)
444 "Move to next keyboard macro in keyboard macro ring. 476 "Move to next keyboard macro in keyboard macro ring.
445Displays the selected macro in the echo area." 477Displays the selected macro in the echo area."
@@ -533,7 +565,10 @@ The format of the counter can be modified via \\[kmacro-set-format]."
533 kmacro-ring)) 565 kmacro-ring))
534 (if (>= len kmacro-ring-max) 566 (if (>= len kmacro-ring-max)
535 (setcdr (nthcdr len kmacro-ring) nil)))) 567 (setcdr (nthcdr len kmacro-ring) nil))))
536 (setq kmacro-counter (if arg (prefix-numeric-value arg) 0) 568 (setq kmacro-counter (or (if arg (prefix-numeric-value arg))
569 kmacro-initial-counter-value
570 0)
571 kmacro-initial-counter-value nil
537 kmacro-counter-value-start kmacro-counter 572 kmacro-counter-value-start kmacro-counter
538 kmacro-last-counter kmacro-counter 573 kmacro-last-counter kmacro-counter
539 kmacro-counter-format-start kmacro-counter-format)) 574 kmacro-counter-format-start kmacro-counter-format))
@@ -645,6 +680,9 @@ With \\[universal-argument], call second macro in macro ring."
645 (if kmacro-call-repeat-key 680 (if kmacro-call-repeat-key
646 (kmacro-call-macro arg no-repeat t) 681 (kmacro-call-macro arg no-repeat t)
647 (kmacro-end-macro arg))) 682 (kmacro-end-macro arg)))
683 ((and (eq this-command 'kmacro-view-macro) ;; We are in repeat mode!
684 kmacro-view-last-item)
685 (kmacro-exec-ring-item (car kmacro-view-last-item) arg))
648 ((and arg (listp arg)) 686 ((and arg (listp arg))
649 (kmacro-call-ring-2nd 1)) 687 (kmacro-call-ring-2nd 1))
650 (t 688 (t
@@ -689,34 +727,97 @@ If kbd macro currently being defined end it before activating it."
689 727
690;;; Misc. commands 728;;; Misc. commands
691 729
730;; An idea for macro bindings:
731;; Create a separate keymap installed as a minor-mode keymap (e.g. in
732;; the emulation-mode-map-alists) in which macro bindings are made
733;; independent of any other bindings. When first binding is made,
734;; the kemap is created, installed, and enabled. Key seq. C-x C-k +
735;; can then be used to toggle the use of this keymap on and off.
736;; This means that it would be safe(r) to bind ordinary keys like
737;; letters and digits, provided that we inhibit the keymap while
738;; executing the macro later on (but that's controversial...)
739
692(defun kmacro-bind-to-key (arg) 740(defun kmacro-bind-to-key (arg)
693 "When not defining or executing a macro, offer to bind last macro to a key." 741 "When not defining or executing a macro, offer to bind last macro to a key.
742The key sequences [C-x C-k 0] through [C-x C-k 9] and [C-x C-k A]
743through [C-x C-k Z] are reserved for user bindings, and to bind to
744one of these sequences, just enter the digit or letter, rather than
745the whole sequence.
746
747You can bind to any valid key sequence, but if you try to bind to
748a key with an existing command binding, you will be asked for
749confirmation whether to replace that binding. Note that the
750binding is made in the `global-map' keymap, so the macro binding
751may be shaded by a local key binding."
694 (interactive "p") 752 (interactive "p")
695 (if (or defining-kbd-macro executing-kbd-macro) 753 (if (or defining-kbd-macro executing-kbd-macro)
696 (if defining-kbd-macro 754 (if defining-kbd-macro
697 (message "Cannot save macro while defining it.")) 755 (message "Cannot save macro while defining it."))
698 (unless last-kbd-macro 756 (unless last-kbd-macro
699 (error "No keyboard macro defined")) 757 (error "No keyboard macro defined"))
700 (let ((key-seq (read-key-sequence "Bind last macro to key: "))) 758 (let ((key-seq (read-key-sequence "Bind last macro to key: "))
701 (unless (equal key-seq "") 759 ok cmd)
702 (define-key global-map key-seq last-kbd-macro))))) 760 (when (= (length key-seq) 1)
761 (let ((ch (aref key-seq 0)))
762 (if (or (and (>= ch ?0) (<= ch ?9))
763 (and (>= ch ?A) (<= ch ?Z)))
764 (setq key-seq (concat "\C-x\C-k" key-seq)
765 ok t))))
766 (when (and (not (equal key-seq ""))
767 (or ok
768 (not (setq cmd (key-binding key-seq)))
769 (stringp cmd)
770 (vectorp cmd)
771 (yes-or-no-p (format "%s runs command %S. Bind anyway? "
772 (format-kbd-macro key-seq)
773 cmd))))
774 (define-key global-map key-seq last-kbd-macro)
775 (message "Keyboard macro bound to %s" (format-kbd-macro key-seq))))))
703 776
704 777
705(defun kmacro-view-macro (&optional arg) 778(defun kmacro-view-macro (&optional arg)
706 "Display the last keyboard macro." 779 "Display the last keyboard macro.
780If repeated, it shows previous elements in the macro ring."
707 (interactive) 781 (interactive)
708 (kmacro-display last-kbd-macro)) 782 (cond
709 783 ((or (kmacro-ring-empty-p)
784 (not (eq last-command 'kmacro-view-macro)))
785 (setq kmacro-view-last-item nil))
786 ((null kmacro-view-last-item)
787 (setq kmacro-view-last-item kmacro-ring
788 kmacro-view-item-no 2))
789 ((consp kmacro-view-last-item)
790 (setq kmacro-view-last-item (cdr kmacro-view-last-item)
791 kmacro-view-item-no (1+ kmacro-view-item-no)))
792 (t
793 (setq kmacro-view-last-item nil)))
794 (setq this-command 'kmacro-view-macro
795 last-command this-command) ;; in case we repeat
796 (kmacro-display (if kmacro-view-last-item
797 (car (car kmacro-view-last-item))
798 last-kbd-macro)
799 nil
800 (if kmacro-view-last-item
801 (concat (cond ((= kmacro-view-item-no 2) "2nd")
802 ((= kmacro-view-item-no 3) "3nd")
803 (t (format "%dth" kmacro-view-item-no)))
804 " previous macro")
805 "Last macro")))
710 806
711(defun kmacro-view-macro-repeat (&optional arg) 807(defun kmacro-view-macro-repeat (&optional arg)
712 "Like `kmacro-view-macro', but allow repeat without repeating prefix." 808 "Display the last keyboard macro.
809If repeated, it shows previous elements in the macro ring.
810To execute the displayed macro ring item without changing the macro ring,
811just enter C-k.
812This is like `kmacro-view-macro', but allows repeating macro commands
813without repeating the prefix."
713 (interactive) 814 (interactive)
714 (let ((keys (kmacro-get-repeat-prefix))) 815 (let ((keys (kmacro-get-repeat-prefix)))
715 (kmacro-view-macro arg) 816 (kmacro-view-macro arg)
716 (if (and last-kbd-macro keys) 817 (if (and last-kbd-macro keys)
717 (kmacro-repeat-on-last-key keys)))) 818 (kmacro-repeat-on-last-key keys))))
718 819
719(put 'kmacro-view-macro-repeat 'kmacro-repeat 'head) 820(put 'kmacro-view-macro-repeat 'kmacro-repeat 'ring)
720 821
721 822
722(defun kmacro-edit-macro-repeat (&optional arg) 823(defun kmacro-edit-macro-repeat (&optional arg)