Mercurial > emacs
comparison lisp/kmacro.el @ 52223:d37e0b4125e8
(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.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 17 Aug 2003 22:04:44 +0000 |
parents | 5f447cd26b30 |
children | 695cf19ef79e |
comparison
equal
deleted
inserted
replaced
52222:2573b58491df | 52223:d37e0b4125e8 |
---|---|
172 | 172 |
173 ;; Keymap | 173 ;; Keymap |
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) |
181 (define-key map "r" 'apply-macro-to-region-lines) | |
182 (define-key map "q" 'kbd-macro-query) ;; Like C-x q | |
183 | |
184 ;; macro ring | |
185 (define-key map "\C-n" 'kmacro-cycle-ring-next) | |
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 | |
193 (define-key map "\C-f" 'kmacro-set-format) | |
194 (define-key map "\C-c" 'kmacro-set-counter) | |
195 (define-key map "\C-i" 'kmacro-insert-counter) | |
196 (define-key map "\C-a" 'kmacro-add-counter) | |
197 | |
198 ;; macro editing | |
179 (define-key map "\C-e" 'kmacro-edit-macro-repeat) | 199 (define-key map "\C-e" 'kmacro-edit-macro-repeat) |
180 (define-key map "\r" 'kmacro-edit-macro) | 200 (define-key map "\r" 'kmacro-edit-macro) |
201 (define-key map "e" 'edit-kbd-macro) | |
202 (define-key map "l" 'kmacro-edit-lossage) | |
181 (define-key map " " 'kmacro-step-edit-macro) | 203 (define-key map " " 'kmacro-step-edit-macro) |
182 (define-key map "l" 'kmacro-edit-lossage) | 204 |
183 (define-key map "\C-i" 'kmacro-insert-counter) | 205 ;; naming and binding |
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) | |
189 (define-key map "\C-p" 'kmacro-cycle-ring-previous) | |
190 (define-key map "\C-f" 'kmacro-set-format) | |
191 (define-key map "\C-c" 'kmacro-set-counter) | |
192 (define-key map "\C-t" 'kmacro-swap-ring) | |
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) |
203 | 211 |
204 ;;; Provide some binding for startup: | 212 ;;; Provide some binding for startup: |
227 "Macro format at start of macro execution.") | 235 "Macro format at start of macro execution.") |
228 | 236 |
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. |
237 With \\[universal-argument], insert previous kmacro-counter (but do not modify counter)." | 249 With \\[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)) |
242 (kmacro-add-counter (prefix-numeric-value arg)))) | 255 (kmacro-add-counter (prefix-numeric-value arg)))) |
243 | 256 |
258 (message "New macro counter value: %s (%d)" (format kmacro-counter-format value) value)) | 271 (message "New macro counter value: %s (%d)" (format kmacro-counter-format value) value)) |
259 | 272 |
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. |
263 With \\[universal-argument], reset counter to its value prior to this iteration of the macro." | 276 With \\[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 |
272 | 289 |
273 (defun kmacro-add-counter (arg) | 290 (defun kmacro-add-counter (arg) |
274 "Add numeric prefix arg (prompt if missing) to macro counter. | 291 "Add numeric prefix arg (prompt if missing) to macro counter. |
275 With \\[universal-argument], restore previous counter value." | 292 With \\[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)) |
280 last | 298 last |
281 kmacro-counter (+ kmacro-counter arg)))) | 299 kmacro-counter (+ kmacro-counter arg)))) |
300 "The keyboard macro ring. | 318 "The keyboard macro ring. |
301 Each element is a list (MACRO COUNTER FORMAT). Actually, the head of | 319 Each element is a list (MACRO COUNTER FORMAT). Actually, the head of |
302 the macro ring (when defining or executing) is not stored in the ring; | 320 the macro ring (when defining or executing) is not stored in the ring; |
303 instead it is available in the variables `last-kbd-macro', `kmacro-counter', | 321 instead it is available in the variables `last-kbd-macro', `kmacro-counter', |
304 and `kmacro-counter-format'.") | 322 and `kmacro-counter-format'.") |
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) | |
305 | 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." |
309 (and last-kbd-macro | 332 (and last-kbd-macro |
359 (message "Only one keyboard macro defined.") | 382 (message "Only one keyboard macro defined.") |
360 t) | 383 t) |
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. |
389 Optional arg TRUNC non-nil specifies to limit width of macro to 60 chars. | |
390 Optional arg DESCR is descriptive text for macro; default is \"Macro:\". | |
391 Optional 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)) |
369 (l (length m)) | 395 (l (length m)) |
370 (z (and nil trunc (> l x)))) | 396 (z (and nil trunc (> l x)))) |
408 (setq keys (this-single-command-keys)) | 434 (setq keys (this-single-command-keys)) |
409 (> (length keys) 1) | 435 (> (length keys) 1) |
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. |
457 This is like `kmacro-call-ring-2nd', but allows repeating macro commands | |
458 without 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) |
429 (if (and kmacro-ring keys) | 462 (if (and kmacro-ring keys) |
430 (kmacro-repeat-on-last-key keys)))) | 463 (kmacro-repeat-on-last-key keys)))) |
435 (defun kmacro-view-ring-2nd () | 468 (defun kmacro-view-ring-2nd () |
436 "Display the current head of the keyboard macro ring." | 469 "Display the current head of the keyboard macro ring." |
437 (interactive) | 470 (interactive) |
438 (unless (kmacro-ring-empty-p) | 471 (unless (kmacro-ring-empty-p) |
439 (kmacro-display (car (car kmacro-ring)) "2nd macro"))) | 472 (kmacro-display (car (car kmacro-ring)) "2nd macro"))) |
440 | |
441 | 473 |
442 | 474 |
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. |
445 Displays the selected macro in the echo area." | 477 Displays the selected macro in the echo area." |
531 (cons | 563 (cons |
532 (list last-kbd-macro kmacro-counter kmacro-counter-format-start) | 564 (list last-kbd-macro kmacro-counter kmacro-counter-format-start) |
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)) |
540 | 575 |
541 (start-kbd-macro append | 576 (start-kbd-macro append |
643 (cond | 678 (cond |
644 (defining-kbd-macro | 679 (defining-kbd-macro |
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 |
651 (kmacro-call-macro arg no-repeat)))) | 689 (kmacro-call-macro arg no-repeat)))) |
652 | 690 |
687 (kmacro-call-macro nil t)) | 725 (kmacro-call-macro nil t)) |
688 | 726 |
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. |
742 The key sequences [C-x C-k 0] through [C-x C-k 9] and [C-x C-k A] | |
743 through [C-x C-k Z] are reserved for user bindings, and to bind to | |
744 one of these sequences, just enter the digit or letter, rather than | |
745 the whole sequence. | |
746 | |
747 You can bind to any valid key sequence, but if you try to bind to | |
748 a key with an existing command binding, you will be asked for | |
749 confirmation whether to replace that binding. Note that the | |
750 binding is made in the `global-map' keymap, so the macro binding | |
751 may 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. |
780 If 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. |
809 If repeated, it shows previous elements in the macro ring. | |
810 To execute the displayed macro ring item without changing the macro ring, | |
811 just enter C-k. | |
812 This is like `kmacro-view-macro', but allows repeating macro commands | |
813 without 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) |
723 "Edit last keyboard macro." | 824 "Edit last keyboard macro." |
724 (interactive "P") | 825 (interactive "P") |