Emacs 从宏创建自动加载的函数

Emacs 从宏创建自动加载的函数,emacs,macros,autoload,Emacs,Macros,Autoload,如何从宏函数工厂创建自动加载函数?例如,假设我有一个宏来创建对齐函数,如下所示,但我希望能够指定一个选项,以便扩展的宏具有自动加载cookie (defmacro align-by (name doc regex) "Alignment function factory." (declare (indent 1)) (let ((fn (intern name))) `(defun ,fn (start end) ,doc (interactive

如何从宏函数工厂创建自动加载函数?例如,假设我有一个宏来创建对齐函数,如下所示,但我希望能够指定一个选项,以便扩展的宏具有自动加载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-*\\)\\\\$")
我知道我可以写这个,但是我可以避免为每个函数写这个吗

;;;###autoload (autoload 'align-backslash "this-file")

目前还不清楚宏将在何处拾取要自动加载的文件名-您当前没有将文件名传递给宏

假设文件名来自宏展开时访问的文件,则可以执行以下操作:

(定义宏对齐方式(名称doc regex)
“校准功能工厂。”
(声明(缩进1))
(实习医生姓名)
`(项目
,(和(缓冲区文件名)
`(自动加载',名称,(缓冲区文件名)))
(defun,fn(开始-结束)
,博士
(交互式“r”)
(对齐regexp开始-结束,regex(()()))
测试:

(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-*\\)\\\\$")))

拾取
;;的代码###自动加载
cookies会在查看代码之前展开宏,因此您应该能够只放置一个
###自动加载
(按…)对齐)表达式前面的cookie,并将正确的自动加载放置在
-autoloads.el
文件中

问题是,在创建自动加载时,宏可能不会被定义,因此宏扩展实际上不会发生。可能有一个
M-x报告emacs错误

如emacs手册所示

如果您编写的函数定义包含一个不寻常的宏,而该宏不是已知和公认的函数定义方法之一,则使用普通的magic autoload注释会将整个定义复制到loaddefs.el中。这是不可取的。您可以将所需的自动加载调用写入loaddefs.el,方法是:

您的
align by
与手册示例中的
mydefuncro
类似。它不是已知的函数定义方法,
autoload
机制不支持它

因此,有三种选择:

  • 通过特殊宏扩展支持的类型列表(
    defun
    defmacro
    cl-defun
    defclass
    ,…)。然后您可以使用简单的
    ###自动加载
    “装饰器”
  • 发明您自己的“myfile”解析(不执行)机制,并通过必要的自动加载定义填充“loaddefs”
  • 使用更复杂的构造(使用
    (自动加载“对齐反斜杠”myfile)(
    )作为函数定义方法
  • 如果您像这样重写
    对齐(没有
    实习生
    ):


    您可以看到,
    align by
    只是一种函数定义方法(如
    cl-defun
    )。

    在什么情况下需要这样做?我很难想到任何不能通过自动加载宏本身来解决的问题,但我猜这只是我的想法,所以我真的很好奇。您不需要扩展宏:
    autoload
    在调用
    时与
    defun
    定义一起调用(通过“对齐反斜杠”对齐…)
    。不可以,您也可以将
    按defun对齐
    用作函数工厂。没关系。但是你有你的函数的完整列表(对齐反斜杠,…)吗?或者它将被动态创建?您想让所有人在帮助缓冲区中都有
    此文件
    链接(到
    定义对齐)还是其他内容?
    ;;;###autoload (autoload 'foo "myfile")
    (mydefunmacro foo
      ...)
    
    (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-*\\)\\\\$")