Mercurial > emacs
annotate lisp/kmacro.el @ 46103:4bea2ef4c58a
(picture-forward-column)
(picture-move-down): Never deactivate the mark.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 01 Jul 2002 07:47:22 +0000 |
parents | d441fc235798 |
children | 7e8358ec31ba |
rev | line source |
---|---|
46083 | 1 ;;; kmacro.el --- enhanced keyboard macros |
2 | |
46085
33538dc6ac79
Fixed copyright and keywords.
Kim F. Storm <storm@cua.dk>
parents:
46083
diff
changeset
|
3 ;; Copyright (C) 2002 Free Software Foundation, Inc. |
46083 | 4 |
5 ;; Author: Kim F. Storm <storm@cua.dk> | |
46085
33538dc6ac79
Fixed copyright and keywords.
Kim F. Storm <storm@cua.dk>
parents:
46083
diff
changeset
|
6 ;; Keywords: keyboard convenience |
46083 | 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 2, or (at your option) | |
13 ;; 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; 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. | |
24 | |
25 ;;; Commentary: | |
26 | |
27 ;; The kmacro package is an alternative user interface to emacs' | |
28 ;; keyboard macro functionality. This functionality is normally bound | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
29 ;; to C-x (, C-x ), and C-x e, but these bindings are too hard to |
46083 | 30 ;; type to be really useful for doing small repeated tasks. |
31 | |
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. | |
35 ;; | |
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. | |
39 ;; | |
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. | |
45 | |
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). | |
50 ;; | |
51 ;; The initial value of `kmacro-counter' is 0, or the numeric prefix | |
52 ;; value given to F7 when starting the macro. | |
53 ;; | |
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. | |
57 ;; | |
58 ;; Example: | |
59 ;; | |
60 ;; The following sequence: M-5 F7 x M-2 F7 y F8 F8 F8 F8 | |
61 ;; inserts the following string: x5yx7yx9yx11y | |
62 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
63 ;; A macro can also be called using a mouse click, default S-mouse-3. |
46083 | 64 ;; This calls the macro at the point where you click the mouse. |
65 | |
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. | |
71 | |
72 ;; You can edit the last macro using M-F7. | |
73 | |
74 ;; You can append to the last macro using C-u F7. | |
75 | |
76 ;; You can set the macro counter using C-F7, and you can set | |
77 ;; the macro counter format with S-F7.. | |
78 | |
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) | |
86 ;; | |
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. | |
92 ;; | |
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. | |
102 ;; | |
103 ;; M-f7 Edit the last macro. | |
104 ;; | |
105 ;; S-f8 Call the previous macro. | |
106 ;; | |
107 ;; C-f8 Cycle the macro ring. | |
108 ;; | |
109 ;; S-mouse-3 Set point at click and End macro and execute macro at | |
110 ;; execute last macro. click. | |
111 | |
112 ;;; Code: | |
113 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
114 ;; Customization: |
46083 | 115 |
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")) | |
122 | |
123 ;;;###autoload | |
124 (defcustom kmacro-initialize nil | |
125 "Setting this variable turns on the kmacro functionality. | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
126 This binds the kmacro function keys in the `global-map', so |
46083 | 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) | |
138 | |
139 (defcustom kmacro-start-key 'f7 | |
140 "The function key used by kmacro to start a macro." | |
141 :type 'symbol | |
142 :group 'kmacro) | |
143 | |
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) | |
148 | |
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) | |
153 | |
154 ;; State variables | |
155 | |
156 (defvar kmacro-counter 0 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
157 "*Current keyboard macro counter.") |
46083 | 158 |
159 (defvar kmacro-counter-format "%d" | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
160 "*Current keyboard macro counter format.") |
46083 | 161 |
162 (defvar kmacro-counter-format-start kmacro-counter-format | |
163 "Macro format at start of macro execution.") | |
164 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
165 (defvar kmacro-last-counter 0 "Last counter inserted by key macro.") |
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
166 (defvar kmacro-append-to nil "Last key macro if appending to macro.") |
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
167 (defvar kmacro-ring nil "Key macro ring.") |
46083 | 168 |
169 (defvar kmacro-ring-max 4 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
170 "*Maximum number of key macros to save in key macro ring.") |
46083 | 171 |
172 (defun kmacro-display (macro) | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
173 "Display a keyboard MACRO." |
46083 | 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)))) | |
193 | |
194 | |
195 (defun kmacro-start-macro (arg) | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
196 "Set `kmacro-counter' to ARG or 0 if missing, and `start-kbd-macro'. |
46083 | 197 With \\[universal-argument], append to current keyboard macro (keep kmacro-counter). |
198 | |
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). | |
202 | |
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...")) | |
225 )) | |
226 | |
227 (defun kmacro-call-macro (arg) | |
228 "End kbd macro if currently being defined; else call last kbd macro. | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
229 With numeric prefix ARG, repeat macro that many times. |
46083 | 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)) | |
244 (t | |
245 (setq kmacro-counter-format kmacro-counter-format-start) | |
246 (call-last-kbd-macro arg)))) | |
247 | |
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))) | |
254 | |
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)) | |
266 | |
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)))) | |
286 (t | |
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)))) | |
291 | |
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) | |
296 nil | |
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 "") | |
301 (define-key global-map key-seq last-kbd-macro)))) | |
302 ) | |
303 | |
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)))) | |
314 | |
315 (defun kmacro-set-format (format) | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
316 "Set macro counter FORMAT." |
46083 | 317 (interactive "sMacro Counter Format (printf format): ") |
318 (setq kmacro-counter-format | |
319 (if (equal format "") | |
320 "%d" | |
321 format)) | |
322 | |
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)) | |
326 ) | |
327 | |
328 (defun kmacro-edit-macro () | |
329 "Edit keyboard macro." | |
330 (interactive) | |
331 (edit-kbd-macro "\r")) | |
332 | |
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." | |
339 | |
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)) | |
343 | |
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) | |
348 | |
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) | |
352 | |
353 (unless (eq call-mouse t) | |
354 (global-set-key (vector call-mouse) 'kmacro-end-call-mouse))) | |
355 | |
46099
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
356 (provide 'kmacro) |
d441fc235798
Passed it through checkdoc. Moved `provide' to the end, where it belongs.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
46085
diff
changeset
|
357 ;;; kmacro.el ends here |