Create autoload function from macro

How can I create an autoload function from a factory macro function? For example, let's say I have a macro to create alignment functions as follows, but I want to be able to specify a parameter so that the extended macro has an autoload cookie.

(defmacro align-by (name doc regex)
  "Alignment function factory."
  (declare (indent 1))
  (let ((fn (intern name)))
    `(defun ,fn (start end)
       ,doc
       (interactive "r")
       (align-regexp start end ,regex))))

(align-by "align-backslash"
  "Align backslashes at end of line in region."
  "\\(\\s-*\\)\\\\$")

I know I can write this, but can I avoid the need to write this for every function?

;;;###autoload (autoload 'align-backslash "this-file")
+4
source share
3 answers

It is not clear where the macro will pick up the name of the file that will be automatically loaded - you are not passing the file name to the macro at this time.

Assuming the file name comes from the file that is visited during the macro extension, this will do the following:

(defmacro align-by (name doc regex)
  "Alignment function factory."
  (declare (indent 1))
  (let ((fn (intern name)))
    `(progn
       ,(and (buffer-file-name)
             `(autoload ',name ,(buffer-file-name)))
       (defun ,fn (start end)
         ,doc
         (interactive "r")
         (align-regexp start end ,regex)))))

Testing:

(macroexpand '(align-by "align-backslash"
           "Align backslashes at end of line in region."
           "\\(\\s-*\\)\\\\$"))

C-u C-x C-e , , :

(progn
  (autoload '"align-backslash" nil)
  (defun align-backslash
      (start end)
    "Align backslashes at end of line in region."
    (interactive "r")
    (align-regexp start end "\\(\\s-*\\)\\\\$")))

, foo.el, ".../foo.el" foo.el:

(progn
  (autoload '"align-backslash" ".../foo.el")
  (defun align-backslash
      (start end)
    "Align backslashes at end of line in region."
    (interactive "r")
    (align-regexp start end "\\(\\s-*\\)\\\\$")))
+1

, ;;;###autoload, , ;;;###autoload (align-by ...) , <foo>-autoloads.el.

, , , , . , M-x report-emacs-bug .

+1

emacs

, , loaddefs.el. . loaddefs.el, :

;;;###autoload (autoload 'foo "myfile")
(mydefunmacro foo
  ...)

align-by mydefunmacro . autoload.

, :

  • (defun, defmacro, cl-defun, defclass,...) . ;;;###autoload "".
  • Come up with your own “myfile” (no execution) and “loaddefs” parsing mechanism that populates the necessary startup definitions.
  • Use a more complex construct (c (autoload 'align-backslash "myfile")) as a defintion function.

If you rewrite align-bylike this (without intern):

(defmacro align-by-defun (name doc regex)
  "Alignment function factory."
  (declare (indent 1))
  `(defun ,name (start end)
     ,doc
     (interactive "r")
     (align-regexp start end ,regex)))

;;;###autoload (autoload 'align-backslash "myfile")
(align-by-defun align-backslash
  "Align backslashes at end of line in region."
  "\\(\\s-*\\)\\\\$")

you can see that align-by- this is just a function definition method (e.g. cl-defun).

+1
source

Source: https://habr.com/ru/post/1650246/


All Articles