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.

pietrodito
  • 187
  • 7
  • 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 currentbuffer-file-name` isn't for the appropriate file. – Drew Jan 17 '20 at 17:02

1 Answers1

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.

gholk
  • 76
  • 4