用Elisp宏编写函数的方法?

19

我写了几个几乎相同的函数,只是它们的名称不同。例如:

; x is name, such as function/paragraph/line/etc.
(defun my-x-function
 (interactive)
 (mark-x) (do-more-stuff) (modify-x))

有没有一种自动生成这些函数的方法?我觉得这就是宏的作用,但我不确定如何使用它们。任何帮助,包括一个小例子都很好。

谢谢!

2个回答

23

没错,这正是宏的作用。这是一个直接的宏示例,可以根据你指定的模式构建函数:

(defmacro make-my-function (name)
  (list 'defun (intern (format "my-%s-function" name)) ()
        (list 'interactive)
        (list (intern (format "mark-%s" name)))
        (list 'do-more-stuff)
        (list (intern (format "modify-%s" name)))))

您可以将此宏复制到Emacs的*scratch*缓冲区中并进行评估,然后检查它是否像这样工作:

(make-my-function x) ; type control-J here
my-x-function ; <-- Emacs's output
(symbol-function 'my-x-function) ; type control-J here
(lambda nil (interactive) (mark-x) (do-more-stuff) (modify-x)) ; <-- Emacs's output

通常人们会使用反引号来更简洁地编写宏,但所有的宏本质上都与上述示例相同。


3

宏可以实现这个功能,但是Emacs有很多模板模块可以做类似的工作。我使用一个叫做yasnippet.el的工具来进行快速代码生成。例如,在C源文件中,如果我输入for<TAB>,我会得到一个for循环模板;它允许我填写模板,设置变量名称、限制和内部循环内容。

看起来像这样:

alt text

你可以为任何想要的东西设置模板。函数定义、if语句、switch语句等等。为不同的模式设置不同的模板。在C中,for循环的模板与在C#中的不同,非常方便。

yasnippet很棒,但可能并不完全相同。宏是有歧义的,因为Emacs有键盘宏可以复制打字或者lisp宏可以改变代码树;如果他必须输入一组无法抽象出来的样板文件,则yasnippet更有帮助(这在C/C++中更为真实,而不是Lisp)。 - Skrylar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接