从宏创建自动加载的功能

时间:2016-08-05 00:24:59

标签: emacs macros autoload

如何从宏功能工厂创建自动加载功能?例如,假设我有一个宏来创建对齐函数,如下所示,但我希望能够指定一个选项,以便扩展的宏具有自动加载cookie。

table

我知道我可以写这个,但是我可以避免为每个函数编写这个吗?

myListDataProviderObject.getList()addAll(my data)

3 个答案:

答案 0 :(得分:1)

目前还不清楚宏会在哪里获取要自动加载的文件的名称 - 目前你没有将文件名传递给宏。

假设文件名来自扩展宏时正在访问的文件,这将执行此操作:

(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)))))

测试:

(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 :(得分:1)

获取;;;###autoload Cookie的代码会在查看代码之前扩展宏,因此能够在{a}之前放置;;;###autoload Cookie (align-by ...)表达式,并在<foo>-autoloads.el文件中放置正确的自动加载。

问题是,您的宏可能不会在创建自动加载时定义,因此宏扩展实际上不会发生。也许M-x report-emacs-bug是有序的。

答案 2 :(得分:1)

作为emacs手册mentioned

  

如果使用不是已知和已识别的函数定义方法之一的异常宏编写函数定义,则使用普通的魔术自动加载注释会将整个定义复制到loaddefs.el中。这是不可取的。您可以将所需的自动加载调用放入loaddefs.el,而不是写入:

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

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

所以有三种选择:

  1. 通过您的特殊宏扩展受支持的类型列表(defundefmacrocl-defundefclass,...)。然后,您可以使用简单的;;;###autoload&#34;装饰器&#34;。
  2. 创建自己的&#34; myfile&#34;解析(不执行)和&#34; loaddefs&#34;通过必要的自动加载定义填充。
  3. 使用更复杂的构造((autoload 'align-backslash "myfile"))作为函数定义方法。
  4. 如果你像这样重写align-by(没有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-*\\)\\\\$")
    

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