Passed it through checkdoc. Moved `provide' to the end, where it belongs.
[emacs.git] / lisp / kmacro.el
blobc1d8938649712b4b077f5ca88e8db375e4e6fa2e
1 ;;; kmacro.el --- enhanced keyboard macros
3 ;; Copyright (C) 2002 Free Software Foundation, Inc.
5 ;; Author: Kim F. Storm <storm@cua.dk>
6 ;; Keywords: keyboard convenience
8 ;; This file is part of GNU Emacs.
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 2, or (at your option)
13 ;; any later version.
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.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;; Commentary:
27 ;; The kmacro package is an alternative user interface to emacs'
28 ;; keyboard macro functionality. This functionality is normally bound
29 ;; to C-x (, C-x ), and C-x e, but these bindings are too hard to
30 ;; type to be really useful for doing small repeated tasks.
32 ;; With kmacro, two function keys are dedicated to keyboard macros,
33 ;; by default F7 and F8. Personally, I prefer F1 and F2, but those
34 ;; keys already have default bindings.
36 ;; To start defining a keyboard macro, use F7. To end the macro,
37 ;; use F8, and to call the macro also use F8. This makes it very
38 ;; easy to repeat a macro immediately after defining it.
40 ;; You can call the macro repeatedly by pressing F8 multiple times, or
41 ;; you can give a numeric prefix argument specifying the number of
42 ;; times to repeat the macro. Macro execution automatically
43 ;; terminates when point reaches the end of the buffer or if an error
44 ;; is signalled by ringing the bell.
46 ;; If you enter F7 while defining the macro, the numeric value of
47 ;; `kmacro-counter' is inserted using the `kmacro-counter-format', and
48 ;; `kmacro-counter' is incremented by 1 (or the numeric prefix value
49 ;; of F7).
51 ;; The initial value of `kmacro-counter' is 0, or the numeric prefix
52 ;; value given to F7 when starting the macro.
54 ;; Now, each time you call the macro using F8, the current
55 ;; value of `kmacro-counter' is inserted and incremented, making it
56 ;; easy to insert incremental numbers in the buffer.
58 ;; Example:
60 ;; The following sequence: M-5 F7 x M-2 F7 y F8 F8 F8 F8
61 ;; inserts the following string: x5yx7yx9yx11y
63 ;; A macro can also be called using a mouse click, default S-mouse-3.
64 ;; This calls the macro at the point where you click the mouse.
66 ;; When you have defined another macro, which is thus called via F8,
67 ;; the previous macro is pushed onto a keyboard macro ring. The head
68 ;; macro on the ring can be executed using S-F8. You can cycle the
69 ;; macro ring using C-F8. You can also swap the last macro and the
70 ;; head of the macro ring using C-u F8.
72 ;; You can edit the last macro using M-F7.
74 ;; You can append to the last macro using C-u F7.
76 ;; You can set the macro counter using C-F7, and you can set
77 ;; the macro counter format with S-F7..
79 ;; The following key bindings are performed:
80 ;;
81 ;; Normal While defining macro
82 ;; --------------------------- ------------------------------
83 ;; f7 Define macro Insert current counter value
84 ;; Prefix arg specifies initial and increase counter by prefix
85 ;; counter value (default 0) (default increment: 1)
87 ;; C-u f7 APPENDs to last macro
88 ;;
89 ;; f8 Call last macro End macro
90 ;; Prefix arg specifies number
91 ;; of times to execute macro.
93 ;; C-u f8 Swap last and head of macro ring.
94 ;;
95 ;; S-f7 Set the format of the macro Ditto, but notice that the
96 ;; counter (default: %d). format is reset at the next
97 ;; invocation of the macro.
98 ;;
99 ;; C-f7 Set the macro counter value Increase/decrease counter value
100 ;; to the prefix value. by the prefix value, or if prefix
101 ;; is C-u, set counter to 0.
103 ;; M-f7 Edit the last macro.
105 ;; S-f8 Call the previous macro.
107 ;; C-f8 Cycle the macro ring.
109 ;; S-mouse-3 Set point at click and End macro and execute macro at
110 ;; execute last macro. click.
112 ;;; Code:
114 ;; Customization:
116 (defgroup kmacro nil
117 "Simplified keyboard macro user interface."
118 :group 'keyboard
119 :group 'convenience
120 :link '(emacs-commentary-link :tag "Commentary" "kmacro.el")
121 :link '(emacs-library-link :tag "Lisp File" "kmacro.el"))
123 ;;;###autoload
124 (defcustom kmacro-initialize nil
125 "Setting this variable turns on the kmacro functionality.
126 This binds the kmacro function keys in the `global-map', so
127 unsetting this variable does not have any effect!"
128 :set #'(lambda (symbol value)
129 (if value (kmacro-initialize))
130 (set symbol value))
131 :initialize 'custom-initialize-default
132 :require 'kmacro
133 :link '(emacs-commentary-link "kmacro.el")
134 :set-after '(kmacro-start-key kmacro-call-key kmacro-mouse-button)
135 :version "21.4"
136 :type 'boolean
137 :group 'kmacro)
139 (defcustom kmacro-start-key 'f7
140 "The function key used by kmacro to start a macro."
141 :type 'symbol
142 :group 'kmacro)
144 (defcustom kmacro-call-key 'f8
145 "The function key used by kmacro to end and call a macro."
146 :type 'symbol
147 :group 'kmacro)
149 (defcustom kmacro-call-mouse-event 'S-mouse-3
150 "The mouse event used by kmacro to call a macro."
151 :type 'symbol
152 :group 'kmacro)
154 ;; State variables
156 (defvar kmacro-counter 0
157 "*Current keyboard macro counter.")
159 (defvar kmacro-counter-format "%d"
160 "*Current keyboard macro counter format.")
162 (defvar kmacro-counter-format-start kmacro-counter-format
163 "Macro format at start of macro execution.")
165 (defvar kmacro-last-counter 0 "Last counter inserted by key macro.")
166 (defvar kmacro-append-to nil "Last key macro if appending to macro.")
167 (defvar kmacro-ring nil "Key macro ring.")
169 (defvar kmacro-ring-max 4
170 "*Maximum number of key macros to save in key macro ring.")
172 (defun kmacro-display (macro)
173 "Display a keyboard MACRO."
174 (let (s)
175 (if (stringp macro)
176 (setq s (if (> (length macro) 50)
177 (concat (substring macro 0 50) "...")
178 macro))
179 (if (vectorp macro)
180 (let (v (i 0) (n (length macro)))
181 (setq s "")
182 (while (and (< i n) (< (length s) 50))
183 (setq v (aref macro i))
184 (setq s (cond
185 ((numberp v) (concat s (char-to-string v)))
186 ((stringp v) (concat s v))
187 ((symbolp v) (concat s "[" (symbol-name v) "]"))
188 (t s)))
189 (setq i (1+ i)))
190 (if (< i n)
191 (setq s (concat s "..."))))))
192 (message (format "Macro: %s" s))))
195 (defun kmacro-start-macro (arg)
196 "Set `kmacro-counter' to ARG or 0 if missing, and `start-kbd-macro'.
197 With \\[universal-argument], append to current keyboard macro (keep kmacro-counter).
199 When defining/executing macro, insert macro counter and increment with
200 ARG or 1 if missing.
201 With \\[universal-argument], insert previous kmacro-counter (but do not modify counter).
203 The macro counter can be modified via \\[kmacro-set-counter].
204 The format of the counter can be modified via \\[kmacro-set-format]."
205 (interactive "p")
206 (if (or defining-kbd-macro executing-kbd-macro)
207 (if (and current-prefix-arg (listp current-prefix-arg))
208 (insert (format kmacro-counter-format kmacro-last-counter))
209 (insert (format kmacro-counter-format kmacro-counter))
210 (setq kmacro-last-counter kmacro-counter
211 kmacro-counter (+ kmacro-counter arg)))
212 (if (and current-prefix-arg (listp current-prefix-arg))
213 (setq kmacro-append-to last-kbd-macro)
214 (setq kmacro-append-to nil
215 kmacro-counter (if current-prefix-arg arg 0)
216 kmacro-last-counter kmacro-counter))
217 (if last-kbd-macro
218 (let ((len (length kmacro-ring)))
219 (setq kmacro-ring (cons last-kbd-macro kmacro-ring))
220 (if (>= len kmacro-ring-max)
221 (setcdr (nthcdr len kmacro-ring) nil))))
222 (setq kmacro-counter-format-start kmacro-counter-format)
223 (start-kbd-macro nil)
224 (if kmacro-append-to (message "Appending to keyboard macro..."))
227 (defun kmacro-call-macro (arg)
228 "End kbd macro if currently being defined; else call last kbd macro.
229 With numeric prefix ARG, repeat macro that many times.
230 With \\[universal-argument], swap current macro with head of macro ring."
231 (interactive "p")
232 (cond
233 (defining-kbd-macro
234 (end-kbd-macro)
235 (if kmacro-append-to
236 (setq last-kbd-macro (concat kmacro-append-to last-kbd-macro)
237 kmacro-append-to nil)))
238 ((and current-prefix-arg (listp current-prefix-arg))
239 (when kmacro-ring
240 (let ((head (car kmacro-ring)))
241 (setq kmacro-ring (cons last-kbd-macro (cdr kmacro-ring)))
242 (setq last-kbd-macro head)))
243 (kmacro-display last-kbd-macro))
245 (setq kmacro-counter-format kmacro-counter-format-start)
246 (call-last-kbd-macro arg))))
248 (defun kmacro-call-macro-ring (arg)
249 "End kbd macro if currently being defined; else call last kbd macro.
250 With \\[universal-argument], display current macro."
251 (interactive "p")
252 (if kmacro-ring
253 (execute-kbd-macro (car kmacro-ring) arg)))
255 (defun kmacro-end-call-mouse (event)
256 "Move point to the position clicked with the mouse and call last kbd macro.
257 If kbd macro currently being defined end it before activating it."
258 (interactive "e")
259 (when defining-kbd-macro
260 (end-kbd-macro)
261 (if kmacro-append-to
262 (setq last-kbd-macro (concat kmacro-append-to last-kbd-macro)
263 kmacro-append-to nil)))
264 (mouse-set-point event)
265 (call-last-kbd-macro nil))
267 (defun kmacro-cycle-macro-ring (&optional previous)
268 "Cycle the keyboard macro ring on \\[kmacro-call-macro-ring].
269 Moves to the next element in the keyboard macro ring.
270 With \\[universal-argument] prefix, move to the previous element in the ring.
271 Displays the selected macro in the echo area."
272 (interactive "p")
273 (if (null kmacro-ring)
274 (message "No keymacros in ring")
275 (cond
276 ((not (eq this-command last-command))
277 nil)
278 ((= (length kmacro-ring) 1)
279 nil)
280 (previous
281 (let* ((len (length kmacro-ring))
282 (tail (nthcdr (- len 2) kmacro-ring))
283 (elt (car (cdr tail))))
284 (setcdr tail nil)
285 (setq kmacro-ring (cons elt kmacro-ring))))
287 (let ((elt (car kmacro-ring)))
288 (setq kmacro-ring (cdr kmacro-ring))
289 (nconc kmacro-ring (list elt)))))
290 (kmacro-display (car kmacro-ring))))
292 (defun kmacro-save-macro-on-key (arg)
293 "When not defining or executing a macro, offer to save last macro on a key."
294 (interactive "p")
295 (if (or defining-kbd-macro executing-kbd-macro)
297 (or last-kbd-macro
298 (error "No keyboard macro defined"))
299 (let ((key-seq (read-key-sequence "Save last macro on key: ")))
300 (or (equal key-seq "\a")
301 (define-key global-map key-seq last-kbd-macro))))
304 (defun kmacro-set-counter (arg)
305 "Set kmacro-counter to ARG or 0 if missing.
306 While defining/executing key macro, increase or decrease counter.
307 With \\[universal-argument], unconditionally set counter to 0."
308 (interactive "p")
309 (setq kmacro-counter
310 (cond ((and current-prefix-arg (listp current-prefix-arg)) 0)
311 ((or defining-kbd-macro executing-kbd-macro) (+ kmacro-counter arg))
312 (current-prefix-arg arg)
313 (t 0))))
315 (defun kmacro-set-format (format)
316 "Set macro counter FORMAT."
317 (interactive "sMacro Counter Format (printf format): ")
318 (setq kmacro-counter-format
319 (if (equal format "")
320 "%d"
321 format))
323 ;; redefine initial macro counter if we are not executing a macro.
324 (if (not (or defining-kbd-macro executing-kbd-macro))
325 (setq kmacro-counter-format-start kmacro-counter-format))
328 (defun kmacro-edit-macro ()
329 "Edit keyboard macro."
330 (interactive)
331 (edit-kbd-macro "\r"))
333 ;;;###autoload
334 (defun kmacro-initialize (&optional start-key call-key call-mouse)
335 "Setup key bindings for the keyboard macro package.
336 If specified, use keys START-KEY, CALL-KEY, and CALL-MOUSE.
337 Don't bind to any mouse event if CALL-MOUSE is t.
338 Otherwise, use customized keys."
340 (setq start-key (or start-key kmacro-start-key 'f7))
341 (setq call-key (or call-key kmacro-call-key 'f8))
342 (setq call-mouse (or call-mouse kmacro-call-mouse-event 'S-mouse-3))
344 (global-set-key (vector start-key) 'kmacro-start-macro)
345 (global-set-key (vector (list 'shift start-key)) 'kmacro-set-format)
346 (global-set-key (vector (list 'control start-key)) 'kmacro-set-counter)
347 (global-set-key (vector (list 'meta start-key)) 'kmacro-edit-macro)
349 (global-set-key (vector call-key) 'kmacro-call-macro)
350 (global-set-key (vector (list 'shift call-key)) 'kmacro-call-macro-ring)
351 (global-set-key (vector (list 'control call-key)) 'kmacro-cycle-macro-ring)
353 (unless (eq call-mouse t)
354 (global-set-key (vector call-mouse) 'kmacro-end-call-mouse)))
356 (provide 'kmacro)
357 ;;; kmacro.el ends here