diff options
| -rw-r--r-- | lisp/kmacro.el | 688 |
1 files changed, 490 insertions, 198 deletions
diff --git a/lisp/kmacro.el b/lisp/kmacro.el index c1d89386497..15e7a076d1f 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el | |||
| @@ -43,6 +43,29 @@ | |||
| 43 | ;; terminates when point reaches the end of the buffer or if an error | 43 | ;; terminates when point reaches the end of the buffer or if an error |
| 44 | ;; is signalled by ringing the bell. | 44 | ;; is signalled by ringing the bell. |
| 45 | 45 | ||
| 46 | ;; When you define a macro with F7/F8, it is automatically added to | ||
| 47 | ;; the head of the "keyboard macro ring", and F8 actually executes the | ||
| 48 | ;; first element of the macro ring. | ||
| 49 | ;; | ||
| 50 | ;; Note: an empty macro is never added to the macro ring. | ||
| 51 | ;; | ||
| 52 | ;; You can execute the second element on the macro ring with C-u F8 or | ||
| 53 | ;; C-x C-k C-l, you can use C-x C-k C-p and C-x C-k C-n to cycle | ||
| 54 | ;; through the macro ring, and you can swap the first and second | ||
| 55 | ;; elements with C-x C-k C-t. To delete the first element in the | ||
| 56 | ;; macro ring, use C-x C-k C-d. | ||
| 57 | ;; | ||
| 58 | ;; | ||
| 59 | ;; You can also use C-x C-k C-s to start a macro, and C-x C-k C-k to | ||
| 60 | ;; end it; then use C-k to execute it immediately, or C-x C-k C-k to | ||
| 61 | ;; execute it later. | ||
| 62 | ;; | ||
| 63 | ;; In general, immediately after using C-x C-k followed by one of C-k, | ||
| 64 | ;; C-l, C-p, or C-n, you can further cycle the macro ring using C-p or | ||
| 65 | ;; C-n, execute the first or second macro using C-k or C-l, delete | ||
| 66 | ;; the head macro with C-d, or edit the current macro with C-e without | ||
| 67 | ;; repeating the C-x C-k prefix. | ||
| 68 | |||
| 46 | ;; If you enter F7 while defining the macro, the numeric value of | 69 | ;; If you enter F7 while defining the macro, the numeric value of |
| 47 | ;; `kmacro-counter' is inserted using the `kmacro-counter-format', and | 70 | ;; `kmacro-counter' is inserted using the `kmacro-counter-format', and |
| 48 | ;; `kmacro-counter' is incremented by 1 (or the numeric prefix value | 71 | ;; `kmacro-counter' is incremented by 1 (or the numeric prefix value |
| @@ -63,18 +86,12 @@ | |||
| 63 | ;; A macro can also be called using a mouse click, default S-mouse-3. | 86 | ;; 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. | 87 | ;; This calls the macro at the point where you click the mouse. |
| 65 | 88 | ||
| 66 | ;; When you have defined another macro, which is thus called via F8, | 89 | ;; You can edit the last macro using C-x C-k C-e. |
| 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 | 90 | ||
| 74 | ;; You can append to the last macro using C-u F7. | 91 | ;; You can append to the last macro using C-u F7. |
| 75 | 92 | ||
| 76 | ;; You can set the macro counter using C-F7, and you can set | 93 | ;; You can set the macro counter using C-x C-k C-c, add to it using C-x C-k C-a, |
| 77 | ;; the macro counter format with S-F7.. | 94 | ;; and you can set the macro counter format with C-x C-k C-f. |
| 78 | 95 | ||
| 79 | ;; The following key bindings are performed: | 96 | ;; The following key bindings are performed: |
| 80 | ;; | 97 | ;; |
| @@ -92,20 +109,6 @@ | |||
| 92 | ;; | 109 | ;; |
| 93 | ;; C-u f8 Swap last and head of macro ring. | 110 | ;; C-u f8 Swap last and head of macro ring. |
| 94 | ;; | 111 | ;; |
| 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 | 112 | ;; S-mouse-3 Set point at click and End macro and execute macro at |
| 110 | ;; execute last macro. click. | 113 | ;; execute last macro. click. |
| 111 | 114 | ||
| @@ -120,38 +123,80 @@ | |||
| 120 | :link '(emacs-commentary-link :tag "Commentary" "kmacro.el") | 123 | :link '(emacs-commentary-link :tag "Commentary" "kmacro.el") |
| 121 | :link '(emacs-library-link :tag "Lisp File" "kmacro.el")) | 124 | :link '(emacs-library-link :tag "Lisp File" "kmacro.el")) |
| 122 | 125 | ||
| 123 | ;;;###autoload | 126 | (defcustom kmacro-call-mouse-event 'S-mouse-3 |
| 124 | (defcustom kmacro-initialize nil | 127 | "The mouse event used by kmacro to call a macro. |
| 125 | "Setting this variable turns on the kmacro functionality. | 128 | Set to nil if no mouse binding is desired." |
| 126 | This binds the kmacro function keys in the `global-map', so | 129 | :type 'symbol |
| 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) | 130 | :group 'kmacro) |
| 138 | 131 | ||
| 139 | (defcustom kmacro-start-key 'f7 | 132 | (defcustom kmacro-ring-max 8 |
| 140 | "The function key used by kmacro to start a macro." | 133 | "Maximum number of keyboard macros to save in macro ring." |
| 141 | :type 'symbol | 134 | :type 'integer |
| 142 | :group 'kmacro) | 135 | :group 'kmacro) |
| 143 | 136 | ||
| 144 | (defcustom kmacro-call-key 'f8 | 137 | |
| 145 | "The function key used by kmacro to end and call a macro." | 138 | (defcustom kmacro-execute-before-append t |
| 146 | :type 'symbol | 139 | "Controls whether appending to a macro starts by executing the macro. |
| 140 | If non-nil, using a single \\[universal-argument] prefix executes the macro | ||
| 141 | before appending, while more than one \\[universal-argument] prefix does not | ||
| 142 | execute the macro. | ||
| 143 | Otherwise, a single \\[universal-argument] prefix does not execute the | ||
| 144 | macro, while more than one \\[universal-argument] prefix causes the | ||
| 145 | macro to be executed before appending to it." | ||
| 146 | :type 'boolean | ||
| 147 | :group 'kmacro) | 147 | :group 'kmacro) |
| 148 | 148 | ||
| 149 | (defcustom kmacro-call-mouse-event 'S-mouse-3 | 149 | |
| 150 | "The mouse event used by kmacro to call a macro." | 150 | (defcustom kmacro-repeat-no-prefix t |
| 151 | :type 'symbol | 151 | "Allow repeating certain macro commands without entering the C-x C-k prefix." |
| 152 | :type 'boolean | ||
| 152 | :group 'kmacro) | 153 | :group 'kmacro) |
| 153 | 154 | ||
| 154 | ;; State variables | 155 | |
| 156 | ;; Keymap | ||
| 157 | |||
| 158 | (defvar kmacro-keymap | ||
| 159 | (let ((map (make-sparse-keymap))) | ||
| 160 | (define-key map "\C-s" 'kmacro-start-macro) | ||
| 161 | (define-key map "\C-k" 'kmacro-end-or-call-macro-rep) | ||
| 162 | (define-key map "\C-e" 'kmacro-edit-macro) | ||
| 163 | (define-key map "\r" 'kmacro-edit-macro-nr) | ||
| 164 | (define-key map "l" 'kmacro-edit-lossage) | ||
| 165 | (define-key map "\C-i" 'kmacro-insert-counter) | ||
| 166 | (define-key map "\C-a" 'kmacro-add-counter) | ||
| 167 | (define-key map "\C-v" 'kmacro-view-macro-rep) | ||
| 168 | (define-key map "\C-l" 'kmacro-call-ring-2nd-rep) | ||
| 169 | (define-key map "\C-r" 'kmacro-view-ring-2nd) | ||
| 170 | (define-key map "\C-n" 'kmacro-cycle-ring-next) | ||
| 171 | (define-key map "\C-p" 'kmacro-cycle-ring-previous) | ||
| 172 | (define-key map "\C-f" 'kmacro-set-format) | ||
| 173 | (define-key map "\C-c" 'kmacro-set-counter) | ||
| 174 | (define-key map "\C-t" 'kmacro-swap-ring) | ||
| 175 | (define-key map "\C-b" 'kmacro-bind-to-key) | ||
| 176 | (define-key map "\C-d" 'kmacro-delete-ring-head) | ||
| 177 | ;; Compatibility bindings | ||
| 178 | (define-key map "q" 'kbd-macro-query) | ||
| 179 | (define-key map "n" 'name-last-kbd-macro) | ||
| 180 | (define-key map "e" 'edit-kbd-macro) | ||
| 181 | map) | ||
| 182 | "Keymap for keyboard macro commands.") | ||
| 183 | (defalias 'kmacro-keymap kmacro-keymap) | ||
| 184 | |||
| 185 | ;;; Provide some binding for startup: | ||
| 186 | ;;;###autoload (global-set-key "\C-x(" 'kmacro-start-macro) | ||
| 187 | ;;;###autoload (global-set-key "\C-x)" 'kmacro-end-macro) | ||
| 188 | ;;;###autoload (global-set-key "\C-xe" 'kmacro-call-macro) | ||
| 189 | ;;;###autoload (global-set-key [f7] 'kmacro-start-macro-or-insert-counter) | ||
| 190 | ;;;###autoload (global-set-key [f8] 'kmacro-end-or-call-macro) | ||
| 191 | ;;;###autoload (global-set-key "\C-x\C-k" 'kmacro-keymap) | ||
| 192 | ;;;###autoload (autoload 'kmacro-keymap "kmacro" "Keymap for keyboard macro commands." t 'keymap) | ||
| 193 | |||
| 194 | (if kmacro-call-mouse-event | ||
| 195 | (global-set-key (vector kmacro-call-mouse-event) 'kmacro-end-call-mouse)) | ||
| 196 | |||
| 197 | |||
| 198 | |||
| 199 | ;;; Keyboard macro counter | ||
| 155 | 200 | ||
| 156 | (defvar kmacro-counter 0 | 201 | (defvar kmacro-counter 0 |
| 157 | "*Current keyboard macro counter.") | 202 | "*Current keyboard macro counter.") |
| @@ -162,37 +207,343 @@ unsetting this variable does not have any effect!" | |||
| 162 | (defvar kmacro-counter-format-start kmacro-counter-format | 207 | (defvar kmacro-counter-format-start kmacro-counter-format |
| 163 | "Macro format at start of macro execution.") | 208 | "Macro format at start of macro execution.") |
| 164 | 209 | ||
| 210 | (defvar kmacro-counter-value-start kmacro-counter | ||
| 211 | "Macro counter at start of macro execution.") | ||
| 212 | |||
| 165 | (defvar kmacro-last-counter 0 "Last counter inserted by key macro.") | 213 | (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.") | ||
| 168 | 214 | ||
| 169 | (defvar kmacro-ring-max 4 | ||
| 170 | "*Maximum number of key macros to save in key macro ring.") | ||
| 171 | 215 | ||
| 172 | (defun kmacro-display (macro) | 216 | (defun kmacro-insert-counter (arg) |
| 217 | "Insert macro counter and increment with ARG or 1 if missing. | ||
| 218 | With \\[universal-argument], insert previous kmacro-counter (but do not modify counter)." | ||
| 219 | (interactive "P") | ||
| 220 | (if (and arg (listp arg)) | ||
| 221 | (insert (format kmacro-counter-format kmacro-last-counter)) | ||
| 222 | (insert (format kmacro-counter-format kmacro-counter)) | ||
| 223 | (kmacro-add-counter (prefix-numeric-value arg)))) | ||
| 224 | |||
| 225 | |||
| 226 | (defun kmacro-set-format (format) | ||
| 227 | "Set macro counter FORMAT." | ||
| 228 | (interactive "sMacro Counter Format (printf format): ") | ||
| 229 | (setq kmacro-counter-format | ||
| 230 | (if (equal format "") "%d" format)) | ||
| 231 | ;; redefine initial macro counter if we are not executing a macro. | ||
| 232 | (if (not (or defining-kbd-macro executing-kbd-macro)) | ||
| 233 | (setq kmacro-counter-format-start kmacro-counter-format))) | ||
| 234 | |||
| 235 | |||
| 236 | (defun kmacro-display-counter (&optional value) | ||
| 237 | "Display current counter value." | ||
| 238 | (unless value (setq value kmacro-counter)) | ||
| 239 | (message "New macro counter value: %s (%d)" (format kmacro-counter-format value) value)) | ||
| 240 | |||
| 241 | |||
| 242 | (defun kmacro-set-counter (arg) | ||
| 243 | "Set kmacro-counter to ARG or prompt if missing. | ||
| 244 | With \\[universal-argument], reset counter to its value prior to this iteration of the macro." | ||
| 245 | (interactive "NMacro counter value: ") | ||
| 246 | (setq kmacro-last-counter kmacro-counter | ||
| 247 | kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg)) | ||
| 248 | kmacro-counter-value-start | ||
| 249 | arg)) | ||
| 250 | (unless executing-kbd-macro | ||
| 251 | (kmacro-display-counter))) | ||
| 252 | |||
| 253 | |||
| 254 | (defun kmacro-add-counter (arg) | ||
| 255 | "Add numeric prefix arg (prompt if missing) to macro counter. | ||
| 256 | With \\[universal-argument], restore previous counter value." | ||
| 257 | (interactive "NAdd to macro counter: ") | ||
| 258 | (let ((last kmacro-last-counter)) | ||
| 259 | (setq kmacro-last-counter kmacro-counter | ||
| 260 | kmacro-counter (if (and current-prefix-arg (listp current-prefix-arg)) | ||
| 261 | last | ||
| 262 | kmacro-counter (+ kmacro-counter arg)))) | ||
| 263 | (unless executing-kbd-macro | ||
| 264 | (kmacro-display-counter))) | ||
| 265 | |||
| 266 | |||
| 267 | (defun kmacro-loop-setup-function () | ||
| 268 | "Function called prior to each iteration of macro." | ||
| 269 | ;; Restore macro counter format to initial format, so it is ok to change | ||
| 270 | ;; counter format in the macro without restoring it. | ||
| 271 | (setq kmacro-counter-format kmacro-counter-format-start) | ||
| 272 | ;; Save initial counter value so we can restore it with C-u kmacro-set-counter. | ||
| 273 | (setq kmacro-counter-value-start kmacro-counter) | ||
| 274 | ;; Return non-nil to continue execution. | ||
| 275 | t) | ||
| 276 | |||
| 277 | |||
| 278 | ;;; Keyboard macro ring | ||
| 279 | |||
| 280 | (defvar kmacro-ring nil | ||
| 281 | "The keyboard macro ring. | ||
| 282 | Each element is a list (MACRO COUNTER FORMAT). Actually, the head of | ||
| 283 | the macro ring (when defining or executing) is not stored in the ring; | ||
| 284 | instead it is available in the variables `last-kbd-macro', `kmacro-counter', | ||
| 285 | and `kmacro-counter-format'.") | ||
| 286 | |||
| 287 | |||
| 288 | (defun kmacro-ring-head () | ||
| 289 | "Return pseudo head element in macro ring." | ||
| 290 | (and last-kbd-macro | ||
| 291 | (list last-kbd-macro kmacro-counter kmacro-counter-format-start))) | ||
| 292 | |||
| 293 | |||
| 294 | (defun kmacro-push-ring (&optional elt) | ||
| 295 | "Push ELT or current macro onto `kmacro-ring'." | ||
| 296 | (when (setq elt (or elt (kmacro-ring-head))) | ||
| 297 | (let ((len (length kmacro-ring))) | ||
| 298 | (setq kmacro-ring (cons elt kmacro-ring)) | ||
| 299 | (if (>= len kmacro-ring-max) | ||
| 300 | (setcdr (nthcdr len kmacro-ring) nil))))) | ||
| 301 | |||
| 302 | |||
| 303 | (defun kmacro-split-ring-element (elt) | ||
| 304 | (setq last-kbd-macro (car elt) | ||
| 305 | kmacro-counter (nth 1 elt) | ||
| 306 | kmacro-counter-format-start (nth 2 elt))) | ||
| 307 | |||
| 308 | |||
| 309 | (defun kmacro-pop-ring1 (&optional raw) | ||
| 310 | "Pop head element off macro ring (no check). | ||
| 311 | Non-nil arg RAW means just return raw first element." | ||
| 312 | (prog1 (car kmacro-ring) | ||
| 313 | (unless raw | ||
| 314 | (kmacro-split-ring-element (car kmacro-ring))) | ||
| 315 | (setq kmacro-ring (cdr kmacro-ring)))) | ||
| 316 | |||
| 317 | |||
| 318 | (defun kmacro-pop-ring (&optional raw) | ||
| 319 | "Pop head element off macro ring. | ||
| 320 | Non-nil arg RAW means just return raw first element." | ||
| 321 | (unless (kmacro-ring-empty-p) | ||
| 322 | (kmacro-pop-ring1 raw))) | ||
| 323 | |||
| 324 | |||
| 325 | (defun kmacro-ring-length () | ||
| 326 | "Return length of macro ring, including pseudo head." | ||
| 327 | (+ (if last-kbd-macro 1 0) (length kmacro-ring))) | ||
| 328 | |||
| 329 | |||
| 330 | (defun kmacro-ring-empty-p (&optional none) | ||
| 331 | "Tell user and return t if `last-kbd-macro' is nil or `kmacro-ring' is empty. | ||
| 332 | Check only `last-kbd-macro' if optional arg NONE is non-nil." | ||
| 333 | (while (and (null last-kbd-macro) kmacro-ring) | ||
| 334 | (kmacro-pop-ring1)) | ||
| 335 | (cond | ||
| 336 | ((null last-kbd-macro) | ||
| 337 | (message "No keyboard macro defined.") | ||
| 338 | t) | ||
| 339 | ((and (null none) (null kmacro-ring)) | ||
| 340 | (message "Only one keyboard macro defined.") | ||
| 341 | t) | ||
| 342 | (t nil))) | ||
| 343 | |||
| 344 | |||
| 345 | (defun kmacro-display (macro &optional trunc descr empty ) | ||
| 173 | "Display a keyboard MACRO." | 346 | "Display a keyboard MACRO." |
| 174 | (let (s) | 347 | (if macro |
| 175 | (if (stringp macro) | 348 | (let* ((x 60) |
| 176 | (setq s (if (> (length macro) 50) | 349 | (m (format-kbd-macro macro)) |
| 177 | (concat (substring macro 0 50) "...") | 350 | (l (length m)) |
| 178 | macro)) | 351 | (z (and nil trunc (> l x)))) |
| 179 | (if (vectorp macro) | 352 | (message (format "%s: %s%s" (or descr "Macro") |
| 180 | (let (v (i 0) (n (length macro))) | 353 | (if z (substring m 0 (1- x)) m) (if z "..." "")))) |
| 181 | (setq s "") | 354 | (message (or empty "No keyboard macros defined")))) |
| 182 | (while (and (< i n) (< (length s) 50)) | 355 | |
| 183 | (setq v (aref macro i)) | 356 | |
| 184 | (setq s (cond | 357 | (defun kmacro-call-ring-2nd (arg) |
| 185 | ((numberp v) (concat s (char-to-string v))) | 358 | "Execute second keyboard macro at in macro ring." |
| 186 | ((stringp v) (concat s v)) | 359 | (interactive "P") |
| 187 | ((symbolp v) (concat s "[" (symbol-name v) "]")) | 360 | (unless (kmacro-ring-empty-p) |
| 188 | (t s))) | 361 | ;; should use counter format specific to the macro on the ring! |
| 189 | (setq i (1+ i))) | 362 | (let ((kmacro-counter (nth 1 (car kmacro-ring))) |
| 190 | (if (< i n) | 363 | (kmacro-counter-format-start (nth 2 (car kmacro-ring)))) |
| 191 | (setq s (concat s "...")))))) | 364 | (execute-kbd-macro (car (car kmacro-ring)) arg #'kmacro-loop-setup-function) |
| 192 | (message (format "Macro: %s" s)))) | 365 | (setcar (cdr (car kmacro-ring)) kmacro-counter)))) |
| 366 | |||
| 367 | |||
| 368 | (defun kmacro-call-ring-2nd-rep (arg) | ||
| 369 | "Like `kmacro-call-ring-2nd', but allow repeat without kmacro prefix." | ||
| 370 | (interactive "P") | ||
| 371 | (kmacro-call-ring-2nd arg) | ||
| 372 | (if kmacro-ring | ||
| 373 | (kmacro-repeat-loop))) | ||
| 374 | |||
| 375 | (put 'kmacro-call-ring-2nd-rep 'kmacro-repeat 'head) | ||
| 376 | |||
| 193 | 377 | ||
| 378 | (defun kmacro-view-ring-2nd () | ||
| 379 | "Display the current head of the keyboard macro ring." | ||
| 380 | (interactive) | ||
| 381 | (unless (kmacro-ring-empty-p) | ||
| 382 | (kmacro-display (car (car kmacro-ring)) "2nd macro"))) | ||
| 383 | |||
| 384 | |||
| 385 | (defun kmacro-repeat-loop () | ||
| 386 | "Process kmacro commands keys immidiately after cycling the ring." | ||
| 387 | (when kmacro-repeat-no-prefix | ||
| 388 | (let (cmd done repeat) | ||
| 389 | (while (and last-kbd-macro | ||
| 390 | (not done) | ||
| 391 | (setq cmd (lookup-key kmacro-keymap (vector (read-event)))) | ||
| 392 | (setq repeat (get cmd 'kmacro-repeat))) | ||
| 393 | (clear-this-command-keys t) | ||
| 394 | (cond | ||
| 395 | ((eq repeat 'ring) | ||
| 396 | (if kmacro-ring | ||
| 397 | (let ((kmacro-repeat-no-prefix nil)) | ||
| 398 | (funcall cmd nil)) | ||
| 399 | (kmacro-display last-kbd-macro t))) | ||
| 400 | ((eq repeat 'head) | ||
| 401 | (funcall cmd nil)) | ||
| 402 | ((eq repeat 'stop) | ||
| 403 | (funcall cmd nil) | ||
| 404 | (setq done t))) | ||
| 405 | (setq last-input-event nil))) | ||
| 406 | (when last-input-event | ||
| 407 | (clear-this-command-keys t) | ||
| 408 | (setq unread-command-events (list last-input-event))))) | ||
| 409 | |||
| 410 | |||
| 411 | (defun kmacro-cycle-ring-next (&optional arg) | ||
| 412 | "Move to next keyboard macro in keyboard macro ring. | ||
| 413 | Displays the selected macro in the echo area." | ||
| 414 | (interactive) | ||
| 415 | (unless (kmacro-ring-empty-p) | ||
| 416 | (kmacro-push-ring) | ||
| 417 | (let* ((len (length kmacro-ring)) | ||
| 418 | (tail (nthcdr (- len 2) kmacro-ring)) | ||
| 419 | (elt (car (cdr tail)))) | ||
| 420 | (setcdr tail nil) | ||
| 421 | (kmacro-split-ring-element elt)) | ||
| 422 | (kmacro-display last-kbd-macro t) | ||
| 423 | (kmacro-repeat-loop))) | ||
| 424 | |||
| 425 | (put 'kmacro-cycle-ring-next 'kmacro-repeat 'ring) | ||
| 426 | |||
| 427 | |||
| 428 | (defun kmacro-cycle-ring-previous (&optional arg) | ||
| 429 | "Move to previous keyboard macro in keyboard macro ring. | ||
| 430 | Displays the selected macro in the echo area." | ||
| 431 | (interactive) | ||
| 432 | (unless (kmacro-ring-empty-p) | ||
| 433 | (let ((cur (kmacro-ring-head))) | ||
| 434 | (kmacro-pop-ring1) | ||
| 435 | (if kmacro-ring | ||
| 436 | (nconc kmacro-ring (list cur)) | ||
| 437 | (setq kmacro-ring (list cur)))) | ||
| 438 | (kmacro-display last-kbd-macro t) | ||
| 439 | (kmacro-repeat-loop))) | ||
| 440 | |||
| 441 | (put 'kmacro-cycle-ring-previous 'kmacro-repeat 'ring) | ||
| 194 | 442 | ||
| 443 | |||
| 444 | (defun kmacro-swap-ring () | ||
| 445 | "Swap first two elements on keyboard macro ring." | ||
| 446 | (interactive) | ||
| 447 | (unless (kmacro-ring-empty-p) | ||
| 448 | (let ((cur (kmacro-ring-head))) | ||
| 449 | (kmacro-pop-ring1) | ||
| 450 | (kmacro-push-ring cur)) | ||
| 451 | (kmacro-display last-kbd-macro t))) | ||
| 452 | |||
| 453 | |||
| 454 | (defun kmacro-delete-ring-head (&optional arg) | ||
| 455 | "Delete current macro from keyboard macro ring." | ||
| 456 | (interactive) | ||
| 457 | (unless (kmacro-ring-empty-p t) | ||
| 458 | (if (null kmacro-ring) | ||
| 459 | (setq last-kbd-macro nil) | ||
| 460 | (kmacro-pop-ring)) | ||
| 461 | (kmacro-display last-kbd-macro t nil "Keyboard macro ring is now empty."))) | ||
| 462 | |||
| 463 | (put 'kmacro-delete-ring-head 'kmacro-repeat 'head) | ||
| 464 | |||
| 465 | ;;; Traditional bindings: | ||
| 466 | |||
| 467 | |||
| 468 | ;;;###autoload | ||
| 195 | (defun kmacro-start-macro (arg) | 469 | (defun kmacro-start-macro (arg) |
| 470 | "Record subsequent keyboard input, defining a keyboard macro. | ||
| 471 | The commands are recorded even as they are executed. | ||
| 472 | Use \\[end-kbd-macro] to finish recording and make the macro available. | ||
| 473 | Use \\[call-last-kbd-macro] to execute the macro. | ||
| 474 | Use \\[name-last-kbd-macro] to give it a permanent name. | ||
| 475 | Non-nil arg (prefix arg) means append to last macro defined; | ||
| 476 | |||
| 477 | With \\[universal-argument] prefix, append to last keyboard macro | ||
| 478 | defined. Depending on `kmacro-execute-before-append', this may begin | ||
| 479 | by re-executing the last macro as if you typed it again. | ||
| 480 | |||
| 481 | Otherwise, it sets `kmacro-counter' to ARG or 0 if missing before | ||
| 482 | defining the macro. | ||
| 483 | |||
| 484 | Use \\[kmacro-insert-counter] to insert (and increment) the macro counter. | ||
| 485 | The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter]. | ||
| 486 | The format of the counter can be modified via \\[kmacro-set-format]." | ||
| 487 | (interactive "P") | ||
| 488 | (if (or defining-kbd-macro executing-kbd-macro) | ||
| 489 | (message "Already defining keyboard macro.") | ||
| 490 | (let ((append (and arg (listp arg)))) | ||
| 491 | (unless append | ||
| 492 | (if last-kbd-macro | ||
| 493 | (let ((len (length kmacro-ring))) | ||
| 494 | (setq kmacro-ring | ||
| 495 | (cons | ||
| 496 | (list last-kbd-macro kmacro-counter kmacro-counter-format-start) | ||
| 497 | kmacro-ring)) | ||
| 498 | (if (>= len kmacro-ring-max) | ||
| 499 | (setcdr (nthcdr len kmacro-ring) nil)))) | ||
| 500 | (setq kmacro-counter (if arg (prefix-numeric-value arg) 0) | ||
| 501 | kmacro-counter-value-start kmacro-counter | ||
| 502 | kmacro-last-counter kmacro-counter | ||
| 503 | kmacro-counter-format-start kmacro-counter-format)) | ||
| 504 | |||
| 505 | (start-kbd-macro append | ||
| 506 | (and append | ||
| 507 | (if kmacro-execute-before-append | ||
| 508 | (> (car arg) 4) | ||
| 509 | (= (car arg) 4))))))) | ||
| 510 | |||
| 511 | |||
| 512 | ;;;###autoload | ||
| 513 | (defun kmacro-end-macro (arg) | ||
| 514 | "Finish defining a keyboard macro. | ||
| 515 | The definition was started by \\[kmacro-start-macro]. | ||
| 516 | The macro is now available for use via \\[kmacro-call-macro], | ||
| 517 | or it can be given a name with \\[name-last-kbd-macro] and then invoked | ||
| 518 | under that name. | ||
| 519 | |||
| 520 | With numeric arg, repeat macro now that many times, | ||
| 521 | counting the definition just completed as the first repetition. | ||
| 522 | An argument of zero means repeat until error." | ||
| 523 | (interactive "P") | ||
| 524 | (end-kbd-macro arg #'kmacro-loop-setup-function) | ||
| 525 | (when (and last-kbd-macro (= (length last-kbd-macro) 0)) | ||
| 526 | (message "Ignore empty macro") | ||
| 527 | (kmacro-pop-ring))) | ||
| 528 | |||
| 529 | |||
| 530 | ;;;###autoload | ||
| 531 | (defun kmacro-call-macro (arg) | ||
| 532 | "Call the last keyboard macro that you defined with \\[kmacro-start-macro]. | ||
| 533 | |||
| 534 | A prefix argument serves as a repeat count. Zero means repeat until error. | ||
| 535 | |||
| 536 | To make a macro permanent so you can call it even after | ||
| 537 | defining others, use M-x name-last-kbd-macro." | ||
| 538 | (interactive "p") | ||
| 539 | (call-last-kbd-macro arg #'kmacro-loop-setup-function)) | ||
| 540 | |||
| 541 | |||
| 542 | |||
| 543 | ;;; Combined function key bindings: | ||
| 544 | |||
| 545 | ;;;###autoload | ||
| 546 | (defun kmacro-start-macro-or-insert-counter (arg) | ||
| 196 | "Set `kmacro-counter' to ARG or 0 if missing, and `start-kbd-macro'. | 547 | "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). | 548 | With \\[universal-argument], append to current keyboard macro (keep kmacro-counter). |
| 198 | 549 | ||
| @@ -200,158 +551,99 @@ When defining/executing macro, insert macro counter and increment with | |||
| 200 | ARG or 1 if missing. | 551 | ARG or 1 if missing. |
| 201 | With \\[universal-argument], insert previous kmacro-counter (but do not modify counter). | 552 | With \\[universal-argument], insert previous kmacro-counter (but do not modify counter). |
| 202 | 553 | ||
| 203 | The macro counter can be modified via \\[kmacro-set-counter]. | 554 | The macro counter can be modified via \\[kmacro-set-counter] and \\[kmacro-add-counter]. |
| 204 | The format of the counter can be modified via \\[kmacro-set-format]." | 555 | The format of the counter can be modified via \\[kmacro-set-format]." |
| 205 | (interactive "p") | 556 | (interactive "P") |
| 206 | (if (or defining-kbd-macro executing-kbd-macro) | 557 | (if (or defining-kbd-macro executing-kbd-macro) |
| 207 | (if (and current-prefix-arg (listp current-prefix-arg)) | 558 | (kmacro-insert-counter arg) |
| 208 | (insert (format kmacro-counter-format kmacro-last-counter)) | 559 | (kmacro-start-macro arg))) |
| 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 | 560 | ||
| 227 | (defun kmacro-call-macro (arg) | 561 | |
| 562 | ;;;###autoload | ||
| 563 | (defun kmacro-end-or-call-macro (arg) | ||
| 228 | "End kbd macro if currently being defined; else call last kbd macro. | 564 | "End kbd macro if currently being defined; else call last kbd macro. |
| 229 | With numeric prefix ARG, repeat macro that many times. | 565 | With numeric prefix ARG, repeat macro that many times. |
| 230 | With \\[universal-argument], swap current macro with head of macro ring." | 566 | With \\[universal-argument], call second macro in macro ring." |
| 231 | (interactive "p") | 567 | (interactive "P") |
| 232 | (cond | 568 | (cond |
| 233 | (defining-kbd-macro | 569 | (defining-kbd-macro |
| 234 | (end-kbd-macro) | 570 | (kmacro-end-macro arg)) |
| 235 | (if kmacro-append-to | 571 | ((and arg (listp arg)) |
| 236 | (setq last-kbd-macro (concat kmacro-append-to last-kbd-macro) | 572 | (kmacro-call-ring-2nd 1)) |
| 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 | 573 | (t |
| 245 | (setq kmacro-counter-format kmacro-counter-format-start) | 574 | (kmacro-call-macro arg)))) |
| 246 | (call-last-kbd-macro arg)))) | 575 | |
| 576 | |||
| 577 | (defun kmacro-end-or-call-macro-rep (arg) | ||
| 578 | "As `kmacro-end-or-call-macro' but allows repeat without kmacro prefix." | ||
| 579 | (interactive "P") | ||
| 580 | (kmacro-end-or-call-macro arg) | ||
| 581 | (kmacro-repeat-loop)) | ||
| 582 | |||
| 583 | (put 'kmacro-end-or-call-macro-rep 'kmacro-repeat 'head) | ||
| 247 | 584 | ||
| 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 | 585 | ||
| 586 | ;;;###autoload | ||
| 255 | (defun kmacro-end-call-mouse (event) | 587 | (defun kmacro-end-call-mouse (event) |
| 256 | "Move point to the position clicked with the mouse and call last kbd macro. | 588 | "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." | 589 | If kbd macro currently being defined end it before activating it." |
| 258 | (interactive "e") | 590 | (interactive "e") |
| 259 | (when defining-kbd-macro | 591 | (when defining-kbd-macro |
| 260 | (end-kbd-macro) | 592 | (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) | 593 | (mouse-set-point event) |
| 265 | (call-last-kbd-macro nil)) | 594 | (kmacro-call-macro nil)) |
| 266 | 595 | ||
| 267 | (defun kmacro-cycle-macro-ring (&optional previous) | 596 | |
| 268 | "Cycle the keyboard macro ring on \\[kmacro-call-macro-ring]. | 597 | ;;; Misc. commands |
| 269 | Moves to the next element in the keyboard macro ring. | 598 | |
| 270 | With \\[universal-argument] prefix, move to the previous element in the ring. | 599 | (defun kmacro-bind-to-key (arg) |
| 271 | Displays the selected macro in the echo area." | 600 | "When not defining or executing a macro, offer to bind last macro to a key." |
| 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") | 601 | (interactive "p") |
| 295 | (if (or defining-kbd-macro executing-kbd-macro) | 602 | (if (or defining-kbd-macro executing-kbd-macro) |
| 296 | nil | 603 | (if defining-kbd-macro |
| 297 | (or last-kbd-macro | 604 | (message "Cannot save macro while defining it.")) |
| 298 | (error "No keyboard macro defined")) | 605 | (unless last-kbd-macro |
| 299 | (let ((key-seq (read-key-sequence "Save last macro on key: "))) | 606 | (error "No keyboard macro defined")) |
| 300 | (or (equal key-seq "") | 607 | (let ((key-seq (read-key-sequence "Bind last macro to key: "))) |
| 301 | (define-key global-map key-seq last-kbd-macro)))) | 608 | (unless (equal key-seq "") |
| 302 | ) | 609 | (define-key global-map key-seq last-kbd-macro))))) |
| 303 | 610 | ||
| 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 | 611 | ||
| 315 | (defun kmacro-set-format (format) | 612 | (defun kmacro-view-macro (&optional arg) |
| 316 | "Set macro counter FORMAT." | 613 | "Display the last keyboard macro." |
| 317 | (interactive "sMacro Counter Format (printf format): ") | 614 | (interactive) |
| 318 | (setq kmacro-counter-format | 615 | (kmacro-display last-kbd-macro)) |
| 319 | (if (equal format "") | ||
| 320 | "%d" | ||
| 321 | format)) | ||
| 322 | 616 | ||
| 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 | 617 | ||
| 328 | (defun kmacro-edit-macro () | 618 | (defun kmacro-view-macro-rep (&optional arg) |
| 329 | "Edit keyboard macro." | 619 | "Like `kmacro-view-macro', but allow repeat without kmacro prefix." |
| 330 | (interactive) | 620 | (interactive) |
| 331 | (edit-kbd-macro "\r")) | 621 | (kmacro-view-macro arg) |
| 622 | (if last-kbd-macro | ||
| 623 | (kmacro-repeat-loop))) | ||
| 624 | |||
| 625 | (put 'kmacro-view-macro-rep 'kmacro-repeat 'head) | ||
| 626 | |||
| 627 | (defun kmacro-edit-macro (&optional arg) | ||
| 628 | "Edit last keyboard macro." | ||
| 629 | (interactive "P") | ||
| 630 | (edit-kbd-macro "\r" arg)) | ||
| 631 | |||
| 632 | (put 'kmacro-edit-macro 'kmacro-repeat 'stop) | ||
| 633 | |||
| 634 | |||
| 635 | (defun kmacro-edit-macro-nr (&optional arg) | ||
| 636 | "As edit last keyboard macro, but without kmacro-repeat property." | ||
| 637 | (interactive "P") | ||
| 638 | (kmacro-edit-macro arg)) | ||
| 639 | |||
| 640 | |||
| 641 | (defun kmacro-edit-lossage () | ||
| 642 | "Edit most recent 100 keystrokes as a keyboard macro." | ||
| 643 | (interactive) | ||
| 644 | (kmacro-push-ring) | ||
| 645 | (edit-kbd-macro "\C-hl")) | ||
| 332 | 646 | ||
| 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 | 647 | ||
| 356 | (provide 'kmacro) | 648 | (provide 'kmacro) |
| 357 | ;;; kmacro.el ends here | 649 | ;;; kmacro.el ends here |