2

After edit :


I am using evil-mode. I often record macros very specific to the file I am editing with qq or qw. Is there a way to autosave those macros and the key associated to them when saving the file ? In order to make those macros working when the file is opened again.

1
  • 1
    Save the macro as Elisp code (see insert-kbd-macro'), and give it a name as a command. Add code to to the command to raise an error if the current buffer-file-name` isn't for the appropriate file.
    – Drew
    Jan 17, 2020 at 17:02

1 Answer 1

3

Try this:

(defun insert-kbd-macro-in-register (register)
  "insert macro from register. prompt for register key
if no argument passed. you may need to revise inserted s-expression."
  (interactive "cthe register key:")
  (let* ((macro (cdr (assoc register register-alist)))
         (macro-string (with-temp-buffer
                         (setf last-kbd-macro macro)
                         (insert-kbd-macro '##)
                         (buffer-string))))
    (insert macro-string)))

If you do not care the ugly output, just call (insert (format "%s" (cdr (assoc register-key register-alist)))).

if you have not record the other macro, you can save the last macro with M-x insert-kbd-macro RET. with empty string as macro name, insert-kbd-macro will insert the last macro.

if you want to advice the evil's p command:

(defun evil-paste-kbd-macro-advice (&rest argv)
  "make evil paste kbd-macro if register content is a macro.
this function check whether content macro by:
 1. equal to `last-kbd-macro'
 2. is a vector but not string
 3. contain unprintable character"
  (if (and (>= (length argv) 2)
           (second argv))
      (let* ((register (second argv))
             (register-pair (assoc register register-alist))
             (content (if register-pair (cdr register-pair))))
        (if (and content
                 (or (eq last-kbd-macro content)
                     (vectorp content)
                     (string-match "[^\t[:print:]\n\r]" content)))
            (let ((last-kbd-macro content))
              (forward-line)
              (beginning-of-line)
              (insert-kbd-macro '##)
              (forward-line -2)
              (search-forward "setq last-kbd-macro")
              (replace-match "execute-kbd-macro")
              t)))))
(advice-add 'evil-paste-after :before-until
            'evil-paste-kbd-macro-advice)

In vim, macro in register is just plain text, so you can paste it "wp. In emacs, macro is a vector of key. however, if there are return or backspace in macro, they are stored as symbol. A vector of characters is string, but a vector contain symbols is not string, so it can not be paste with evil's paste command.

The advice above will detect whether the register's content is string. If it is not, the advice will insert it as macro, or it will do nothing, and evil will paste it as ordinary string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.