branch: elpa/evil commit 30e819dcf47294a758a47a362d2f61fc19aefcf0 Author: Axel Forsman <axels...@gmail.com> Commit: Axel Forsman <axels...@gmail.com>
Fix executing macro infinite times This commit fixes a regression caused by #1549 where you could no longer give a prefix argument to execute the macro in an infinite loop. --- evil-commands.el | 27 ++++++++++++--------------- evil-ex.el | 4 ++-- evil-tests.el | 9 +++++++++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index 3f9b5ab417..5816d8a721 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -2390,7 +2390,7 @@ will be opened instead." (evil-set-register evil-this-macro nil) (kmacro-start-macro nil) (setq evil-macro-buffer (current-buffer))) - (t (error "Invalid register"))))) + (t (error "Invalid register `%s'" register))))) (evil-define-command evil-execute-macro (count macro) "Execute keyboard macro MACRO, COUNT times. @@ -2402,15 +2402,14 @@ when called interactively." :suppress-operator t (interactive (let (count macro register) - (setq count (if current-prefix-arg - (if (numberp current-prefix-arg) - current-prefix-arg - 0) 1) + (setq count (cond ((null current-prefix-arg) 1) + ((numberp current-prefix-arg) current-prefix-arg) + (t 0)) register (or evil-this-register (read-char))) (cond - ((or (and (eq register ?@) (eq evil-last-register ?:)) - (eq register ?:)) - (setq macro (lambda () (evil-ex-repeat nil)) + ((or (eq register ?:) + (and (eq register ?@) (eq evil-last-register ?:))) + (setq macro #'evil-ex-repeat evil-last-register ?:)) ((eq register ?@) (unless evil-last-register @@ -2423,24 +2422,22 @@ when called interactively." (cond ((functionp macro) (evil-repeat-abort) - (dotimes (_ (or count 1)) - (funcall macro))) + (if (zerop count) + (while t (funcall macro)) + (dotimes (_ (or count 1)) (funcall macro)))) ((or (and (not (stringp macro)) (not (vectorp macro))) (member macro '("" []))) ;; allow references to currently empty registers ;; when defining macro - (unless evil-this-macro - (user-error "No previous macro"))) + (unless evil-this-macro (user-error "No previous macro"))) (t (condition-case err (evil-with-single-undo - (dotimes (_ (or count 1)) - (execute-kbd-macro macro))) + (execute-kbd-macro macro count)) ;; enter Normal state if the macro fails (error (evil-normal-state) - (evil-normalize-keymaps) (signal (car err) (cdr err))))))) (evil-define-command evil-execute-last-recorded-macro (count) diff --git a/evil-ex.el b/evil-ex.el index 496348f387..4f75d3fc60 100644 --- a/evil-ex.el +++ b/evil-ex.el @@ -675,8 +675,8 @@ This function interprets special file names like # and %." (unless (zerop (length evil-ex-argument)) (evil-ex-replace-special-filenames evil-ex-argument))) -(defun evil-ex-repeat (count) - "Repeat the last ex command." +(defun evil-ex-repeat (&optional count) + "Repeat the last Ex command." (interactive "P") (when count (goto-char (point-min)) diff --git a/evil-tests.el b/evil-tests.el index 51eb5ab4a3..4e8aaf4dd8 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -9589,6 +9589,15 @@ parameter set." ("ci|testing" [escape]) "| foo |testing| bar |"))) +(ert-deftest evil-test-kbd-macro () + "Test recording and replaying of macros." + :tags '(evil kbd-macro) + (ert-info ("Execute macro an infinite number of times") + (evil-test-buffer "xxx" + (evil-set-register ?q "ryl") + (error 'end-of-line "\C-u@q") + "yyy"))) + (ert-deftest evil-test-undo-kbd-macro () "Test if evil can undo the changes made by a keyboard macro when an error stops the execution of the macro"