diff options
| -rw-r--r-- | doc/emacs/kmacro.texi | 19 | ||||
| -rw-r--r-- | etc/NEWS | 14 | ||||
| -rw-r--r-- | lisp/edmacro.el | 113 |
3 files changed, 134 insertions, 12 deletions
diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi index fc1402b489d..05095bc68b8 100644 --- a/doc/emacs/kmacro.texi +++ b/doc/emacs/kmacro.texi | |||
| @@ -515,6 +515,19 @@ editing it. Type @kbd{C-h m} once in that buffer to display details | |||
| 515 | of how to edit the macro. When you are finished editing, type | 515 | of how to edit the macro. When you are finished editing, type |
| 516 | @kbd{C-c C-c}. | 516 | @kbd{C-c C-c}. |
| 517 | 517 | ||
| 518 | @findex edmacro-insert-key | ||
| 519 | @findex edmacro-set-macro-to-region-lines | ||
| 520 | @code{edmacro-mode}, the major mode used by | ||
| 521 | @code{kmacro-edit-macro}, provides commands for more easily editing | ||
| 522 | the formatted macro. Use @kbd{C-c C-q} (@code{edmacro-insert-key}) to | ||
| 523 | insert the next key sequence that you type into the buffer using the | ||
| 524 | correct format, similar to @kbd{C-q} (@code{quoted-insert}). Use | ||
| 525 | @kbd{C-c C-r} (@code{edmacro-set-macro-to-region-lines}) to replace | ||
| 526 | the macro's text with the text in the region. If the region does not | ||
| 527 | begin at the start of a line or if it does not end at the end of a | ||
| 528 | line, the region is extended to include complete lines. If the region | ||
| 529 | ends at the beginning of a line, that final line is excluded. | ||
| 530 | |||
| 518 | @findex edit-kbd-macro | 531 | @findex edit-kbd-macro |
| 519 | @kindex C-x C-k e | 532 | @kindex C-x C-k e |
| 520 | You can edit a named keyboard macro or a macro bound to a key by typing | 533 | You can edit a named keyboard macro or a macro bound to a key by typing |
| @@ -523,9 +536,13 @@ keyboard input that you would use to invoke the macro---@kbd{C-x e} or | |||
| 523 | @kbd{M-x @var{name}} or some other key sequence. | 536 | @kbd{M-x @var{name}} or some other key sequence. |
| 524 | 537 | ||
| 525 | @findex kmacro-edit-lossage | 538 | @findex kmacro-edit-lossage |
| 539 | @vindex edmacro-reverse-macro-lines | ||
| 526 | @kindex C-x C-k l | 540 | @kindex C-x C-k l |
| 527 | You can edit the last 300 keystrokes as a macro by typing | 541 | You can edit the last 300 keystrokes as a macro by typing |
| 528 | @kbd{C-x C-k l} (@code{kmacro-edit-lossage}). | 542 | @kbd{C-x C-k l} (@code{kmacro-edit-lossage}). By default, |
| 543 | your most recent keystrokes are listed at the bottom of the buffer. | ||
| 544 | To list a macro's key sequences in reverse order, set | ||
| 545 | @code{edmacro-reverse-macro-lines} to @code{t}. | ||
| 529 | 546 | ||
| 530 | @node Keyboard Macro Step-Edit | 547 | @node Keyboard Macro Step-Edit |
| 531 | @section Stepwise Editing a Keyboard Macro | 548 | @section Stepwise Editing a Keyboard Macro |
| @@ -772,6 +772,20 @@ neither of which have been supported by Emacs since version 23.1. | |||
| 772 | The user option 'url-gateway-nslookup-program' and the function | 772 | The user option 'url-gateway-nslookup-program' and the function |
| 773 | 'url-gateway-nslookup-host' are consequently also obsolete. | 773 | 'url-gateway-nslookup-host' are consequently also obsolete. |
| 774 | 774 | ||
| 775 | +++ | ||
| 776 | ** Edmacro | ||
| 777 | |||
| 778 | *** New command 'edmacro-set-macro-to-region-lines'. | ||
| 779 | Bound to 'C-c C-r', this command replaces the macro text with the | ||
| 780 | lines of the region. If needed, the region is extended to include | ||
| 781 | whole lines. If the region ends at the beginning of a line, that last | ||
| 782 | line is excluded. | ||
| 783 | |||
| 784 | *** New user option 'edmacro-reverse-macro-lines'. | ||
| 785 | When this is non-nil, the lines of key sequences are displayed with | ||
| 786 | the most recent line fist. This is can be useful when working with | ||
| 787 | macros with many lines, such as from 'kmacro-edit-lossage'. | ||
| 788 | |||
| 775 | 789 | ||
| 776 | * New Modes and Packages in Emacs 30.1 | 790 | * New Modes and Packages in Emacs 30.1 |
| 777 | 791 | ||
diff --git a/lisp/edmacro.el b/lisp/edmacro.el index bbf5a7f0495..6cad8158321 100644 --- a/lisp/edmacro.el +++ b/lisp/edmacro.el | |||
| @@ -73,9 +73,19 @@ Default nil means to write characters above \\177 in octal notation." | |||
| 73 | :type 'boolean | 73 | :type 'boolean |
| 74 | :group 'kmacro) | 74 | :group 'kmacro) |
| 75 | 75 | ||
| 76 | (defcustom edmacro-reverse-macro-lines nil | ||
| 77 | "Non-nil if `edit-kbd-macro' should show the most recent line of key sequences first. | ||
| 78 | |||
| 79 | This is useful when dealing with long lists of key sequences, such as | ||
| 80 | from `kmacro-edit-lossage'." | ||
| 81 | :type 'boolean | ||
| 82 | :group 'kmacro | ||
| 83 | :version "30.1") | ||
| 84 | |||
| 76 | (defvar-keymap edmacro-mode-map | 85 | (defvar-keymap edmacro-mode-map |
| 77 | "C-c C-c" #'edmacro-finish-edit | 86 | "C-c C-c" #'edmacro-finish-edit |
| 78 | "C-c C-q" #'edmacro-insert-key) | 87 | "C-c C-q" #'edmacro-insert-key |
| 88 | "C-c C-r" #'edmacro-set-macro-to-region-lines) | ||
| 79 | 89 | ||
| 80 | (defface edmacro-label | 90 | (defface edmacro-label |
| 81 | '((default :inherit bold) | 91 | '((default :inherit bold) |
| @@ -88,7 +98,10 @@ Default nil means to write characters above \\177 in octal notation." | |||
| 88 | :group 'kmacro) | 98 | :group 'kmacro) |
| 89 | 99 | ||
| 90 | (defvar edmacro-mode-font-lock-keywords | 100 | (defvar edmacro-mode-font-lock-keywords |
| 91 | `((,(rx bol (group (or "Command" "Key" "Macro") ":")) 0 'edmacro-label) | 101 | `((,(rx bol (group (or "Command" "Key" |
| 102 | (seq "Macro" (zero-or-one " (most recent line first)"))) | ||
| 103 | ":")) | ||
| 104 | 0 'edmacro-label) | ||
| 92 | (,(rx bol | 105 | (,(rx bol |
| 93 | (group ";; Keyboard Macro Editor. Press ") | 106 | (group ";; Keyboard Macro Editor. Press ") |
| 94 | (group (*? nonl)) | 107 | (group (*? nonl)) |
| @@ -166,7 +179,13 @@ With a prefix argument, format the macro in a more concise way." | |||
| 166 | (let* ((oldbuf (current-buffer)) | 179 | (let* ((oldbuf (current-buffer)) |
| 167 | (mmac (edmacro-fix-menu-commands mac)) | 180 | (mmac (edmacro-fix-menu-commands mac)) |
| 168 | (fmt (edmacro-format-keys mmac 1)) | 181 | (fmt (edmacro-format-keys mmac 1)) |
| 169 | (fmtv (edmacro-format-keys mmac (not prefix))) | 182 | (fmtv (let ((fmtv (edmacro-format-keys mmac (not prefix)))) |
| 183 | (if (not edmacro-reverse-macro-lines) | ||
| 184 | fmtv | ||
| 185 | (with-temp-buffer | ||
| 186 | (insert fmtv) | ||
| 187 | (reverse-region (point-min) (point-max)) | ||
| 188 | (buffer-string))))) | ||
| 170 | (buf (get-buffer-create "*Edit Macro*"))) | 189 | (buf (get-buffer-create "*Edit Macro*"))) |
| 171 | (message "Formatting keyboard macro...done") | 190 | (message "Formatting keyboard macro...done") |
| 172 | (switch-to-buffer buf) | 191 | (switch-to-buffer buf) |
| @@ -181,6 +200,9 @@ With a prefix argument, format the macro in a more concise way." | |||
| 181 | (setq-local font-lock-defaults | 200 | (setq-local font-lock-defaults |
| 182 | '(edmacro-mode-font-lock-keywords nil nil ((?\" . "w")))) | 201 | '(edmacro-mode-font-lock-keywords nil nil ((?\" . "w")))) |
| 183 | (setq font-lock-multiline nil) | 202 | (setq font-lock-multiline nil) |
| 203 | ;; Make buffer-local so that the commands still work | ||
| 204 | ;; even if the default value changes. | ||
| 205 | (make-local-variable 'edmacro-reverse-macro-lines) | ||
| 184 | (erase-buffer) | 206 | (erase-buffer) |
| 185 | (insert (substitute-command-keys | 207 | (insert (substitute-command-keys |
| 186 | (concat | 208 | (concat |
| @@ -202,7 +224,9 @@ With a prefix argument, format the macro in a more concise way." | |||
| 202 | (insert "Key: none\n"))) | 224 | (insert "Key: none\n"))) |
| 203 | (when (and mac-counter mac-format) | 225 | (when (and mac-counter mac-format) |
| 204 | (insert (format "Counter: %d\nFormat: \"%s\"\n" mac-counter mac-format)))) | 226 | (insert (format "Counter: %d\nFormat: \"%s\"\n" mac-counter mac-format)))) |
| 205 | (insert "\nMacro:\n\n") | 227 | (insert (format "\nMacro%s:\n\n" (if edmacro-reverse-macro-lines |
| 228 | " (most recent line first)" | ||
| 229 | ""))) | ||
| 206 | (save-excursion | 230 | (save-excursion |
| 207 | (insert fmtv "\n")) | 231 | (insert fmtv "\n")) |
| 208 | (recenter '(4)) | 232 | (recenter '(4)) |
| @@ -255,6 +279,33 @@ or nil, use a compact 80-column format." | |||
| 255 | 279 | ||
| 256 | ;;; Commands for *Edit Macro* buffer. | 280 | ;;; Commands for *Edit Macro* buffer. |
| 257 | 281 | ||
| 282 | (defvar edmacro--skip-line-regexp | ||
| 283 | "[ \t]*\\($\\|;;\\|REM[ \t\n]\\)" | ||
| 284 | "A regexp identifying lines that should be ignored.") | ||
| 285 | |||
| 286 | (defvar edmacro--command-line-regexp | ||
| 287 | "Command:[ \t]*\\([^ \t\n]*\\)[ \t]*$" | ||
| 288 | "A regexp identifying the line containing the command name.") | ||
| 289 | |||
| 290 | (defvar edmacro--key-line-regexp | ||
| 291 | "Key:\\(.*\\)$" | ||
| 292 | "A regexp identifying the line containing the bound key sequence.") | ||
| 293 | |||
| 294 | (defvar edmacro--counter-line-regexp | ||
| 295 | "Counter:[ \t]*\\([^ \t\n]*\\)[ \t]*$" | ||
| 296 | "A regexp identifying the line containing the counter value.") | ||
| 297 | |||
| 298 | (defvar edmacro--format-line-regexp | ||
| 299 | "Format:[ \t]*\"\\([^\n]*\\)\"[ \t]*$" | ||
| 300 | "A regexp identifying the line containing the counter format.") | ||
| 301 | |||
| 302 | (defvar edmacro--macro-lines-regexp | ||
| 303 | (rx "Macro" | ||
| 304 | (zero-or-one " (most recent line first)") | ||
| 305 | ":" | ||
| 306 | (zero-or-more (any " \t\n"))) | ||
| 307 | "A regexp identifying the lines that precede the macro's contents.") | ||
| 308 | |||
| 258 | (defun edmacro-finish-edit () | 309 | (defun edmacro-finish-edit () |
| 259 | (interactive nil edmacro-mode) | 310 | (interactive nil edmacro-mode) |
| 260 | (unless (eq major-mode 'edmacro-mode) | 311 | (unless (eq major-mode 'edmacro-mode) |
| @@ -266,9 +317,9 @@ or nil, use a compact 80-column format." | |||
| 266 | (top (point-min))) | 317 | (top (point-min))) |
| 267 | (goto-char top) | 318 | (goto-char top) |
| 268 | (let ((case-fold-search nil)) | 319 | (let ((case-fold-search nil)) |
| 269 | (while (cond ((looking-at "[ \t]*\\($\\|;;\\|REM[ \t\n]\\)") | 320 | (while (cond ((looking-at edmacro--skip-line-regexp) |
| 270 | t) | 321 | t) |
| 271 | ((looking-at "Command:[ \t]*\\([^ \t\n]*\\)[ \t]*$") | 322 | ((looking-at edmacro--command-line-regexp) |
| 272 | (when edmacro-store-hook | 323 | (when edmacro-store-hook |
| 273 | (error "\"Command\" line not allowed in this context")) | 324 | (error "\"Command\" line not allowed in this context")) |
| 274 | (let ((str (match-string 1))) | 325 | (let ((str (match-string 1))) |
| @@ -283,7 +334,7 @@ or nil, use a compact 80-column format." | |||
| 283 | cmd))) | 334 | cmd))) |
| 284 | (keyboard-quit)))) | 335 | (keyboard-quit)))) |
| 285 | t) | 336 | t) |
| 286 | ((looking-at "Key:\\(.*\\)$") | 337 | ((looking-at edmacro--key-line-regexp) |
| 287 | (when edmacro-store-hook | 338 | (when edmacro-store-hook |
| 288 | (error "\"Key\" line not allowed in this context")) | 339 | (error "\"Key\" line not allowed in this context")) |
| 289 | (let ((key (kbd (match-string 1)))) | 340 | (let ((key (kbd (match-string 1)))) |
| @@ -303,21 +354,21 @@ or nil, use a compact 80-column format." | |||
| 303 | (edmacro-format-keys key 1)))) | 354 | (edmacro-format-keys key 1)))) |
| 304 | (keyboard-quit)))))) | 355 | (keyboard-quit)))))) |
| 305 | t) | 356 | t) |
| 306 | ((looking-at "Counter:[ \t]*\\([^ \t\n]*\\)[ \t]*$") | 357 | ((looking-at edmacro--counter-line-regexp) |
| 307 | (when edmacro-store-hook | 358 | (when edmacro-store-hook |
| 308 | (error "\"Counter\" line not allowed in this context")) | 359 | (error "\"Counter\" line not allowed in this context")) |
| 309 | (let ((str (match-string 1))) | 360 | (let ((str (match-string 1))) |
| 310 | (unless (equal str "") | 361 | (unless (equal str "") |
| 311 | (setq mac-counter (string-to-number str)))) | 362 | (setq mac-counter (string-to-number str)))) |
| 312 | t) | 363 | t) |
| 313 | ((looking-at "Format:[ \t]*\"\\([^\n]*\\)\"[ \t]*$") | 364 | ((looking-at edmacro--format-line-regexp) |
| 314 | (when edmacro-store-hook | 365 | (when edmacro-store-hook |
| 315 | (error "\"Format\" line not allowed in this context")) | 366 | (error "\"Format\" line not allowed in this context")) |
| 316 | (let ((str (match-string 1))) | 367 | (let ((str (match-string 1))) |
| 317 | (unless (equal str "") | 368 | (unless (equal str "") |
| 318 | (setq mac-format str))) | 369 | (setq mac-format str))) |
| 319 | t) | 370 | t) |
| 320 | ((looking-at "Macro:[ \t\n]*") | 371 | ((looking-at edmacro--macro-lines-regexp) |
| 321 | (goto-char (match-end 0)) | 372 | (goto-char (match-end 0)) |
| 322 | nil) | 373 | nil) |
| 323 | ((eobp) nil) | 374 | ((eobp) nil) |
| @@ -336,7 +387,13 @@ or nil, use a compact 80-column format." | |||
| 336 | (when (buffer-name obuf) | 387 | (when (buffer-name obuf) |
| 337 | (set-buffer obuf)) | 388 | (set-buffer obuf)) |
| 338 | (message "Compiling keyboard macro...") | 389 | (message "Compiling keyboard macro...") |
| 339 | (let ((mac (edmacro-parse-keys str))) | 390 | (let ((mac (edmacro-parse-keys (if edmacro-reverse-macro-lines |
| 391 | (with-temp-buffer | ||
| 392 | (insert str) | ||
| 393 | (reverse-region (point-min) | ||
| 394 | (point-max)) | ||
| 395 | (buffer-string)) | ||
| 396 | str)))) | ||
| 340 | (message "Compiling keyboard macro...done") | 397 | (message "Compiling keyboard macro...done") |
| 341 | (if store-hook | 398 | (if store-hook |
| 342 | (funcall store-hook mac) | 399 | (funcall store-hook mac) |
| @@ -372,6 +429,36 @@ or nil, use a compact 80-column format." | |||
| 372 | (insert (edmacro-format-keys key t) "\n") | 429 | (insert (edmacro-format-keys key t) "\n") |
| 373 | (insert (edmacro-format-keys key) " "))) | 430 | (insert (edmacro-format-keys key) " "))) |
| 374 | 431 | ||
| 432 | (defun edmacro-set-macro-to-region-lines (beg end) | ||
| 433 | "Set the macro text to lines of text in the buffer between BEG and END. | ||
| 434 | |||
| 435 | Interactively, BEG and END are the beginning and end of the | ||
| 436 | region. If the region does not begin at the start of a line or | ||
| 437 | if it does not end at the end of a line, the region is extended | ||
| 438 | to include complete lines. If the region ends at the beginning | ||
| 439 | of a line, that final line is excluded." | ||
| 440 | (interactive "*r" edmacro-mode) | ||
| 441 | ;; Use `save-excursion' to restore region if there are any errors. | ||
| 442 | ;; If there are no errors, update the macro text, then go to the | ||
| 443 | ;; beginning of the macro text. | ||
| 444 | (let ((final-position)) | ||
| 445 | (save-excursion | ||
| 446 | (goto-char beg) | ||
| 447 | (unless (bolp) (setq beg (pos-bol))) | ||
| 448 | (goto-char end) | ||
| 449 | (unless (or (bolp) (eolp)) (setq end (pos-eol))) | ||
| 450 | (let ((text (buffer-substring beg end))) | ||
| 451 | (goto-char (point-min)) | ||
| 452 | (if (not (let ((case-fold-search nil)) | ||
| 453 | (re-search-forward edmacro--macro-lines-regexp nil t))) | ||
| 454 | (user-error "\"Macro:\" line not found") | ||
| 455 | (delete-region (match-end 0) | ||
| 456 | (point-max)) | ||
| 457 | (goto-char (point-max)) | ||
| 458 | (insert text) | ||
| 459 | (setq final-position (match-beginning 0))))) | ||
| 460 | (goto-char final-position))) | ||
| 461 | |||
| 375 | (defun edmacro-mode () | 462 | (defun edmacro-mode () |
| 376 | "\\<edmacro-mode-map>Keyboard Macro Editing mode. Press \ | 463 | "\\<edmacro-mode-map>Keyboard Macro Editing mode. Press \ |
| 377 | \\[edmacro-finish-edit] to save and exit. | 464 | \\[edmacro-finish-edit] to save and exit. |
| @@ -393,6 +480,10 @@ or \"none\" for no key bindings. | |||
| 393 | You can edit these lines to change the places where the new macro | 480 | You can edit these lines to change the places where the new macro |
| 394 | is stored. | 481 | is stored. |
| 395 | 482 | ||
| 483 | Press \\[edmacro-set-macro-to-region-lines] to replace the text following the \"Macro:\" line | ||
| 484 | with the text of the lines overlapping the region of text between | ||
| 485 | point and mark. If that region ends at the beginning of a line, | ||
| 486 | that final line is excluded. | ||
| 396 | 487 | ||
| 397 | Format of keyboard macros during editing: | 488 | Format of keyboard macros during editing: |
| 398 | 489 | ||