1;;; kmacro.el --- enhanced keyboard macros -*- lexical-binding: t -*-
2
3;; Copyright (C) 2002-2021 Free Software Foundation, Inc.
4
5;; Author: Kim F. Storm <storm@cua.dk>
6;; Keywords: keyboard convenience
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; The kmacro package provides the user interface to Emacs' basic
26;; keyboard macro functionality.  With kmacro, two function keys are
27;; dedicated to keyboard macros, by default F3 and F4.
28
29;; Note: The traditional bindings C-x (, C-x ), and C-x e are still
30;; supported, but for some users these bindings are too hard to type
31;; to be really useful for doing small repeated tasks.
32
33;; To start defining a keyboard macro, use F3.  To end the macro,
34;; use F4, and to call the macro also use F4.  This makes it very
35;; easy to repeat a macro immediately after defining it.
36;;
37;; You can call the macro repeatedly by pressing F4 multiple times, or
38;; you can give a numeric prefix argument specifying the number of
39;; times to repeat the macro.  Macro execution automatically
40;; terminates when point reaches the end of the buffer or if an error
41;; is signaled by ringing the bell.
42
43;; When you define a macro with F3/F4, it is automatically added to
44;; the head of the "keyboard macro ring", and F4 actually executes the
45;; first element of the macro ring.
46;;
47;; Note: an empty macro is never added to the macro ring.
48;;
49;; You can execute the second element on the macro ring with C-u F4 or
50;; C-x C-k C-l, you can use C-x C-k C-p and C-x C-k C-n to cycle
51;; through the macro ring, and you can swap the first and second
52;; elements with C-x C-k C-t.  To delete the first element in the
53;; macro ring, use C-x C-k C-d.
54;;
55;; You can also use C-x C-k C-s to start a macro, and C-x C-k C-k to
56;; end it; then use C-k to execute it immediately, or C-x C-k C-k to
57;; execute it later.
58;;
59;; In general, immediately after using C-x C-k followed by one of C-k,
60;; C-l, C-p, or C-n, you can further cycle the macro ring using C-p or
61;; C-n, execute the first or second macro using C-k or C-l, delete
62;; the head macro with C-d, or edit the current macro with C-e without
63;; repeating the C-x C-k prefix.
64
65;; If you enter F3 while defining the macro, the numeric value of
66;; `kmacro-counter' is inserted using the `kmacro-counter-format', and
67;; `kmacro-counter' is incremented by 1 (or the numeric prefix value
68;; of F3).
69;;
70;; The initial value of `kmacro-counter' is 0, or the numeric prefix
71;; value given to F3 when starting the macro.
72;;
73;; Now, each time you call the macro using F4, the current
74;; value of `kmacro-counter' is inserted and incremented, making it
75;; easy to insert incremental numbers in the buffer.
76;;
77;; Example:
78;;
79;; The following sequence: M-5 F3 x M-2 F3 y F4 F4 F4 F4
80;; inserts the following string:  x5yx7yx9yx11y
81
82;; A macro can also be called using a mouse click, default S-mouse-3.
83;; This calls the macro at the point where you click the mouse.
84
85;; You can edit the last macro using C-x C-k C-e.
86
87;; You can append to the last macro using C-u F3.
88
89;; You can set the macro counter using C-x C-k C-c, add to it using C-x C-k C-a,
90;; and you can set the macro counter format with C-x C-k C-f.
91
92;; The following key bindings are performed:
93;;
94;;           Normal                         While defining macro
95;;           ---------------------------    ------------------------------
96;;  f3       Define macro                   Insert current counter value
97;;           Prefix arg specifies initial   and increase counter by prefix
98;;           counter value (default 0)      (default increment: 1)
99;;
100;;  C-u f3   APPENDs to last macro
101;;
102;;  f4       Call last macro                End macro
103;;           Prefix arg specifies number
104;;           of times to execute macro.
105;;
106;;  C-u f4   Swap last and head of macro ring.
107;;
108;;  S-mouse-3  Set point at click and       End macro and execute macro at
109;;             execute last macro.          click.
110
111;;; Code:
112
113;; Customization:
114(require 'replace)
115(require 'cl-lib)
116
117(defgroup kmacro nil
118  "Simplified keyboard macro user interface."
119  :group 'keyboard
120  :group 'convenience
121  :version "22.1"
122  :link '(emacs-commentary-link :tag "Commentary" "kmacro.el")
123  :link '(emacs-library-link :tag "Lisp File" "kmacro.el"))
124
125(defcustom kmacro-call-mouse-event 'S-mouse-3
126  "The mouse event used by kmacro to call a macro.
127Set to nil if no mouse binding is desired."
128  :type 'symbol)
129
130(defcustom kmacro-ring-max 8
131  "Maximum number of keyboard macros to save in macro ring."
132  :type 'integer)
133
134
135(defcustom kmacro-execute-before-append t
136  "Controls whether appending to a macro starts by executing the macro.
137If non-nil, using a single \\[universal-argument] prefix executes the macro
138before appending, while more than one \\[universal-argument] prefix does not
139execute the macro.
140Otherwise, a single \\[universal-argument] prefix does not execute the
141macro, while more than one \\[universal-argument] prefix causes the
142macro to be executed before appending to it."
143  :type 'boolean)
144
145
146(defcustom kmacro-repeat-no-prefix t
147  "Allow repeating certain macro commands without entering the \\[kmacro-keymap] prefix."
148  :type 'boolean)
149
150(defcustom kmacro-call-repeat-key t
151  "Allow repeating macro call using last key or a specific key."
152  :type '(choice (const :tag "Disabled" nil)
153		 (const :tag "Last key" t)
154		 (character :tag "Character" :value ?e)
155		 (symbol :tag "Key symbol" :value RET)))
156
157(defcustom kmacro-call-repeat-with-arg nil
158  "Repeat macro call with original arg when non-nil; repeat once if nil."
159  :type 'boolean)
160
161(defcustom kmacro-step-edit-mini-window-height 0.75
162  "Override `max-mini-window-height' when step edit keyboard macro."
163  :type 'number)
164
165;; Keymap
166
167(defvar kmacro-keymap
168  (let ((map (make-sparse-keymap)))
169    ;; Start, end, execute macros
170    (define-key map "s"    #'kmacro-start-macro)
171    (define-key map "\C-s" #'kmacro-start-macro)
172    (define-key map "\C-k" #'kmacro-end-or-call-macro-repeat)
173    (define-key map "r"    #'apply-macro-to-region-lines)
174    (define-key map "q"    #'kbd-macro-query)  ;; Like C-x q
175    (define-key map "d"    #'kdb-macro-redisplay)
176
177    ;; macro ring
178    (define-key map "\C-n" #'kmacro-cycle-ring-next)
179    (define-key map "\C-p" #'kmacro-cycle-ring-previous)
180    (define-key map "\C-v" #'kmacro-view-macro-repeat)
181    (define-key map "\C-d" #'kmacro-delete-ring-head)
182    (define-key map "\C-t" #'kmacro-swap-ring)
183    (define-key map "\C-l" #'kmacro-call-ring-2nd-repeat)
184
185    ;; macro counter
186    (define-key map "\C-f" #'kmacro-set-format)
187    (define-key map "\C-c" #'kmacro-set-counter)
188    (define-key map "\C-i" #'kmacro-insert-counter)
189    (define-key map "\C-a" #'kmacro-add-counter)
190
191    ;; macro editing
192    (define-key map "\C-e" #'kmacro-edit-macro-repeat)
193    (define-key map "\r"   #'kmacro-edit-macro)
194    (define-key map "e"    #'edit-kbd-macro)
195    (define-key map "l"    #'kmacro-edit-lossage)
196    (define-key map " "    #'kmacro-step-edit-macro)
197
198    ;; naming and binding
199    (define-key map "b"    #'kmacro-bind-to-key)
200    (define-key map "n"    #'kmacro-name-last-macro)
201    (define-key map "x"    #'kmacro-to-register)
202    map)
203  "Keymap for keyboard macro commands.")
204(defalias 'kmacro-keymap kmacro-keymap)
205
206;;; Provide some binding for startup:
207;;;###autoload (global-set-key "\C-x(" #'kmacro-start-macro)
208;;;###autoload (global-set-key "\C-x)" #'kmacro-end-macro)
209;;;###autoload (global-set-key "\C-xe" #'kmacro-end-and-call-macro)
210;;;###autoload (global-set-key [f3] #'kmacro-start-macro-or-insert-counter)
211;;;###autoload (global-set-key [f4] #'kmacro-end-or-call-macro)
212;;;###autoload (global-set-key "\C-x\C-k" #'kmacro-keymap)
213;;;###autoload (autoload 'kmacro-keymap "kmacro" "Keymap for keyboard macro commands." t 'keymap)
214
215(if kmacro-call-mouse-event
216  (global-set-key (vector kmacro-call-mouse-event) #'kmacro-end-call-mouse))
217
218
219;;; Called from keyboard-quit
220
221(defun kmacro-keyboard-quit ()
222  (or (not defining-kbd-macro)
223      (eq defining-kbd-macro 'append)
224      (kmacro-ring-empty-p)
225      (kmacro-pop-ring)))
226
227
228;;; Keyboard macro counter
229
230(defvar kmacro-counter 0
231  "Current keyboard macro counter.
232
233This is normally initialized to zero when the macro is defined,
234and incremented each time the value of the counter is inserted
235into a buffer.  See `kmacro-start-macro-or-insert-counter' for
236more details.")
237
238(defvar kmacro-default-counter-format "%d")
239
240(defvar kmacro-counter-format "%d"
241  "Current keyboard macro counter format.
242
243Can be set directly via `kmacro-set-format', which see.")
244
245(defvar kmacro-counter-format-start kmacro-counter-format
246  "Macro format at start of macro execution.")
247
248(defvar kmacro-counter-value-start kmacro-counter
249  "Macro counter at start of macro execution.")
250
251(defvar kmacro-last-counter 0
252  "Last counter inserted by key macro.")
253
254(defvar kmacro-initial-counter-value nil
255  "Initial counter value for the next keyboard macro to be defined.")
256
257
258(defun kmacro-insert-counter (arg)
259  "Insert current value of `kmacro-counter', then increment it by ARG.
260Interactively, ARG defaults to 1.  With \\[universal-argument], insert
261the previous value of `kmacro-counter', and do not increment the
262current value.
263
264The previous value of the counter is the one it had before
265the last increment.
266
267See Info node `(emacs) Keyboard Macro Counter' for more
268information."
269  (interactive "P")
270  (if kmacro-initial-counter-value
271      (setq kmacro-counter kmacro-initial-counter-value
272	    kmacro-initial-counter-value nil))
273  (if (consp arg)
274      (insert (format kmacro-counter-format kmacro-last-counter))
275    (insert (format kmacro-counter-format kmacro-counter))
276    (kmacro-add-counter (prefix-numeric-value arg))))
277
278
279(defun kmacro-set-format (format)
280  "Set the format of `kmacro-counter' to FORMAT.
281
282The default format is \"%d\", which means to insert the number in
283decimal without any padding.  You can specify any format string
284that the `format' function accepts and that makes sense with a
285single integer extra argument.
286
287If you run this command while no keyboard macro is being defined,
288the new format affects all subsequent macro definitions.
289
290If you run this command while defining a keyboard macro, it
291affects only that macro, from that point on.
292
293Do not put the format string inside double quotes when you insert
294it in the minibuffer.
295
296See Info node `(emacs) Keyboard Macro Counter' for more
297information."
298  (interactive "sMacro Counter Format: ")
299  (setq kmacro-counter-format
300	(if (equal format "") "%d" format))
301  ;; redefine initial macro counter if we are not executing a macro.
302  (if (not (or defining-kbd-macro executing-kbd-macro))
303      (setq kmacro-default-counter-format kmacro-counter-format)))
304
305
306(defun kmacro-display-counter (&optional value)
307  "Display current counter value.
308
309See Info node `(emacs) Keyboard Macro Counter' for more
310information."
311  (unless value (setq value kmacro-counter))
312  (message "New macro counter value: %s (%d)"
313           (format kmacro-counter-format value) value))
314
315(defun kmacro-set-counter (arg)
316  "Set the value of `kmacro-counter' to ARG, or prompt for value if no argument.
317With \\[universal-argument] prefix, reset counter to its value prior to this iteration of the
318macro.
319
320See Info node `(emacs) Keyboard Macro Counter' for more
321information."
322  (interactive "NMacro counter value: ")
323  (if (not (or defining-kbd-macro executing-kbd-macro))
324      (kmacro-display-counter (setq kmacro-initial-counter-value arg))
325    (setq kmacro-last-counter kmacro-counter
326	  kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
327			     kmacro-counter-value-start
328			   arg))
329    (unless executing-kbd-macro
330      (kmacro-display-counter))))
331
332
333(defun kmacro-add-counter (arg)
334  "Add the value of numeric prefix arg (prompt if missing) to `kmacro-counter'.
335With \\[universal-argument], restore previous counter value.
336
337See Info node `(emacs) Keyboard Macro Counter' for more
338information."
339  (interactive "NAdd to macro counter: ")
340  (if kmacro-initial-counter-value
341      (setq kmacro-counter kmacro-initial-counter-value
342	    kmacro-initial-counter-value nil))
343  (let ((last kmacro-last-counter))
344    (setq kmacro-last-counter kmacro-counter
345	  kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg))
346			     last
347			   kmacro-counter (+ kmacro-counter arg))))
348  (unless executing-kbd-macro
349    (kmacro-display-counter)))
350
351
352(defun kmacro-loop-setup-function ()
353  "Function called prior to each iteration of macro."
354  ;; Restore macro counter format to initial format, so it is ok to change
355  ;; counter format in the macro without restoring it.
356  (setq kmacro-counter-format kmacro-counter-format-start)
357  ;; Save initial counter value so we can restore it with C-u kmacro-set-counter.
358  (setq kmacro-counter-value-start kmacro-counter)
359  ;; Return non-nil to continue execution.
360  t)
361
362
363;;; Keyboard macro ring
364
365(defvar kmacro-ring nil
366  "The keyboard macro ring.
367Each element is a list (MACRO COUNTER FORMAT).  Actually, the head of
368the macro ring (when defining or executing) is not stored in the ring;
369instead it is available in the variables `last-kbd-macro', `kmacro-counter',
370and `kmacro-counter-format'.")
371
372;; Remember what we are currently looking at with kmacro-view-macro.
373
374(defvar kmacro-view-last-item nil)
375(defvar kmacro-view-item-no 0)
376
377
378(defun kmacro-ring-head ()
379  "Return pseudo head element in macro ring."
380  (and last-kbd-macro
381       (list last-kbd-macro kmacro-counter kmacro-counter-format-start)))
382
383
384(defun kmacro-push-ring (&optional elt)
385  "Push ELT or current macro onto `kmacro-ring'."
386  (when (setq elt (or elt (kmacro-ring-head)))
387    (let ((history-delete-duplicates nil))
388      (add-to-history 'kmacro-ring elt kmacro-ring-max))))
389
390
391(defun kmacro-split-ring-element (elt)
392  (setq last-kbd-macro (car elt)
393	kmacro-counter (nth 1 elt)
394	kmacro-counter-format-start (nth 2 elt)))
395
396
397(defun kmacro-pop-ring1 (&optional raw)
398  "Pop head element off macro ring (no check).
399Non-nil arg RAW means just return raw first element."
400  (prog1 (car kmacro-ring)
401    (unless raw
402      (kmacro-split-ring-element (car kmacro-ring)))
403    (setq kmacro-ring (cdr kmacro-ring))))
404
405
406(defun kmacro-pop-ring (&optional raw)
407  "Pop head element off macro ring.
408Non-nil arg RAW means just return raw first element."
409  (unless (kmacro-ring-empty-p)
410    (kmacro-pop-ring1 raw)))
411
412
413(defun kmacro-ring-empty-p (&optional none)
414  "Tell user and return t if `last-kbd-macro' is nil or `kmacro-ring' is empty.
415Check only `last-kbd-macro' if optional arg NONE is non-nil."
416  (while (and (null last-kbd-macro) kmacro-ring)
417    (kmacro-pop-ring1))
418  (cond
419   ((null last-kbd-macro)
420    (message "No keyboard macro defined.")
421    t)
422   ((and (null none) (null kmacro-ring))
423    (message "Only one keyboard macro defined.")
424    t)
425   (t nil)))
426
427
428(defun kmacro-display (macro &optional trunc descr empty)
429  "Display a keyboard MACRO.
430Optional arg TRUNC non-nil specifies to limit width of macro to 60 chars.
431Optional arg DESCR is descriptive text for macro; default is \"Macro:\".
432Optional arg EMPTY is message to print if no macros are defined."
433  (if macro
434      (let* ((x 60)
435	     (m (format-kbd-macro macro))
436	     (l (length m))
437	     (z (and trunc (> l x))))
438	(message "%s%s: %s%s" (or descr "Macro")
439		 (if (= kmacro-counter 0) ""
440		   (format " [%s]"
441			   (format kmacro-counter-format-start kmacro-counter)))
442		 (if z (substring m 0 (1- x)) m) (if z "..." "")))
443    (message "%s" (or empty "No keyboard macros defined"))))
444
445
446(defun kmacro-repeat-on-last-key (keys)
447  "Process kmacro commands keys immediately after cycling the ring."
448  (setq keys (vconcat keys))
449  (let ((n (1- (length keys)))
450	cmd done repeat)
451    (while (and last-kbd-macro
452		(not done)
453		(aset keys n (read-event))
454		(setq cmd (key-binding keys t))
455		(setq repeat (get cmd 'kmacro-repeat)))
456      (clear-this-command-keys t)
457      (cond
458       ((eq repeat 'ring)
459	(if kmacro-ring
460	    (let ((kmacro-repeat-no-prefix nil))
461	      (funcall cmd nil))
462	  (kmacro-display last-kbd-macro t)))
463       ((eq repeat 'head)
464	(let ((kmacro-repeat-no-prefix nil))
465	  (funcall cmd nil)))
466       ((eq repeat 'stop)
467	(funcall cmd nil)
468	(setq done t)))
469      (setq last-input-event nil)))
470  (when last-input-event
471    (clear-this-command-keys t)
472    (push last-input-event unread-command-events)))
473
474
475(defun kmacro-get-repeat-prefix ()
476  (let (keys)
477    (and kmacro-repeat-no-prefix
478	 (setq keys (this-single-command-keys))
479	 (> (length keys) 1)
480	 keys)))
481
482
483;;;###autoload
484(defun kmacro-exec-ring-item (item arg)
485  "Execute item ITEM from the macro ring.
486ARG is the number of times to execute the item."
487  ;; Use counter and format specific to the macro on the ring!
488  (let ((kmacro-counter (nth 1 item))
489	(kmacro-counter-format-start (nth 2 item)))
490    (execute-kbd-macro (car item) arg #'kmacro-loop-setup-function)
491    (setcar (cdr item) kmacro-counter)))
492
493
494(defun kmacro-call-ring-2nd (arg)
495  "Execute second keyboard macro in macro ring."
496  (interactive "P")
497  (unless (kmacro-ring-empty-p)
498    (kmacro-exec-ring-item (car kmacro-ring) arg)))
499
500
501(defun kmacro-call-ring-2nd-repeat (arg)
502  "Execute second keyboard macro in macro ring.
503This is like `kmacro-call-ring-2nd', but allows repeating macro commands
504without repeating the prefix."
505  (interactive "P")
506  (let ((keys (kmacro-get-repeat-prefix)))
507    (kmacro-call-ring-2nd arg)
508    (if (and kmacro-ring keys)
509	(kmacro-repeat-on-last-key keys))))
510
511(put 'kmacro-call-ring-2nd-repeat 'kmacro-repeat 'head)
512
513
514(defun kmacro-view-ring-2nd ()
515  "Display the second macro in the keyboard macro ring."
516  (interactive)
517  (unless (kmacro-ring-empty-p)
518    (kmacro-display (car (car kmacro-ring)) nil "2nd macro")))
519
520
521(defun kmacro-cycle-ring-next (&optional _arg)
522  "Move to next keyboard macro in keyboard macro ring.
523Displays the selected macro in the echo area.
524The ARG parameter is unused."
525  (interactive)
526  (unless (kmacro-ring-empty-p)
527    (kmacro-push-ring)
528    (let* ((keys (kmacro-get-repeat-prefix))
529	   (len (length kmacro-ring))
530	   (tail (nthcdr (- len 2) kmacro-ring))
531	   (elt (car (cdr tail))))
532      (setcdr tail nil)
533      (kmacro-split-ring-element elt)
534      (kmacro-display last-kbd-macro t)
535      (if keys
536	  (kmacro-repeat-on-last-key keys)))))
537
538(put 'kmacro-cycle-ring-next 'kmacro-repeat 'ring)
539
540
541(defun kmacro-cycle-ring-previous (&optional _arg)
542  "Move to previous keyboard macro in keyboard macro ring.
543Displays the selected macro in the echo area.
544The ARG parameter is unused."
545  (interactive)
546  (unless (kmacro-ring-empty-p)
547    (let ((keys (kmacro-get-repeat-prefix))
548	  (cur (kmacro-ring-head)))
549      (kmacro-pop-ring1)
550      (if kmacro-ring
551	  (nconc kmacro-ring (list cur))
552	(setq kmacro-ring (list cur)))
553      (kmacro-display last-kbd-macro t)
554      (if keys
555	  (kmacro-repeat-on-last-key keys)))))
556
557(put 'kmacro-cycle-ring-previous 'kmacro-repeat 'ring)
558
559
560(defun kmacro-swap-ring ()
561  "Swap first two elements on keyboard macro ring."
562  (interactive)
563  (unless (kmacro-ring-empty-p)
564    (let ((cur (kmacro-ring-head)))
565      (kmacro-pop-ring1)
566      (kmacro-push-ring cur))
567    (kmacro-display last-kbd-macro t)))
568
569
570(defun kmacro-delete-ring-head (&optional _arg)
571  "Delete current macro from keyboard macro ring.
572The ARG parameter is unused."
573  (interactive)
574  (unless (kmacro-ring-empty-p t)
575    (if (null kmacro-ring)
576	(setq last-kbd-macro nil)
577      (kmacro-pop-ring))
578    (kmacro-display last-kbd-macro t nil "Keyboard macro ring is now empty.")))
579
580(put 'kmacro-delete-ring-head 'kmacro-repeat 'head)
581
582;;; Traditional bindings:
583
584
585;;;###autoload
586(defun kmacro-start-macro (arg)
587  "Record subsequent keyboard input, defining a keyboard macro.
588The commands are recorded even as they are executed.
589Use \\[kmacro-end-macro] to finish recording and make the macro available.
590Use \\[kmacro-end-and-call-macro] to execute the macro.
591
592Non-nil arg (prefix arg) means append to last macro defined.
593
594With \\[universal-argument] prefix, append to last keyboard macro
595defined.  Depending on `kmacro-execute-before-append', this may begin
596by re-executing the last macro as if you typed it again.
597
598Otherwise, it sets `kmacro-counter' to ARG or 0 if missing before
599defining the macro.
600
601Use \\[kmacro-insert-counter] to insert (and increment) the macro counter.
602The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter].
603The format of the counter can be modified via \\[kmacro-set-format].
604
605Use \\[kmacro-name-last-macro] to give it a name that will remain valid even
606after another macro is defined.
607Use \\[kmacro-bind-to-key] to bind it to a key sequence."
608  (interactive "P")
609  (if (or defining-kbd-macro executing-kbd-macro)
610      (message "Already defining keyboard macro.")
611    (let ((append (and arg (listp arg))))
612      (unless append
613	(if last-kbd-macro
614	    (kmacro-push-ring
615	     (list last-kbd-macro kmacro-counter kmacro-counter-format-start)))
616	(setq kmacro-counter (or (if arg (prefix-numeric-value arg))
617				 kmacro-initial-counter-value
618				 0)
619	      kmacro-initial-counter-value nil
620	      kmacro-counter-value-start kmacro-counter
621	      kmacro-last-counter kmacro-counter
622	      kmacro-counter-format kmacro-default-counter-format
623	      kmacro-counter-format-start kmacro-default-counter-format))
624
625      (start-kbd-macro append
626		       (and append
627			    (if kmacro-execute-before-append
628				(> (car arg) 4)
629			      (= (car arg) 4))))
630      (if (and defining-kbd-macro append)
631	  (setq defining-kbd-macro 'append)))))
632
633
634;;;###autoload
635(defun kmacro-end-macro (arg)
636  "Finish defining a keyboard macro.
637The definition was started by \\[kmacro-start-macro].
638The macro is now available for use via \\[kmacro-call-macro],
639or it can be given a name with \\[kmacro-name-last-macro] and then invoked
640under that name.
641
642With numeric arg, repeat macro now that many times,
643counting the definition just completed as the first repetition.
644An argument of zero means repeat until error."
645  (interactive "P")
646   ;; Isearch may push the kmacro-end-macro key sequence onto the macro.
647   ;; Just ignore it when executing the macro.
648  (unless executing-kbd-macro
649    (end-kbd-macro arg #'kmacro-loop-setup-function)
650    (when (and last-kbd-macro (= (length last-kbd-macro) 0))
651      (setq last-kbd-macro nil)
652      (message "Ignore empty macro")
653      ;; Don't call `kmacro-ring-empty-p' to avoid its messages.
654      (while (and (null last-kbd-macro) kmacro-ring)
655	(kmacro-pop-ring1)))))
656
657
658;;;###autoload
659(defun kmacro-call-macro (arg &optional no-repeat end-macro macro)
660  "Call the keyboard MACRO that you defined with \\[kmacro-start-macro].
661A prefix argument serves as a repeat count.  Zero means repeat until error.
662MACRO defaults to `last-kbd-macro'.
663
664When you call the macro, you can call the macro again by repeating
665just the last key in the key sequence that you used to call this
666command.  See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg'
667for details on how to adjust or disable this behavior.
668
669To give a macro a name so you can call it even after defining others,
670use \\[kmacro-name-last-macro]."
671  (interactive "p")
672  (let ((repeat-key (and (or (and (null no-repeat)
673                                  (> (length (this-single-command-keys)) 1))
674                             ;; Used when we're in the process of repeating.
675                             (eq no-repeat 'repeating))
676			 last-input-event)))
677    (if end-macro
678	(kmacro-end-macro arg)		; modifies last-kbd-macro
679      (let ((last-kbd-macro (or macro last-kbd-macro)))
680	(call-last-kbd-macro arg #'kmacro-loop-setup-function)))
681    (when (consp arg)
682      (setq arg (car arg)))
683    (when (and (or (null arg) (> arg 0))
684	       (setq repeat-key
685		     (if (eq kmacro-call-repeat-key t)
686			 repeat-key
687		       kmacro-call-repeat-key)))
688      ;; Issue a hint to the user, if the echo area isn't in use.
689      (unless (current-message)
690	(message "(Type %s to repeat macro%s)"
691		 (format-kbd-macro (vector repeat-key) nil)
692		 (if (and kmacro-call-repeat-with-arg
693			  arg (> arg 1))
694		     (format " %d times" arg) "")))
695      ;; Can't use the `keep-pred' arg because this overlay keymap
696      ;; needs to be removed during the next run of the kmacro
697      ;; (i.e. we must add and remove this map at each repetition).
698      (set-transient-map
699       (let ((map (make-sparse-keymap)))
700         (define-key map (vector repeat-key)
701           (let ((ra (and kmacro-call-repeat-with-arg arg))
702                 (m (if end-macro
703			last-kbd-macro
704		      (or macro last-kbd-macro))))
705             (lambda ()
706               (interactive)
707               (kmacro-call-macro ra 'repeating nil m))))
708         map)))))
709
710
711;;; Combined function key bindings:
712
713;;;###autoload
714(defun kmacro-start-macro-or-insert-counter (arg)
715  "Record subsequent keyboard input, defining a keyboard macro.
716The commands are recorded even as they are executed.
717
718Initializes the macro's `kmacro-counter' to ARG (or 0 if no prefix arg)
719before defining the macro.
720
721With \\[universal-argument], appends to current keyboard macro (keeping
722the current value of `kmacro-counter').
723
724When used during defining/executing a macro, inserts the current value
725of `kmacro-counter' and increments the counter value by ARG (or by 1 if no
726prefix argument).  With just \\[universal-argument], inserts the previous
727value of `kmacro-counter', and does not modify the counter; this is
728different from incrementing the counter by zero.  (The previous value
729of the counter is the one it had before the last increment.)
730
731The macro counter can be set directly via \\[kmacro-set-counter] and \\[kmacro-add-counter].
732The format of the inserted value of the counter can be controlled
733via \\[kmacro-set-format]."
734  (interactive "P")
735  (if (or defining-kbd-macro executing-kbd-macro)
736      (kmacro-insert-counter arg)
737    (kmacro-start-macro arg)))
738
739
740;;;###autoload
741(defun kmacro-end-or-call-macro (arg &optional no-repeat)
742  "End kbd macro if currently being defined; else call last kbd macro.
743With numeric prefix ARG, repeat macro that many times.
744With \\[universal-argument], call second macro in macro ring."
745  (interactive "P")
746  (cond
747   (defining-kbd-macro
748     (if kmacro-call-repeat-key
749	 (kmacro-call-macro arg no-repeat t)
750       (kmacro-end-macro arg)))
751   ((and (eq this-command 'kmacro-view-macro)  ;; We are in repeat mode!
752	 kmacro-view-last-item)
753    (kmacro-exec-ring-item (car kmacro-view-last-item) arg))
754   ((and arg (listp arg))
755    (kmacro-call-ring-2nd 1))
756   (t
757    (kmacro-call-macro arg no-repeat))))
758
759
760(defun kmacro-end-or-call-macro-repeat (arg)
761  "As `kmacro-end-or-call-macro' but allow repeat without repeating prefix."
762  (interactive "P")
763  (let ((keys (kmacro-get-repeat-prefix)))
764    (kmacro-end-or-call-macro arg t)
765    (if keys
766	(kmacro-repeat-on-last-key keys))))
767
768(put 'kmacro-end-or-call-macro-repeat 'kmacro-repeat 'head)
769
770
771;;;###autoload
772(defun kmacro-end-and-call-macro (arg &optional no-repeat)
773  "Call last keyboard macro, ending it first if currently being defined.
774With numeric prefix ARG, repeat macro that many times.
775Zero argument means repeat until there is an error.
776
777To give a macro a name, so you can call it even after defining other
778macros, use \\[kmacro-name-last-macro]."
779  (interactive "P")
780  (if defining-kbd-macro
781      (kmacro-end-macro nil))
782  (kmacro-call-macro arg no-repeat))
783
784
785;;;###autoload
786(defun kmacro-end-call-mouse (event)
787  "Move point to the position clicked with the mouse and call last kbd macro.
788If kbd macro currently being defined end it before activating it."
789  (interactive "e")
790  (when defining-kbd-macro
791    (end-kbd-macro)
792    (when (and last-kbd-macro (= (length last-kbd-macro) 0))
793      (setq last-kbd-macro nil)
794      (message "Ignore empty macro")
795      ;; Don't call `kmacro-ring-empty-p' to avoid its messages.
796      (while (and (null last-kbd-macro) kmacro-ring)
797        (kmacro-pop-ring1))))
798  (mouse-set-point event)
799  (kmacro-call-macro nil t))
800
801
802;;; Misc. commands
803
804;; An idea for macro bindings:
805;; Create a separate keymap installed as a minor-mode keymap (e.g. in
806;; the emulation-mode-map-alists) in which macro bindings are made
807;; independent of any other bindings.  When first binding is made,
808;; the keymap is created, installed, and enabled.  Key seq. C-x C-k +
809;; can then be used to toggle the use of this keymap on and off.
810;; This means that it would be safe(r) to bind ordinary keys like
811;; letters and digits, provided that we inhibit the keymap while
812;; executing the macro later on (but that's controversial...)
813
814;;;###autoload
815(defun kmacro-lambda-form (mac &optional counter format)
816  "Create lambda form for macro bound to symbol or key."
817  ;; Apparently, there are two different ways this is called:
818  ;; either `counter' and `format' are both provided and `mac' is a vector,
819  ;; or only `mac' is provided, as a list (MAC COUNTER FORMAT).
820  ;; The first is used from `insert-kbd-macro' and `edmacro-finish-edit',
821  ;; while the second is used from within this file.
822  (let ((mac (if counter (list mac counter format) mac)))
823    ;; FIXME: This should be a "funcallable struct"!
824    (lambda (&optional arg)
825      "Keyboard macro."
826      ;; We put an "unused prompt" as a special marker so
827      ;; `kmacro-extract-lambda' can see it's "one of us".
828      (interactive "pkmacro")
829      (if (eq arg 'kmacro--extract-lambda)
830          (cons 'kmacro--extract-lambda mac)
831        (kmacro-exec-ring-item mac arg)))))
832
833(defun kmacro-extract-lambda (mac)
834  "Extract kmacro from a kmacro lambda form."
835  (let ((mac (cond
836              ((eq (car-safe mac) 'lambda)
837               (let ((e (assoc 'kmacro-exec-ring-item mac)))
838                 (car-safe (cdr-safe (car-safe (cdr-safe e))))))
839              ((and (functionp mac)
840                    (equal (interactive-form mac) '(interactive "pkmacro")))
841               (let ((r (funcall mac 'kmacro--extract-lambda)))
842                 (and (eq (car-safe r) 'kmacro--extract-lambda) (cdr r)))))))
843    (and (consp mac)
844         (= (length mac) 3)
845         (arrayp (car mac))
846         mac)))
847
848(defalias 'kmacro-p #'kmacro-extract-lambda
849  "Return non-nil if MAC is a kmacro keyboard macro.")
850
851(defun kmacro-bind-to-key (_arg)
852  "When not defining or executing a macro, offer to bind last macro to a key.
853The key sequences `C-x C-k 0' through `C-x C-k 9' and `C-x C-k A'
854through `C-x C-k Z' are reserved for user bindings, and to bind to
855one of these sequences, just enter the digit or letter, rather than
856the whole sequence.
857
858You can bind to any valid key sequence, but if you try to bind to
859a key with an existing command binding, you will be asked for
860confirmation whether to replace that binding.  Note that the
861binding is made in the `global-map' keymap, so the macro binding
862may be shaded by a local key binding.
863The ARG parameter is unused."
864  (interactive "p")
865  (if (or defining-kbd-macro executing-kbd-macro)
866      (if defining-kbd-macro
867	  (message "Cannot save macro while defining it."))
868    (unless last-kbd-macro
869      (error "No keyboard macro defined"))
870    (let ((key-seq (read-key-sequence "Bind last macro to key: "))
871	  ok cmd)
872      (when (= (length key-seq) 1)
873	(let ((ch (aref key-seq 0)))
874	  (if (and (integerp ch)
875		   (or (and (>= ch ?0) (<= ch ?9))
876		       (and (>= ch ?A) (<= ch ?Z))))
877	      (setq key-seq (concat "\C-x\C-k" key-seq)
878		    ok t))))
879      (when (and (not (equal key-seq "\^G"))
880		 (or ok
881		     (not (setq cmd (key-binding key-seq)))
882		     (stringp cmd)
883		     (vectorp cmd)
884		     (yes-or-no-p (format "%s runs command %S.  Bind anyway? "
885					  (format-kbd-macro key-seq)
886					  cmd))))
887	(define-key global-map key-seq
888	  (kmacro-lambda-form (kmacro-ring-head)))
889	(message "Keyboard macro bound to %s" (format-kbd-macro key-seq))))))
890
891(defun kmacro-keyboard-macro-p (symbol)
892  "Return non-nil if SYMBOL is the name of some sort of keyboard macro."
893  (let ((f (symbol-function symbol)))
894    (when f
895      (or (stringp f)
896	  (vectorp f)
897	  (kmacro-p f)))))
898
899(defun kmacro-name-last-macro (symbol)
900  "Assign a name to the last keyboard macro defined.
901Argument SYMBOL is the name to define.
902The symbol's function definition becomes the keyboard macro string.
903Such a \"function\" cannot be called from Lisp, but it is a valid editor command."
904  (interactive "SName for last kbd macro: ")
905  (or last-kbd-macro
906      (error "No keyboard macro defined"))
907  (and (fboundp symbol)
908       (not (kmacro-keyboard-macro-p symbol))
909       (error "Function %s is already defined and not a keyboard macro"
910	      symbol))
911  (if (string-equal symbol "")
912      (error "No command name given"))
913  ;; FIXME: Use plain old `last-kbd-macro' for kmacros where it doesn't
914  ;; make a difference?
915  (fset symbol (kmacro-lambda-form (kmacro-ring-head)))
916  ;; This used to be used to detect when a symbol corresponds to a kmacro.
917  ;; Nowadays it's unused because we used `kmacro-p' instead to see if the
918  ;; symbol's function definition matches that of a kmacro, which is more
919  ;; reliable.
920  (put symbol 'kmacro t))
921
922
923(cl-defstruct (kmacro-register
924               (:constructor nil)
925               (:constructor kmacro-make-register (macro)))
926  macro)
927
928(cl-defmethod register-val-jump-to ((data kmacro-register) _arg)
929  (kmacro-call-macro current-prefix-arg nil nil (kmacro-register-macro data)))
930
931(cl-defmethod register-val-describe ((data kmacro-register) _verbose)
932  (princ (format "a keyboard macro:\n   %s"
933		 (format-kbd-macro (kmacro-register-macro data)))))
934
935(cl-defmethod register-val-insert ((data kmacro-register))
936  (insert (format-kbd-macro (kmacro-register-macro data))))
937
938(defun kmacro-to-register (r)
939  "Store the last keyboard macro in register R.
940
941Interactively, reads the register using `register-read-with-preview'."
942  (interactive
943   (progn
944     (or last-kbd-macro (error "No keyboard macro defined"))
945     (list (register-read-with-preview "Save to register: "))))
946  (set-register r (kmacro-make-register last-kbd-macro)))
947
948
949(defun kmacro-view-macro (&optional _arg)
950  "Display the last keyboard macro.
951If repeated, it shows previous elements in the macro ring.
952The ARG parameter is unused."
953  (interactive)
954  (cond
955   ((or (kmacro-ring-empty-p)
956	(not (eq last-command 'kmacro-view-macro)))
957    (setq kmacro-view-last-item nil))
958   ((null kmacro-view-last-item)
959    (setq kmacro-view-last-item kmacro-ring
960	  kmacro-view-item-no 2))
961   ((consp kmacro-view-last-item)
962    (setq kmacro-view-last-item (cdr kmacro-view-last-item)
963	  kmacro-view-item-no (1+ kmacro-view-item-no)))
964   (t
965    (setq kmacro-view-last-item nil)))
966  (setq this-command 'kmacro-view-macro
967	last-command this-command) ;; in case we repeat
968  (kmacro-display (if kmacro-view-last-item
969		      (car (car kmacro-view-last-item))
970		    last-kbd-macro)
971		  nil
972		  (if kmacro-view-last-item
973		      (concat (cond ((= kmacro-view-item-no 2) "2nd")
974				    ((= kmacro-view-item-no 3) "3rd")
975				    (t (format "%dth" kmacro-view-item-no)))
976			      " previous macro")
977		    "Last macro")))
978
979(defun kmacro-view-macro-repeat (&optional arg)
980  "Display the last keyboard macro.
981If repeated, it shows previous elements in the macro ring.
982To execute the displayed macro ring item without changing the macro ring,
983just enter C-k.
984This is like `kmacro-view-macro', but allows repeating macro commands
985without repeating the prefix."
986  (interactive)
987  (let ((keys (kmacro-get-repeat-prefix)))
988    (kmacro-view-macro arg)
989    (if (and last-kbd-macro keys)
990	(kmacro-repeat-on-last-key keys))))
991
992(put 'kmacro-view-macro-repeat 'kmacro-repeat 'ring)
993
994
995(defun kmacro-edit-macro-repeat (&optional arg)
996  "Edit last keyboard macro."
997  (interactive "P")
998  (edit-kbd-macro "\r" arg))
999
1000(put 'kmacro-edit-macro-repeat 'kmacro-repeat 'stop)
1001
1002
1003(defun kmacro-edit-macro (&optional arg)
1004  "As edit last keyboard macro, but without kmacro-repeat property."
1005  (interactive "P")
1006  (edit-kbd-macro "\r" arg))
1007
1008
1009(defun kmacro-edit-lossage ()
1010  "Edit most recent 300 keystrokes as a keyboard macro."
1011  (interactive)
1012  (kmacro-push-ring)
1013  (edit-kbd-macro (car (where-is-internal 'view-lossage))))
1014
1015
1016;;; Single-step editing of keyboard macros
1017
1018(defvar kmacro-step-edit-active nil)  	 ;; step-editing active
1019(defvar kmacro-step-edit-new-macro)  	 ;; storage for new macro
1020(defvar kmacro-step-edit-inserting)  	 ;; inserting into macro
1021(defvar kmacro-step-edit-appending)  	 ;; append to end of macro
1022(defvar kmacro-step-edit-replace)    	 ;; replace orig macro when done
1023(defvar kmacro-step-edit-key-index)      ;; index of current key
1024(defvar kmacro-step-edit-action)     	 ;; automatic action on next pre-command hook
1025(defvar kmacro-step-edit-help)     	 ;; kmacro step edit help enabled
1026(defvar kmacro-step-edit-num-input-keys) ;; to ignore duplicate pre-command hook
1027
1028(defvar kmacro-step-edit-map
1029  (let ((map (make-sparse-keymap)))
1030    ;; query-replace-map answers include: `act', `skip', `act-and-show',
1031    ;; `exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
1032    ;; `automatic', `backup', `exit-prefix', and `help'.")
1033    ;; Also: `quit', `edit-replacement'
1034
1035    (set-keymap-parent map query-replace-map)
1036
1037    (define-key map "\t" 'act-repeat)
1038    (define-key map [tab] 'act-repeat)
1039    (define-key map "\C-k" 'skip-rest)
1040    (define-key map "c" 'automatic)
1041    (define-key map "f" 'skip-keep)
1042    (define-key map "q" 'quit)
1043    (define-key map "d" 'skip)
1044    (define-key map "\C-d" 'skip)
1045    (define-key map "i" 'insert)
1046    (define-key map "I" 'insert-1)
1047    (define-key map "r" 'replace)
1048    (define-key map "R" 'replace-1)
1049    (define-key map "a" 'append)
1050    (define-key map "A" 'append-end)
1051    map)
1052  "Keymap that defines the responses to questions in `kmacro-step-edit-macro'.
1053This keymap is an extension to the `query-replace-map', allowing the
1054following additional answers: `insert', `insert-1', `replace', `replace-1',
1055`append', `append-end', `act-repeat', `skip-end', `skip-keep'.")
1056
1057(defun kmacro-step-edit-prompt (macro index)
1058  ;; Show step-edit prompt
1059  (let ((keys (and (not kmacro-step-edit-appending)
1060		   index (substring macro index executing-kbd-macro-index)))
1061	(future (and (not kmacro-step-edit-appending)
1062		     (substring macro executing-kbd-macro-index)))
1063	(message-log-max nil)
1064	(curmsg (current-message)))
1065
1066    ;; TODO: Scroll macro if max-mini-window-height is too small.
1067    (message "%s"
1068	     (concat
1069	      (format "Macro: %s%s%s%s%s\n"
1070		      (format-kbd-macro kmacro-step-edit-new-macro 1)
1071		      (if (and kmacro-step-edit-new-macro (> (length kmacro-step-edit-new-macro) 0)) " " "")
1072		      (propertize (if keys (format-kbd-macro keys)
1073				    (if kmacro-step-edit-appending "<APPEND>" "<INSERT>")) 'face 'region)
1074		      (if future " " "")
1075		      (if future (format-kbd-macro future) ""))
1076	      (cond
1077	       ((minibufferp)
1078		(format "%s\n%s\n"
1079			  (propertize "\
1080                         minibuffer                             " 'face 'header-line)
1081			  (buffer-substring (point-min) (point-max))))
1082	       (curmsg
1083		(format "%s\n%s\n"
1084			(propertize "\
1085                         echo area                              " 'face 'header-line)
1086			curmsg))
1087	       (t ""))
1088	      (if keys
1089		  (format "%s\n%s%s %S [yn iIaArR C-k kq!] "
1090			  (propertize "\
1091--------------Step Edit Keyboard Macro  [?: help]---------------" 'face 'mode-line)
1092			  (if kmacro-step-edit-help "\
1093 Step: y/SPC: execute next,  d/n/DEL: skip next,  f: skip but keep
1094       TAB: execute while same,  ?: toggle help
1095 Edit: i: insert,  r: replace,  a: append,  A: append at end,
1096       I/R: insert/replace with one sequence,
1097 End:  !/c: execute rest,  C-k: skip rest and save,  q/C-g: quit
1098----------------------------------------------------------------
1099" "")
1100			  (propertize "Next command:" 'face 'bold)
1101			  this-command)
1102		(propertize
1103		 (format "Type key sequence%s to insert and execute%s: "
1104			 (if (numberp kmacro-step-edit-inserting) ""  "s")
1105			 (if (numberp kmacro-step-edit-inserting) ""  " (end with C-j)"))
1106		 'face 'bold))))))
1107
1108(defun kmacro-step-edit-query ()
1109  ;; Pre-command hook function for step-edit in "command" mode
1110  (let ((resize-mini-windows t)
1111	(max-mini-window-height kmacro-step-edit-mini-window-height)
1112	act restore-index next-index)
1113
1114    ;; Handle commands which reads additional input using read-char.
1115    (cond
1116     ((and (eq this-command 'quoted-insert)
1117	   (not (eq kmacro-step-edit-action t)))
1118      ;; Find the actual end of this key sequence.
1119      ;; Must be able to backtrack in case we actually execute it.
1120      (setq restore-index executing-kbd-macro-index)
1121      (let (unread-command-events)
1122	(quoted-insert 0)
1123	(when unread-command-events
1124	  (setq executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events))
1125		next-index executing-kbd-macro-index)))))
1126
1127    ;; Query the user; stop macro execution temporarily.
1128    (let ((macro executing-kbd-macro)
1129	  (executing-kbd-macro nil)
1130	  (defining-kbd-macro nil))
1131
1132      ;; Any action requested by previous command
1133      (cond
1134       ((eq kmacro-step-edit-action t)  ;; Reentry for actual command @ end of prefix arg.
1135	(cond
1136	 ((eq this-command 'quoted-insert)
1137	  (clear-this-command-keys) ;; recent-keys actually
1138	  (let (unread-command-events)
1139	    (quoted-insert (prefix-numeric-value current-prefix-arg))
1140	    (setq kmacro-step-edit-new-macro
1141		  (vconcat kmacro-step-edit-new-macro (recent-keys)))
1142	    (when unread-command-events
1143	      (setq kmacro-step-edit-new-macro
1144		    (substring kmacro-step-edit-new-macro 0 (- (length unread-command-events)))
1145		    executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events)))))
1146	  (setq current-prefix-arg nil
1147		prefix-arg nil)
1148	  (setq act 'ignore))
1149	 (t
1150	  (setq act 'act)))
1151	(setq kmacro-step-edit-action nil))
1152       ((eq this-command kmacro-step-edit-action)  ;; TAB -> activate while same command
1153	(setq act 'act))
1154       (t
1155	(setq kmacro-step-edit-action nil)))
1156
1157      ;; Handle prefix arg, or query user
1158      (cond
1159       (act act) ;; set above
1160       (t
1161	(kmacro-step-edit-prompt macro kmacro-step-edit-key-index)
1162	(setq act (lookup-key kmacro-step-edit-map
1163			      (vector (with-current-buffer (current-buffer) (read-event))))))))
1164
1165    ;; Resume macro execution and perform the action
1166    (cond
1167     ((cond
1168       ((eq act 'act)
1169	t)
1170       ((eq act 'act-repeat)
1171	(setq kmacro-step-edit-action this-command)
1172	t)
1173       ((eq act 'quit)
1174	(setq kmacro-step-edit-replace nil)
1175	(setq kmacro-step-edit-active 'ignore)
1176	nil)
1177       ((eq act 'skip)
1178	nil)
1179       ((eq act 'skip-keep)
1180	(setq this-command 'ignore)
1181	t)
1182       ((eq act 'skip-rest)
1183	(setq kmacro-step-edit-active 'ignore)
1184	nil)
1185       ((memq act '(automatic exit))
1186	(setq kmacro-step-edit-active nil)
1187	(setq act t)
1188	t)
1189       ((member act '(insert-1 insert))
1190	(setq executing-kbd-macro-index kmacro-step-edit-key-index)
1191	(setq kmacro-step-edit-inserting (if (eq act 'insert-1) 1 t))
1192	nil)
1193       ((member act '(replace-1 replace))
1194	(setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t))
1195	(if (= executing-kbd-macro-index (length executing-kbd-macro))
1196	    (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
1197		  kmacro-step-edit-appending t))
1198	nil)
1199       ((eq act 'append)
1200	(setq kmacro-step-edit-inserting t)
1201	(if (= executing-kbd-macro-index (length executing-kbd-macro))
1202	    (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
1203		  kmacro-step-edit-appending t))
1204	t)
1205       ((eq act 'append-end)
1206	(if (= executing-kbd-macro-index (length executing-kbd-macro))
1207	    (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
1208		  kmacro-step-edit-inserting t
1209		  kmacro-step-edit-appending t)
1210	  (setq kmacro-step-edit-active 'append-end))
1211	(setq act t)
1212	t)
1213       ((eq act 'help)
1214	(setq executing-kbd-macro-index kmacro-step-edit-key-index)
1215	(setq kmacro-step-edit-help (not kmacro-step-edit-help))
1216	nil)
1217       (t ;; Ignore unknown responses
1218	(setq executing-kbd-macro-index kmacro-step-edit-key-index)
1219	nil))
1220      (if (> executing-kbd-macro-index kmacro-step-edit-key-index)
1221	  (setq kmacro-step-edit-new-macro
1222		(vconcat kmacro-step-edit-new-macro
1223			 (substring executing-kbd-macro
1224				    kmacro-step-edit-key-index
1225				    (if (eq act t) nil
1226                                      executing-kbd-macro-index)))))
1227      (if restore-index
1228	  (setq executing-kbd-macro-index restore-index)))
1229     (t
1230      (setq this-command 'ignore)))
1231    (setq kmacro-step-edit-key-index next-index)))
1232
1233(defun kmacro-step-edit-insert ()
1234  ;; Pre-command hook function for step-edit in "insert" mode
1235  (let ((resize-mini-windows t)
1236	(max-mini-window-height kmacro-step-edit-mini-window-height)
1237	(macro executing-kbd-macro)
1238	(executing-kbd-macro nil)
1239	(defining-kbd-macro nil)
1240	cmd keys next-index)
1241    (setq executing-kbd-macro-index kmacro-step-edit-key-index)
1242    (kmacro-step-edit-prompt macro nil)
1243    ;; Now, we have read a key sequence from the macro, but we don't want
1244    ;; to execute it yet.  So push it back and read another sequence.
1245    (setq keys (read-key-sequence nil nil nil nil t))
1246    (setq cmd (key-binding keys t nil))
1247    (if (cond
1248	 ((null cmd)
1249	  t)
1250	 ((eq cmd 'quoted-insert)
1251	  (clear-this-command-keys) ;; recent-keys actually
1252	  (quoted-insert (prefix-numeric-value current-prefix-arg))
1253	  (setq current-prefix-arg nil
1254		prefix-arg nil)
1255	  (setq keys (vconcat keys (recent-keys)))
1256	  (when (numberp kmacro-step-edit-inserting)
1257	    (setq kmacro-step-edit-inserting nil)
1258	    (when unread-command-events
1259	      (setq keys (substring keys 0 (- (length unread-command-events)))
1260		    executing-kbd-macro-index (- executing-kbd-macro-index (length unread-command-events))
1261		    next-index executing-kbd-macro-index
1262		    unread-command-events nil)))
1263	  (setq cmd 'ignore)
1264	  nil)
1265	 ((numberp kmacro-step-edit-inserting)
1266	  (setq kmacro-step-edit-inserting nil)
1267	  nil)
1268	 ((equal keys "\C-j")
1269	  (setq kmacro-step-edit-inserting nil)
1270	  (setq kmacro-step-edit-action nil)
1271	  (setq next-index kmacro-step-edit-key-index)
1272	  t)
1273	 (t nil))
1274	(setq this-command 'ignore)
1275      (setq this-command cmd)
1276      (if (memq this-command '(self-insert-command digit-argument))
1277	  (setq last-command-event (aref keys (1- (length keys)))))
1278      (if keys
1279	  (setq kmacro-step-edit-new-macro (vconcat kmacro-step-edit-new-macro keys))))
1280    (setq kmacro-step-edit-key-index next-index)))
1281
1282(defun kmacro-step-edit-pre-command ()
1283  (remove-hook 'post-command-hook #'kmacro-step-edit-post-command)
1284  (when kmacro-step-edit-active
1285    (cond
1286     ((eq kmacro-step-edit-active 'ignore)
1287      (setq this-command 'ignore))
1288     ((eq kmacro-step-edit-active 'append-end)
1289      (if (= executing-kbd-macro-index (length executing-kbd-macro))
1290	  (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
1291		kmacro-step-edit-inserting t
1292		kmacro-step-edit-appending t
1293		kmacro-step-edit-active t)))
1294     ((/= kmacro-step-edit-num-input-keys num-input-keys)
1295      (if kmacro-step-edit-inserting
1296	  (kmacro-step-edit-insert)
1297	(kmacro-step-edit-query))
1298      (setq kmacro-step-edit-num-input-keys num-input-keys)
1299      (if (and kmacro-step-edit-appending (not kmacro-step-edit-inserting))
1300	  (setq kmacro-step-edit-appending nil
1301		kmacro-step-edit-active 'ignore)))))
1302  (when (eq kmacro-step-edit-active t)
1303    (add-hook 'post-command-hook #'kmacro-step-edit-post-command t)))
1304
1305(defun kmacro-step-edit-minibuf-setup ()
1306  (remove-hook 'pre-command-hook #'kmacro-step-edit-pre-command t)
1307  (when kmacro-step-edit-active
1308    (add-hook 'pre-command-hook #'kmacro-step-edit-pre-command nil t)))
1309
1310(defun kmacro-step-edit-post-command ()
1311  (remove-hook 'pre-command-hook #'kmacro-step-edit-pre-command)
1312  (when kmacro-step-edit-active
1313    (add-hook 'pre-command-hook #'kmacro-step-edit-pre-command nil nil)
1314    (if kmacro-step-edit-key-index
1315	(setq executing-kbd-macro-index kmacro-step-edit-key-index)
1316      (setq kmacro-step-edit-key-index executing-kbd-macro-index))))
1317
1318
1319(defun kmacro-step-edit-macro ()
1320  "Step edit and execute last keyboard macro.
1321
1322To customize possible responses, change the \"bindings\" in
1323`kmacro-step-edit-map'."
1324  (interactive)
1325  (let ((kmacro-step-edit-active t)
1326	(kmacro-step-edit-new-macro "")
1327	(kmacro-step-edit-inserting nil)
1328	(kmacro-step-edit-appending nil)
1329	(kmacro-step-edit-replace t)
1330	(kmacro-step-edit-key-index 0)
1331	(kmacro-step-edit-action nil)
1332	(kmacro-step-edit-help nil)
1333	(kmacro-step-edit-num-input-keys num-input-keys)
1334	(pre-command-hook pre-command-hook)
1335	(post-command-hook post-command-hook)
1336	(minibuffer-setup-hook minibuffer-setup-hook))
1337    (add-hook 'pre-command-hook #'kmacro-step-edit-pre-command nil)
1338    (add-hook 'post-command-hook #'kmacro-step-edit-post-command t)
1339    (add-hook 'minibuffer-setup-hook #'kmacro-step-edit-minibuf-setup t)
1340    (call-last-kbd-macro nil nil)
1341    (when (and kmacro-step-edit-replace
1342	       kmacro-step-edit-new-macro
1343	       (not (equal last-kbd-macro kmacro-step-edit-new-macro)))
1344      (kmacro-push-ring)
1345      (setq last-kbd-macro kmacro-step-edit-new-macro))))
1346
1347(defun kdb-macro-redisplay ()
1348  "Force redisplay during kbd macro execution."
1349  (interactive)
1350  (or executing-kbd-macro
1351      defining-kbd-macro
1352      (user-error "Not defining or executing kbd macro"))
1353  (when executing-kbd-macro
1354    (let ((executing-kbd-macro nil))
1355      (redisplay))))
1356
1357(provide 'kmacro)
1358
1359;;; kmacro.el ends here
1360