diff --git a/lisp/kmacro.el b/lisp/kmacro.el index 94d8794bd23..d0630a1998f 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el @@ -183,10 +183,18 @@ kmacro-keymap "C-l" #'kmacro-call-ring-2nd-repeat ;; macro counter - "C-f" #'kmacro-set-format - "C-c" #'kmacro-set-counter - "C-i" #'kmacro-insert-counter - "C-a" #'kmacro-add-counter + "C-f" #'kmacro-set-format + "C-c" #'kmacro-set-counter + "C-i" #'kmacro-insert-counter + "C-a" #'kmacro-add-counter + "C-r l" #'kmacro-reg-load-counter + "C-r s" #'kmacro-reg-save-counter + "C-r a =" #'kmacro-reg-add-counter-equal + "C-r a <" #'kmacro-reg-add-counter-less + "C-r a >" #'kmacro-reg-add-counter-greater + "C-q =" #'kmacro-quit-counter-equal + "C-q <" #'kmacro-quit-counter-less + "C-q >" #'kmacro-quit-counter-greater ;; macro editing "C-e" #'kmacro-edit-macro-repeat @@ -347,6 +355,96 @@ kmacro-add-counter (kmacro-display-counter))) +(defun kmacro-reg-load-counter (register) + "Load the value of REGISTER into `kmacro-counter'." + (interactive + (list (register-read-with-preview "Load register to counter: "))) + (let ((register-val (get-register register))) + (when (numberp register-val) + (setq kmacro-counter register-val)))) + + +(defun kmacro-reg-save-counter (register) + "Save the value of `kmacro-counter' to REGISTER." + (interactive + (list (register-read-with-preview "Save counter to register: "))) + (set-register register kmacro-counter)) + + +(defun kmacro-reg-add-counter-equal (&optional arg) + "Increment `kmacro-counter' by ARG if the counter is equal to a +register's value. +ARG is the numeric prefix argument that defaults to one." + (interactive "p") + (let + ((register (register-read-with-preview "Compare counter to register: "))) + (kmacro-reg-add-counter '= register arg))) + + +(defun kmacro-reg-add-counter-less (&optional arg) + "Increment `kmacro-counter' by ARG if the counter is less than a +register's value. +ARG is the numeric prefix argument that defaults to one." + (interactive "p") + (let + ((register (register-read-with-preview "Compare counter to register: "))) + (kmacro-reg-add-counter '< register arg))) + + +(defun kmacro-reg-add-counter-greater (&optional arg) + "Increment `kmacro-counter' by ARG if the counter is greater than +a register's value. +ARG is the numeric prefix argument that defaults to one." + (interactive "p") + (let + ((register (register-read-with-preview "Compare counter to register: "))) + (kmacro-reg-add-counter '> register arg))) + + +(defun kmacro-reg-add-counter (pred register arg) + "Increment `kmacro-counter' by ARG if predicate PRED returns +non-nil. +PRED is called with two arguments: `kmacro-counter' and REGISTER." + (let ((register-val (get-register register))) + (when (apply pred (list kmacro-counter register-val)) + (setq current-prefix-arg nil) + (kmacro-add-counter arg)))) + + +(defun kmacro-quit-counter-equal (&optional arg) + "Quit the keyboard macro if `kmacro-counter' is equal to ARG. +ARG is the numeric prefix argument that defaults to zero." + (interactive "P") + (kmacro-quit-counter '= arg)) + + +(defun kmacro-quit-counter-less (&optional arg) + "Quit the keyboard macro if `kmacro-counter' is less than ARG. +ARG is the numeric prefix argument that defaults to zero." + (interactive "P") + (kmacro-quit-counter '< arg)) + + +(defun kmacro-quit-counter-greater (&optional arg) + "Quit the keyboard macro if `kmacro-counter' is greater than ARG. +ARG is the numeric prefix argument that defaults to zero." + (interactive "P") + (kmacro-quit-counter '> arg)) + + +(defun kmacro-quit-counter (pred &optional arg) + "Quit the keyboard macro if predicate PRED returns non-nil. +PRED is called with two arguments: `kmacro-counter' and ARG." + (when kmacro-initial-counter-value + (setq kmacro-counter kmacro-initial-counter-value + kmacro-initial-counter-value nil)) + (let ((arg + (cond ((null arg) 0) + (t (prefix-numeric-value arg))))) + (when (apply pred (list kmacro-counter arg)) + (keyboard-quit)))) + + (defun kmacro-loop-setup-function () "Function called prior to each iteration of macro." ;; Restore macro counter format to initial format, so it is ok to change