Emacs 未执行defmacro的主体

Emacs 未执行defmacro的主体,emacs,lisp,elisp,Emacs,Lisp,Elisp,我注意到我的代码中有一种趋势,即反复使用相同的(使用当前缓冲区…),因此我决定根据使用当前缓冲区的宏定义定义一个宏,这就是我到目前为止所做的: (defmacro with-assembla-buffer(asm-buffer-name heading-str &rest body) "Create buffer with name of ASM-BUFFER-NAME, or uses it if exists,

我注意到我的代码中有一种趋势,即反复使用相同的
(使用当前缓冲区…
),因此我决定根据使用当前缓冲区的
宏定义定义一个宏,这就是我到目前为止所做的:

(defmacro with-assembla-buffer(asm-buffer-name heading-str &rest body)
  "Create buffer with name of ASM-BUFFER-NAME, or uses it if exists,                                                                                                      
   preps it with readonly/erase/heading - executes `body' - then puts                                                                                                     
   readonly back on, goes to beginning of buffer, and switches to it."
  (with-current-buffer (get-buffer-create asm-buffer-name)
    (assembla-mode)
    (toggle-read-only -1)
    (erase-buffer)
    (insert (format "-- %s --------------------" heading-str))
    (newline)
    `(progn ,@body)
    (toggle-read-only 1)
    (goto-char (point-min))
    (switch-to-buffer (current-buffer))))

它的主体从来没有被执行过,但是当它被切换到
defun
而不是
defmacro
时,它确实工作得很好。所以除了为什么主体从来没有被执行过,我的另一个问题是-作为宏比defun更有意义吗?记住,宏会生成代码。你的macro看起来不是。请查看示例调用的宏扩展。调试宏的第一步是检查某些代码的宏扩展

上图:为什么这是宏中的代码而不是源代码?宏展开时将执行此代码,它不会出现在生成的代码中。您可能希望对其进行反引号

  (assembla-mode)
  (toggle-read-only -1)
  (erase-buffer)
  (insert (format "-- %s --------------------" heading-str))
  (newline)

   `(progn ,@body)

上图:这不能满足您的需要。您需要对所有要生成的代码进行反引用,而不仅仅是此表单。

我对整个过程进行了反引用,这更有意义。谢谢!Dan:还要注意,对于字节编译的elisp,宏在编译时会展开,因此宏执行的代码不会在运行时执行当运行字节编译的代码时。(这个关键的细微差别很容易被忽略,因为对于未编译的代码,宏将被动态扩展,并且每次都执行代码。)引用Emacs-23的
C-h f switch to buffer
:“警告:这不是在Lisp程序中临时处理另一个缓冲区的方法!请改用
设置缓冲区
。这样可以避免弄乱窗口缓冲区的对应关系”
  (assembla-mode)
  (toggle-read-only -1)
  (erase-buffer)
  (insert (format "-- %s --------------------" heading-str))
  (newline)

   `(progn ,@body)